Skip to content

Conversation

@naveenpaul1
Copy link
Contributor

@naveenpaul1 naveenpaul1 commented Dec 2, 2025

Describe the Problem

User ID for principal is not supported

Explain the Changes

  1. Block put pucket policy if the principal is IAM user ID

Issues: Fixed #xxx / Gap #xxx

Testing Instructions:

GAP: Missing integration test for IAM users, Will add in upcoming PRs

  • Doc added/updated
  • Tests added

Summary by CodeRabbit

  • Bug Fixes
    • Bucket policy principal resolution improved: IAM users are no longer treated as valid principals when looked up by account ID, preventing unintended principal matches and reducing erroneous permission grants.
    • Policy evaluation now respects deployment-specific account identification rules to provide more accurate access-control decisions.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

Walkthrough

Added ownership-aware principal resolution: bucket principal lookup now avoids treating IAM user accounts (accounts with an owner property) as valid principals when identified by account ID; an exported helper supplies the appropriate account identifier for policy checks across deployments.

Changes

Cohort / File(s) Change Summary
Bucket principal resolution logic
src/server/system_services/bucket_server.js
When principal is not an ARN, check account.owner; if present (IAM user), log debug and return false instead of treating the account ID as a valid principal.
Policy identifier helper
src/endpoint/s3/s3_bucket_policy_utils.js
Added get_account_identifier_id(is_nc_deployment, account) and exported it; returns account._id only for NC deployments or when account.owner is undefined.
Policy checks usage
src/endpoint/s3/s3_rest.js
Replaced direct use of account._id with get_account_identifier_id(is_nc_deployment, account) in bucket policy evaluation; added clarifying comments about deployment-specific identifier behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Review logic in get_account_by_principal for correctness and side effects on existing policy evaluation.
  • Verify get_account_identifier_id usage in s3_rest.js covers all code paths and doesn't break non-NC deployments.
  • Check unit/integration tests or add tests for IAM-user vs account-root principal resolution.

Possibly related PRs

Suggested labels

size/XS

Suggested reviewers

  • aayushchouhan09
  • shirady
  • liranmauda

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'IAM | User ID for principal is not supported' clearly and specifically summarizes the main change: blocking IAM user IDs as principals in bucket policies.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link

@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: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89f64d8 and 774f343.

