Skip to content

[ISSUE #7354]🚀add ACL configuration and validation modules, including file loading and permission handling#7355

Merged
rocketmq-rust-bot merged 1 commit into
mainfrom
feat-7354
May 14, 2026
Merged

[ISSUE #7354]🚀add ACL configuration and validation modules, including file loading and permission handling#7355
rocketmq-rust-bot merged 1 commit into
mainfrom
feat-7354

Conversation

@mxsm
Copy link
Copy Markdown
Owner

@mxsm mxsm commented May 13, 2026

Which Issue(s) This PR Fixes(Closes)

Brief Description

How Did You Test This Change?

Summary by CodeRabbit

Release Notes

  • New Features

    • ACL configuration can now be loaded from YAML files with automatic validation and deduplication support.
    • Added permission configuration system for legacy ACL compatibility.
  • Bug Fixes

    • Improved handling of DLQ group-topic prefixes in resource authorization.
  • Improvements

    • Secret keys are now redacted in debug output for enhanced security.

Review Change Stack

@rocketmq-rust-bot
Copy link
Copy Markdown
Collaborator

🔊@mxsm 🚀Thanks for your contribution🎉!

💡CodeRabbit(AI) will review your code first🔥!

Note

🚨The code review suggestions from CodeRabbit are to be used as a reference only, and the PR submitter can decide whether to make changes based on their own judgment. Ultimately, the project management personnel will conduct the final code review💥.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Walkthrough

The PR introduces ACL file loading, validation, and permission handling for RocketMQ. It adds a FileAclConfigLoader that discovers and merges YAML configuration files, a validate_acl_config function ensuring required fields are present and non-duplicate, a Permission type for legacy bit mapping, and updates Resource::of_group to normalize DLQ prefixes. It also redacts secrets in PlainAccessConfig debug/display output.

Changes

ACL Configuration Loading and Authorization

Layer / File(s) Summary
ACL Module Facade and Public API
rocketmq-auth/src/acl.rs, rocketmq-auth/src/lib.rs
Creates acl and permission as public modules in rocketmq-auth, re-exporting AclConfig, PlainAccessConfig, PlainAccessData, FileAclConfigLoader, and validate_acl_config as the public surface.
ACL File Discovery and Loading
rocketmq-auth/src/acl/loader.rs
FileAclConfigLoader recursively scans root directories for .yml/.yaml files (excluding tools.yml), deserializes them as YAML, merges account entries with deduplication by access key, and validates the merged AclConfig before returning. Includes comprehensive tests for discovery, deduplication, and whitespace-only file handling.
ACL Configuration Validation
rocketmq-auth/src/acl/validator.rs
validate_acl_config iterates over plain access configs, ensures non-blank accessKey and secretKey fields, rejects duplicate access keys via HashSet, and returns errors without exposing secret values. Includes tests verifying proper rejection and secret non-leakage.
Permission Bits and Legacy Action Mapping
rocketmq-auth/src/permission.rs
Permission(u8) type represents ACL permission bits with DENY, ANY, PUB, SUB constants, parse() method for legacy string conversion, and migration_actions_and_decision() to map legacy values to RocketMQ Action lists and allow/deny decisions.
Resource DLQ Group-Topic Prefix Stripping
rocketmq-auth/src/authorization/model/resource.rs
Resource::of_group extends normalization to strip DLQ group-topic prefixes (detected via NamespaceUtil::is_dlq_topic) alongside existing retry-topic stripping. Includes test verifying the DLQ prefix is correctly removed.
PlainAccessConfig Secret Redaction in Logs
rocketmq-common/src/common/base/plain_access_config.rs
PlainAccessConfig removes Debug derive and adds custom impl fmt::Debug and updated impl fmt::Display rendering secret_key as "<redacted>" to prevent secrets from appearing in debug/display output. Includes test verifying both formats redact the secret.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 ACL configs now load from files with care,
Validating secrets, keeping passwords rare,
Legacy permissions map to modern ways,
DLQ prefixes stripped through all the days,
A safe, redacted log for watchful eyes! 🔐

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: adding ACL configuration and validation modules with file loading and permission handling functionality.
Linked Issues check ✅ Passed The pull request implements all primary coding objectives from issue #7354: ACL configuration modules, validation, file loading, and permission handling.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: ACL modules, validation, file loading, permission handling, and supporting functionality like DLQ group prefix stripping.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-7354

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@rocketmq-rust-robot rocketmq-rust-robot added the feature🚀 Suggest an idea for this project. label May 13, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rocketmq-auth/src/permission.rs`:
- Around line 38-46: The parse() function currently maps unknown permission
strings to DENY while migration_actions_and_decision() treats unknown strings as
(vec![Action::All], Decision::Allow); pick one behavior and make them
consistent: either (preferred) change migration_actions_and_decision() to return
the same restrictive default as parse() (Decision::Deny and no actions) for
unknown inputs, updating the method that references
migration_actions_and_decision() and the match arms that handle unknown cases,
or if the permissive migration behavior is intentional add clear doc comments to
both parse() and migration_actions_and_decision() explaining the deliberate
difference (e.g., backward-compatibility for migrations) and why it is safe;
reference the functions parse and migration_actions_and_decision when making the
change or adding docs.
- Line 30: The ANY constant (pub const ANY: Self = Self(1 << 1)) is unused
except in a negative assertion and should be removed or explicitly documented;
either delete the ANY constant from permission.rs if not needed, or add a clear
doc comment or #[deprecated] attribute above ANY explaining its reserved/future
purpose and update any tests referencing it (the negative assertion at line
referencing ANY) so they reflect the change; ensure parse() and
migration_actions_and_decision() remain unaffected and run tests after the
change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c5c019e1-b13b-46a1-9045-aa8ba4499fd8

📥 Commits

Reviewing files that changed from the base of the PR and between 085c543 and 8253014.

📒 Files selected for processing (7)
  • rocketmq-auth/src/acl.rs
  • rocketmq-auth/src/acl/loader.rs
  • rocketmq-auth/src/acl/validator.rs
  • rocketmq-auth/src/authorization/model/resource.rs
  • rocketmq-auth/src/lib.rs
  • rocketmq-auth/src/permission.rs
  • rocketmq-common/src/common/base/plain_access_config.rs


impl Permission {
pub const DENY: Self = Self(1);
pub const ANY: Self = Self(1 << 1);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for usages of Permission::ANY across the codebase
rg -n --type=rust 'Permission::ANY' -C3

Repository: mxsm/rocketmq-rust

Length of output: 495


🏁 Script executed:

#!/bin/bash
# Get context around line 98 to understand the test intent
cat -n rocketmq-auth/src/permission.rs | sed -n '85,110p'

Repository: mxsm/rocketmq-rust

Length of output: 1305


🏁 Script executed:

#!/bin/bash
# Check the full Permission struct definition and all constants
cat -n rocketmq-auth/src/permission.rs | sed -n '20,40p'

Repository: mxsm/rocketmq-rust

Length of output: 779


🏁 Script executed:

#!/bin/bash
# Search for any comments or doc strings about Permission constants
rg -n --type=rust -B5 'pub const ANY' rocketmq-auth/src/permission.rs

Repository: mxsm/rocketmq-rust

Length of output: 279


Remove unused ANY constant or add documentation explaining its purpose.

The ANY constant is only referenced in a negative assertion at line 98 and is never used in parse() or migration_actions_and_decision(). If this is reserved for future use, add a #[deprecated] attribute or doc comment to clarify intent; otherwise, remove it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rocketmq-auth/src/permission.rs` at line 30, The ANY constant (pub const ANY:
Self = Self(1 << 1)) is unused except in a negative assertion and should be
removed or explicitly documented; either delete the ANY constant from
permission.rs if not needed, or add a clear doc comment or #[deprecated]
attribute above ANY explaining its reserved/future purpose and update any tests
referencing it (the negative assertion at line referencing ANY) so they reflect
the change; ensure parse() and migration_actions_and_decision() remain
unaffected and run tests after the change.

Comment on lines +38 to +46
pub fn parse(value: Option<&str>) -> Self {
match value.map(str::trim).unwrap_or_default() {
"PUB" => Self::PUB,
"SUB" => Self::SUB,
"PUB|SUB" | "SUB|PUB" => Self(Self::PUB.0 | Self::SUB.0),
"DENY" | "" => Self::DENY,
_ => Self::DENY,
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Document or reconcile inconsistent handling of unknown permission strings.

parse() defaults unknown inputs to DENY (line 44), which is a security-safe fallback. However, migration_actions_and_decision() maps unknown inputs to (vec![Action::All], Decision::Allow) (lines 57, 64), which is permissive. This semantic inconsistency could lead to confusion or security gaps if different code paths interpret the same unknown permission string differently.

If this divergence is intentional (e.g., parse for strict validation vs. migration for backward compatibility), add doc comments explaining the rationale. Otherwise, consider aligning both methods to use the same default behavior for unknown inputs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rocketmq-auth/src/permission.rs` around lines 38 - 46, The parse() function
currently maps unknown permission strings to DENY while
migration_actions_and_decision() treats unknown strings as (vec![Action::All],
Decision::Allow); pick one behavior and make them consistent: either (preferred)
change migration_actions_and_decision() to return the same restrictive default
as parse() (Decision::Deny and no actions) for unknown inputs, updating the
method that references migration_actions_and_decision() and the match arms that
handle unknown cases, or if the permissive migration behavior is intentional add
clear doc comments to both parse() and migration_actions_and_decision()
explaining the deliberate difference (e.g., backward-compatibility for
migrations) and why it is safe; reference the functions parse and
migration_actions_and_decision when making the change or adding docs.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

❌ Patch coverage is 94.54545% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.12%. Comparing base (085c543) to head (8253014).

Files with missing lines Patch % Lines
rocketmq-auth/src/acl/loader.rs 90.68% 15 Missing ⚠️
rocketmq-auth/src/permission.rs 95.65% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7355      +/-   ##
==========================================
+ Coverage   63.06%   63.12%   +0.05%     
==========================================
  Files        1121     1124       +3     
  Lines      212016   212346     +330     
==========================================
+ Hits       133718   134045     +327     
- Misses      78298    78301       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Collaborator

@rocketmq-rust-bot rocketmq-rust-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - All CI checks passed ✅

@rocketmq-rust-bot rocketmq-rust-bot merged commit 7014fe9 into main May 14, 2026
20 of 21 checks passed
@rocketmq-rust-bot rocketmq-rust-bot added approved PR has approved and removed ready to review waiting-review waiting review this PR labels May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI review first Ai review pr first approved PR has approved auto merge feature🚀 Suggest an idea for this project.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature🚀] add ACL configuration and validation modules, including file loading and permission handling

3 participants