Skip to content

Conversation

@shirady
Copy link
Contributor

@shirady shirady commented Nov 25, 2025

Describe the Problem

Currently, bucket policy principal of ARN was for root user account only, after this change it would be effective for IAM users under this account as well.

Explain the Changes

  1. Add additional check after the check of bucket policy by principal ARN of the user to also check the permission in account level.

Issues:

List of GAPs:

  1. This code does not handle a case where there is a user under an OBC account, in case we decide to add this layer.
  2. The tests are only manual at this point; there is a plan to add automated tests after we have the design change.

Testing Instructions:

  1. Build the images and install the NooBaa system on Rancher Desktop (see guide).
    Note: nb is an alias that runs the local operator from build/_output/bin (alias created by devenv).
  2. Wait for the default backing store pod to be in state Ready before starting the tests: kubectl wait --for=condition=available backingstore/noobaa-default-backing-store --timeout=6m -n test1
  3. I'm using port-forward (in a different tab):
  • S3 kubectl port-forward -n test1 service/s3 12443:443
  • IAM kubectl port-forward -n test1 service/iam 14443:443
  1. create 2 accounts:
  • nb account create shira-acc01 -n test1 --show-secrets
  • nb account create shira-acc02 -n test1 --show-secrets
  1. Create the alias for the accounts:
    account-1-s3='AWS_ACCESS_KEY=<access-key> AWS_SECRET_ACCESS_KEY=<secret-key> aws --no-verify-ssl --endpoint-url https://localhost:12443'
    account-2-s3='AWS_ACCESS_KEY=<access-key> AWS_SECRET_ACCESS_KEY=<secret-key> aws --no-verify-ssl --endpoint-url https://localhost:12443'
    account-2-iam='AWS_ACCESS_KEY=<access-key> AWS_SECRET_ACCESS_KEY=<secret-key> aws --no-verify-ssl --endpoint-url https://localhost:14443'
  2. Check the connection to the endpoint:
  • try to list the buckets: account-1-s3 s3 ls; echo $? account-2-s3 s3 ls; echo $?
  1. Create a bucket for each account:
  • account-1-s3 s3 mb s3://buc-acc1
  • account-2-s3 s3 mb s3://buc-acc2
  1. Create a user under account 2: account-2-iam iam create-user --user-name Robert
    Note: To validate user creation, you can run account-2-iam iam list-users and expect 1 user in the list
  2. Create access keys: account-2-iam iam create-access-keys --user-name Robert
  3. Add IAM policy to the user: account-2-iam iam put-user-policy --user-name Robert --policy-name policy_allow_s3 --policy-document file://~/Documents/iam-tests/iam_policies/policy_allow_s3.json

policy_allow_s3.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": "*"
        }
    ]
}
  1. Create the alias for the user (like in step 5 with alias user-2-s3): user-1-s3='AWS_ACCESS_KEY=<access-key> AWS_SECRET_ACCESS_KEY=<secret-key> aws --no-verify-ssl --endpoint-url https://localhost:12443'
  2. The case with no bucket policy, for example:
  • The user cannot put an object in the bucket in the second account:
    echo 'test_data' | user-1-s3 s3 cp - s3://buc-acc1/test_object.txt (should not work)
  • The user can list objects in the bucket (to check the flow of the RPC call of has_bucket_action_permission function that was created in the auth_server):
    user-1-s3 s3 ls s3://buc-acc1 (should work)
  1. Find the ID of account 2 for the ARN, for example by running: account-2-s3 s3api get-bucket-acl --bucket buc-acc2 and taking the ID.
  2. Add bucket policy of the root account user as principal:
    account-1-s3 s3api put-bucket-policy --bucket buc-acc1 --policy file://policy_principal_arn_owner.json

policy_principal_arn_owner.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::69259fff8b07c200228c4fb3:root"
                ]
            },
            "Action": [
                "s3:*"
            ],
            "Resource": "*"
        }
    ]
}

Code changes for testing:

  1. To see the account (of a user) in the cache after changes, src/sdk/object_sdk.js uses cache expiry of 1 millisecond.
const account_cache = new LRUCache({
    name: 'AccountCache',
-    expiry_ms: config.OBJECT_SDK_ACCOUNT_CACHE_EXPIRY_MS,
+   expiry_ms: 1, //SDSD 

Notes:

  • In step 1 - deploying the system, I used --use-standalone-db for simplicity (fewer steps for the system in Ready status).

  • Doc added/updated

  • Tests added

@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

Walkthrough

Implements ownership-based ARN permission checks in bucket authorization with conditional logic for NC versus non-NC deployments. Modifies the S3 REST endpoint to compute account identifiers differently and adds a new owner-based ARN permission check path. Updates auth_server to verify bucket owner root account permissions and enforce DENY when owner-based checks fail.

Changes

Cohort / File(s) Summary
Authorization permission logic
src/server/common_services/auth_server.js
Adds owner ARN permission check to has_bucket_action_permission: when account.owner exists, computes owner's ARN, queries bucket policy for that ARN, and enforces DENY if owner check fails. Final permission result now includes owner ARN-based ALLOW pathway alongside existing is_owner check.
S3 endpoint authorization flow
src/endpoint/s3/s3_rest.js
Introduces conditional owner-based ARN checks for NC vs non-NC deployments. Computes account_identifier_name differently per deployment type. Invokes permission_by_arn with disallow_public_access option. Adds new permission_by_arn_owner path for non-NC deployments that influences final allow/deny decision alongside existing id/name/arn checks and ownership status.

Sequence Diagram

sequenceDiagram
    participant Client
    participant S3REST as S3 REST<br/>Endpoint
    participant AuthServer
    participant Policy as Bucket Policy
    
    Client->>S3REST: Request
    S3REST->>S3REST: Determine deployment<br/>(NC vs non-NC)
    alt Non-NC Deployment
        S3REST->>S3REST: permission_by_arn<br/>(disallow_public_access)
        S3REST->>AuthServer: has_bucket_action_permission<br/>(including owner check)
    else NC Deployment
        S3REST->>S3REST: permission_by_arn<br/>(disallow_public_access)
        S3REST->>S3REST: Standard checks
    end
    
    AuthServer->>AuthServer: Check if<br/>account.owner exists
    alt Account has owner
        AuthServer->>AuthServer: Compute owner ARN
        AuthServer->>Policy: Query owner ARN<br/>permissions
        Policy-->>AuthServer: Policy result
        alt Owner DENY
            AuthServer-->>S3REST: Return false
            S3REST->>Client: Access Denied
        else Owner ALLOW
            AuthServer-->>S3REST: Return true
        end
    else No owner
        AuthServer->>AuthServer: Use existing<br/>is_owner check
        AuthServer-->>S3REST: Return result
    end
    
    S3REST->>Client: Grant/Deny Access
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Extra attention areas:
    • NC vs non-NC deployment branching logic and account_identifier_name computation in s3_rest.js
    • Owner ARN query and early DENY enforcement in auth_server.js has_bucket_action_permission
    • Integration between permission_by_arn with disallow_public_access and new permission_by_arn_owner path
    • Interaction between new owner checks and existing is_owner/id/name/arn authorization pathways

Possibly related PRs

Suggested reviewers

  • aayushchouhan09
  • liranmauda
  • jackyalbo

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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
Title check ✅ Passed The title accurately reflects the main change: adding bucket policy principal checks for the account root user when the requesting account is an IAM user, which aligns with the PR's objectives and code modifications.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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.

@shirady shirady self-assigned this Nov 25, 2025
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.

1 participant