📒 Files selected for processing (1)
  • src/server/system_services/bucket_server.js (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9277
File: src/endpoint/s3/s3_rest.js:258-261
Timestamp: 2025-11-12T04:55:42.193Z
Learning: In the context of S3 REST requests (src/endpoint/s3/s3_rest.js), the account.owner field from req.object_sdk.requesting_account is already a string (account ID) because it comes from RPC serialization where owner._id.toString() is applied in account_server.js. No additional .toString() or ._id extraction is needed when passing account.owner to IAM utility functions.
📚 Learning: 2025-11-19T15:03:42.260Z
Learnt from: shirady
Repo: noobaa/noobaa-core PR: 9291
File: src/server/common_services/auth_server.js:548-554
Timestamp: 2025-11-19T15:03:42.260Z
Learning: In src/server/common_services/auth_server.js, account objects are loaded directly from system_store (e.g., system_store.data.get_by_id()), so account.owner is an object ID reference with an ._id property, not a string. This differs from s3_rest.js where account.owner is a string due to RPC serialization.

Applied to files:

  • src/server/system_services/bucket_server.js
📚 Learning: 2025-11-12T04:55:42.193Z
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9277
File: src/endpoint/s3/s3_rest.js:258-261
Timestamp: 2025-11-12T04:55:42.193Z
Learning: In the context of S3 REST requests (src/endpoint/s3/s3_rest.js), the account.owner field from req.object_sdk.requesting_account is already a string (account ID) because it comes from RPC serialization where owner._id.toString() is applied in account_server.js. No additional .toString() or ._id extraction is needed when passing account.owner to IAM utility functions.

Applied to files:

  • src/server/system_services/bucket_server.js
📚 Learning: 2025-11-18T07:00:17.653Z
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9277
File: src/endpoint/s3/s3_bucket_policy_utils.js:357-368
Timestamp: 2025-11-18T07:00:17.653Z
Learning: In NooBaa codebase, account.name is always a SensitiveString instance, so calling account.name.unwrap() is safe without defensive type checks in functions like get_bucket_policy_principal_arn in src/endpoint/s3/s3_bucket_policy_utils.js.

Applied to files:

  • src/server/system_services/bucket_server.js
📚 Learning: 2025-11-13T07:56:23.620Z
Learnt from: shirady
Repo: noobaa/noobaa-core PR: 9281
File: src/server/system_services/account_server.js:1053-1058
Timestamp: 2025-11-13T07:56:23.620Z
Learning: In noobaa-core, account_server.js is only used in containerized deployments, not in NSFS/NC deployments. NSFS/NC deployments have separate account management code in src/manage_nsfs/ directory. Therefore, account_server.js only processes accounts from account_schema.js where owner is an objectid reference, never from nsfs_account_schema.js where owner is a string.

Applied to files:

  • src/server/system_services/bucket_server.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-package-lock-validation
  • GitHub Check: run-jest-unit-tests
  • GitHub Check: Build Noobaa Image

@shirady
Copy link
Contributor

shirady commented Dec 3, 2025

@naveenpaul1,
What about the s3_rest file?
It still checks the account_id for IAM user

Signed-off-by: Naveen Paul <napaul@redhat.com>
Copy link

@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: 0

🧹 Nitpick comments (1)
src/endpoint/s3/s3_bucket_policy_utils.js (1)

380-391: Simplify boolean logic and fix typo.

The conditional logic can be simplified, and there's a typo in the comment.

Apply this diff:

 /**
- *  Both NSFS NC and containerized will validate bucket policy against acccount id 
- *  but in containerized deplyment not against IAM user ID.
+ *  Both NSFS NC and containerized will validate bucket policy against account id 
+ *  but in containerized deployment not against IAM user ID.
  * 
  * @param {boolean} is_nc_deployment
  * @param {object} account
  */
 function get_account_identifier_id(is_nc_deployment, account) {
-    if (is_nc_deployment || (!is_nc_deployment && account.owner === undefined)) {
+    if (is_nc_deployment || account.owner === undefined) {
         return account._id;
     }
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 774f343 and 96dedf1.

📒 Files selected for processing (3)
  • src/endpoint/s3/s3_bucket_policy_utils.js (2 hunks)
  • src/endpoint/s3/s3_rest.js (1 hunks)
  • src/server/system_services/bucket_server.js (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9277
File: src/endpoint/s3/s3_rest.js:258-261
Timestamp: 2025-11-12T04:55:42.193Z
Learning: In the context of S3 REST requests (src/endpoint/s3/s3_rest.js), the account.owner field from req.object_sdk.requesting_account is already a string (account ID) because it comes from RPC serialization where owner._id.toString() is applied in account_server.js. No additional .toString() or ._id extraction is needed when passing account.owner to IAM utility functions.
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9277
File: src/endpoint/s3/s3_bucket_policy_utils.js:357-368
Timestamp: 2025-11-18T07:00:17.653Z
Learning: In NooBaa codebase, account.name is always a SensitiveString instance, so calling account.name.unwrap() is safe without defensive type checks in functions like get_bucket_policy_principal_arn in src/endpoint/s3/s3_bucket_policy_utils.js.
Learnt from: shirady
Repo: noobaa/noobaa-core PR: 9291
File: src/server/common_services/auth_server.js:548-554
Timestamp: 2025-11-19T15:03:42.260Z
Learning: In src/server/common_services/auth_server.js, account objects are loaded directly from system_store (e.g., system_store.data.get_by_id()), so account.owner is an object ID reference with an ._id property, not a string. This differs from s3_rest.js where account.owner is a string due to RPC serialization.
📚 Learning: 2025-11-12T04:55:42.193Z
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9277
File: src/endpoint/s3/s3_rest.js:258-261
Timestamp: 2025-11-12T04:55:42.193Z
Learning: In the context of S3 REST requests (src/endpoint/s3/s3_rest.js), the account.owner field from req.object_sdk.requesting_account is already a string (account ID) because it comes from RPC serialization where owner._id.toString() is applied in account_server.js. No additional .toString() or ._id extraction is needed when passing account.owner to IAM utility functions.

Applied to files:

  • src/endpoint/s3/s3_rest.js
  • src/endpoint/s3/s3_bucket_policy_utils.js
  • src/server/system_services/bucket_server.js
📚 Learning: 2025-11-18T07:00:17.653Z
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9277
File: src/endpoint/s3/s3_bucket_policy_utils.js:357-368
Timestamp: 2025-11-18T07:00:17.653Z
Learning: In NooBaa codebase, account.name is always a SensitiveString instance, so calling account.name.unwrap() is safe without defensive type checks in functions like get_bucket_policy_principal_arn in src/endpoint/s3/s3_bucket_policy_utils.js.

Applied to files:

  • src/endpoint/s3/s3_rest.js
  • src/endpoint/s3/s3_bucket_policy_utils.js
  • src/server/system_services/bucket_server.js
📚 Learning: 2025-11-13T07:56:23.620Z
Learnt from: shirady
Repo: noobaa/noobaa-core PR: 9281
File: src/server/system_services/account_server.js:1053-1058
Timestamp: 2025-11-13T07:56:23.620Z
Learning: In noobaa-core, account_server.js is only used in containerized deployments, not in NSFS/NC deployments. NSFS/NC deployments have separate account management code in src/manage_nsfs/ directory. Therefore, account_server.js only processes accounts from account_schema.js where owner is an objectid reference, never from nsfs_account_schema.js where owner is a string.

Applied to files:

  • src/endpoint/s3/s3_rest.js
  • src/server/system_services/bucket_server.js
📚 Learning: 2025-11-19T15:03:42.260Z
Learnt from: shirady
Repo: noobaa/noobaa-core PR: 9291
File: src/server/common_services/auth_server.js:548-554
Timestamp: 2025-11-19T15:03:42.260Z
Learning: In src/server/common_services/auth_server.js, account objects are loaded directly from system_store (e.g., system_store.data.get_by_id()), so account.owner is an object ID reference with an ._id property, not a string. This differs from s3_rest.js where account.owner is a string due to RPC serialization.

Applied to files:

  • src/endpoint/s3/s3_rest.js
  • src/server/system_services/bucket_server.js
🧬 Code graph analysis (1)
src/endpoint/s3/s3_bucket_policy_utils.js (3)
src/endpoint/s3/s3_rest.js (3)
  • is_nc_deployment (253-253)
  • account (252-252)
  • account (358-358)
src/server/system_services/bucket_server.js (1)
  • account (561-561)
src/util/account_util.js (2)
  • account (30-42)
  • account (196-196)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Noobaa Image
  • GitHub Check: run-jest-unit-tests
  • GitHub Check: run-package-lock-validation
🔇 Additional comments (3)
src/endpoint/s3/s3_bucket_policy_utils.js (1)

432-432: LGTM!

The export of the new helper function is correct.

src/server/system_services/bucket_server.js (1)

562-566: LGTM!

The guard against IAM user principals identified by ID is correct. The null check for account prevents runtime errors, and the account.owner check properly identifies IAM users. This successfully blocks IAM user IDs from being used as principals in bucket policies.

Based on learnings, in bucket_server.js, account.owner is an object ID reference (not a string), so the truthy check correctly identifies IAM users.

src/endpoint/s3/s3_rest.js (1)

255-257: Fix typos in comment.

Apply this diff:

-    // Both NSFS NC and containerized will validate bucket policy against acccount id 
-    // but in containerized deplyment not against IAM user ID.
+    // Both NSFS NC and containerized will validate bucket policy against account id 
+    // but in containerized deployment not against IAM user ID.
     const account_identifier_id = s3_bucket_policy_utils.get_account_identifier_id(is_nc_deployment, account);

The comment typos ("acccount" and "deplyment") should be corrected. Regarding the consistency concern about IAM user ID validation between this file and bucket_server.js: verify this is intentional behavior for NC backward compatibility, as the current implementation allows policy checks against IAM user IDs while bucket_server.js blocks them as principals.

* @param {object} account
*/
function get_account_identifier_id(is_nc_deployment, account) {
if (is_nc_deployment || (!is_nc_deployment && account.owner === undefined)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure that you need this part !is_nc_deployment:
in case: is_nc_deployment = true, enter the condition on the first part
in case: is_nc_deployment = false enter the condition on the second part only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants