Skip to content

Remove bcrypt#9211

Merged
tangledbytes merged 1 commit intonoobaa:masterfrom
tangledbytes:utkarsh/prune/password
Sep 8, 2025
Merged

Remove bcrypt#9211
tangledbytes merged 1 commit intonoobaa:masterfrom
tangledbytes:utkarsh/prune/password

Conversation

@tangledbytes
Copy link
Member

@tangledbytes tangledbytes commented Sep 5, 2025

Explain the Changes

This PR attempts to remove bcrypt. The following are the changes:

  1. Removes bcrypt as dependency
  2. Remove create_auth RPC. Wherever required, the call to this RPC is replaced by auth_server.make_auth_token function which creates a token on the fly using share JWT secret.
  3. Remove reset_password RPC.
  4. The tests are updated accordingly as well.

Issues: Fixed #xxx / Gap #xxx

Testing Instructions:

  • Doc added/updated
  • Tests added

Summary by CodeRabbit

  • New Features

    • CLI/tools accept/use auth tokens; auto-generate admin tokens when not provided.
  • Refactor

    • Sign-in shifted from email/password RPC flow to locally generated admin tokens; password fields deprecated and password-reset flows removed.
  • Chores

    • Removed legacy bcrypt utility and dependency.
  • Tests

    • Test suites and helpers updated to use generated admin tokens for authentication.

@coderabbitai
Copy link

coderabbitai bot commented Sep 5, 2025

Caution

Review failed

An error occurred during the review process. Please try again later.

Warning

Tools execution failed with the following error:

Failed to run tools: 8 RESOURCE_EXHAUSTED: Received message larger than max (31050845 vs 4194304)

✨ Finishing Touches
🧪 Generate unit tests
  • 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: 16

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/test/pipeline/account_test.js (2)

302-317: Login via token: remove password from payload and fix error text.

Password is unused in local-token flow; update error to match new call.

 async function login_user(email) {
     console.log(`login user: ${email}`);
     rpc = api.new_rpc_from_base_address(`wss://${TEST_CFG.mgmt_ip}:${TEST_CFG.mgmt_port_https}`, 'EXTERNAL');
     client = rpc.new_client({});
     const auth_params = {
         email,
-        password: 'DeMo1',
         system: 'demo',
         role: 'admin'
     };
     try {
-        client.options.auth_token = make_auth_token(auth_params);
+        client.options.auth_token = make_auth_token(auth_params);
     } catch (e) {
-        throw new Error(`failed to create_auth_token for ${auth_params.email}`);
+        throw new Error(`failed to make_auth_token for ${auth_params.email}`);
     }
 }

419-449: Remove all password-based auth artifacts and bcrypt

  • Tests & CLI still call create_auth_token/reset_password (e.g., src/test/pipeline/account_test.js lines 82, 315; agent_cli.js)
  • bcrypt remains a dependency (package.json) and is imported in the AWS CLI signature tests (awscli_iwgdirl7.sreq)
    Refactor tests and CLI to use only the new token-based API and drop bcrypt.
🧹 Nitpick comments (31)
src/server/system_services/schemas/account_schema.js (1)

28-29: Formalize deprecation flags on password fields (and consider deprecating has_login).

The comments are helpful. If your schema tooling supports it, set a machine-readable flag to propagate to validators/docs.

Apply:

-        password: { wrapper: SensitiveString }, // bcrypted password - DEPRECATED
-        next_password_change: { date: true }, // DEPRECATED
+        password: { wrapper: SensitiveString, deprecated: true, description: 'bcrypted password - DEPRECATED' },
+        next_password_change: { date: true, deprecated: true, description: 'DEPRECATED' },

Also consider marking has_login as deprecated in this schema (or documenting the new token-only flow where relevant).

Would you like me to scan the codebase for any uses that still rely on has_login/password and open a follow-up?

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

545-545: Reset password endpoint now forbidden—verify UI/clients and consider removing the RPC.

Blocking with FORBIDDEN is fine, but ensure all callers (UI/CLI/automation) have migrated to token-only flows to avoid user-facing errors. Consider removing the RPC/surfacing a clearer NOT_SUPPORTED code if your clients distinguish it.

Would you like a follow-up patch to remove the RPC from the schema and update any UI text?

src/test/system_tests/test_bucket_placement.js (2)

18-18: Importing token generator in tests is fine; keep it test-only.

Ensure make_auth_token usage remains confined to test/CI codepaths to avoid accidental enablement in user-facing tooling.


44-48: Avoid hard-coded admin identity; parameterize via argv/env.

This improves portability across environments and clusters.

Apply:

-    const auth_params = {
-        email: 'demo@noobaa.com',
-        role: 'admin',
-        system: 'demo',
-    };
+    const email = argv.email || process.env.NOOBAA_EMAIL || 'demo@noobaa.com';
+    const system = argv.system || process.env.NOOBAA_SYSTEM || 'demo';
+    const role = argv.role || 'admin';
+    const auth_params = { email, role, system };
src/test/pipeline/quota_test.js (1)

226-230: Parameterize credentials; don’t hard-code admin.

Keeps pipeline tests reusable across environments.

-        client.options.auth_token = make_auth_token({
-            email: 'demo@noobaa.com',
-            role: 'admin',
-            system: 'demo',
-        });
+        const email = argv.email || process.env.NOOBAA_EMAIL || 'demo@noobaa.com';
+        const system = argv.system || process.env.NOOBAA_SYSTEM || 'demo';
+        const role = argv.role || 'admin';
+        client.options.auth_token = make_auth_token({ email, role, system });
src/test/utils/basic_server_ops.js (1)

147-153: Centralize token creation to a small helper; reduce duplication.

Many tests repeat the same admin token snippet. Extract to a shared test util to avoid drift.

Example inline tweak (if you prefer not to add a helper yet):

-            const auth_params = {
-                email: 'demo@noobaa.com',
-                role: 'admin',
-                system: 'demo'
-            };
-            client.options.auth_token = make_auth_token(auth_params);
+            const email = process.env.NOOBAA_EMAIL || 'demo@noobaa.com';
+            const system = process.env.NOOBAA_SYSTEM || 'demo';
+            const role = 'admin';
+            client.options.auth_token = make_auth_token({ email, role, system });

If desired, I can propose a src/test/utils/auth.js with get_admin_token() and submit a follow-up patch.

src/test/qa/data_availability_test.js (1)

196-202: Rename or update function intent and parameterize identity.

  • The function no longer “creates” via RPC; consider a clearer name (e.g., set_rpc_and_set_auth_token).
  • Also remove hard-coded admin.
-async function set_rpc_and_create_auth_token() {
-    const auth_params = {
-        email: 'demo@noobaa.com',
-        system: 'demo',
-        role: 'admin',
-    };
-    client.options.auth_token = make_auth_token(auth_params);
-}
+async function set_rpc_and_set_auth_token() {
+    const email = argv.email || process.env.NOOBAA_EMAIL || 'demo@noobaa.com';
+    const system = argv.system || process.env.NOOBAA_SYSTEM || 'demo';
+    const role = argv.role || 'admin';
+    client.options.auth_token = make_auth_token({ email, role, system });
+}

Remember to update its call site accordingly.

src/test/system_tests/test_s3_authentication.js (1)

35-42: Make auth configurable and future-proof against token expiry.

  • Parameterize identity; avoid hard-coded admin.
  • If tests can run long, ensure token TTL is sufficient or refresh on 401.
 function authenticate() {
-    const auth_params = {
-        email: 'demo@noobaa.com',
-        role: 'admin',
-        system: 'demo',
-    };
-    client.options.auth_token = make_auth_token(auth_params);
+    const email = argv.email || process.env.NOOBAA_EMAIL || 'demo@noobaa.com';
+    const system = argv.system || process.env.NOOBAA_SYSTEM || 'demo';
+    const role = argv.role || 'admin';
+    client.options.auth_token = make_auth_token({ email, role, system });
 }

If make_auth_token supports TTL, consider passing an explicit value suitable for the test duration.

src/test/external_tests/external_tests_utils.js (3)

25-28: Validate required env before using it.

Fail fast with a clear message when email is missing.

 async function get_authenticated_global_rpc_client() {
-    const global_rpc_client = await get_rpc_client_by_email_and_password(process.env.email, process.env.password);
+    if (!process.env.email) throw new Error('Missing required env var: email');
+    const global_rpc_client = await get_rpc_client_by_email_and_password(process.env.email, process.env.password);
     return global_rpc_client;
 }

62-69: Guard against accounts with no access keys.

Prevents TypeError when the list is empty and yields a clearer error.

 async function get_account_access_keys(account_name) {
     const account = is_containerized_deployment() ?
         await get_account_by_name(account_name) :
         await get_account(account_name);
-    const access_keys = account.access_keys[0];
+    if (!account.access_keys || account.access_keys.length === 0) {
+        throw new Error(`Account "${account_name}" has no access keys`);
+    }
+    const access_keys = account.access_keys[0];
     const access_key = new SensitiveString(access_keys.access_key).unwrap();
     const secret_key = new SensitiveString(access_keys.secret_key).unwrap();
     return { access_key, secret_key };
 }

116-116: Remove leftover debug log.

Avoid leaking internal objects to stdout in CI.

-    console.log(test_pool);
src/test/pipeline/account_test.js (2)

75-83: Drop stale 'reset_password' case from reporter.

This case no longer exists and skews reporting.

 const cases = [
     'create_account',
     'delete_account',
     'regenerate_s3Access',
     'edit_s3Access',
     'edit_bucket_creation',
     'restrict_ip_access',
-    'reset_password'
 ];

142-150: Use the function argument instead of the global for s3_access.

The parameter is currently ignored.

 function set_account_details(has_login, account_name, email, s3_access) {
     return {
         name: account_name,
         email,
         password: TEST_CFG.password,
         has_login,
-        s3_access: TEST_CFG.s3_access,
+        s3_access,
     };
 }
src/test/integration_tests/internal/test_system_servers.js (1)

287-292: Reset token back to original system after rename.

Avoid mismatched system claim for subsequent calls.

         rpc_client.options.auth_token = make_auth_token({
             email: EMAIL,
             system: SYS1,
             role: 'admin'
         });
         await rpc_client.system.update_system({ name: SYSTEM });
+        // Reset token to match reverted system name
+        rpc_client.options.auth_token = make_auth_token({
+            email: EMAIL,
+            system: SYSTEM,
+            role: 'admin'
+        });
src/test/qa/rebuild_replicas_test.js (2)

12-12: Avoid coupling tests to server internals for token minting

Importing make_auth_token directly from server code makes tests depend on server internals. Prefer consuming a token from env (e.g., NB_ADMIN_TOKEN) and only fall back to local minting, to keep tests flexible across environments.

Apply within set_rpc_and_create_auth_token:

-    client.options.auth_token = make_auth_token(auth_params);
+    client.options.auth_token = process.env.NB_ADMIN_TOKEN || make_auth_token(auth_params);

255-262: Name mismatch: function now “sets” not “creates” an auth token

Minor: set_rpc_and_create_auth_token no longer creates a token via RPC. Consider renaming to reflect behavior (e.g., set_rpc_and_apply_auth_token) to avoid confusion.

src/test/integration_tests/nsfs/test_nsfs_integration.js (1)

279-283: Prefer env-provided admin token; fall back to local minting

This keeps tests portable across CI/prod-like environments where only a pre-minted token should be used.

-        rpc_client.options.auth_token = make_auth_token({
+        rpc_client.options.auth_token = process.env.NB_ADMIN_TOKEN || make_auth_token({
             email: EMAIL,
             role: 'admin',
             system: SYSTEM,
         });
src/test/pipeline/namespace_test.js (1)

281-287: Make token source configurable (env first), then mint locally

Improves portability and reduces tight coupling on server internals in pipeline runs.

-    client.options.auth_token = make_auth_token(auth_params);
+    client.options.auth_token = process.env.NB_ADMIN_TOKEN || make_auth_token(auth_params);
src/cmd/backingstore.js (2)

105-110: Validate required env before minting an admin token

If CREATE_SYS_NAME or CREATE_SYS_EMAIL are unset, make_auth_token may create an unusable token; fail fast with a clear error.

-        client.options.auth_token = make_auth_token({
-            system: process.env.CREATE_SYS_NAME,
-            role: 'admin',
-            email: process.env.CREATE_SYS_EMAIL
-        });
+        const { CREATE_SYS_NAME, CREATE_SYS_EMAIL } = process.env;
+        if (!CREATE_SYS_NAME || !CREATE_SYS_EMAIL) {
+            throw new Error('backingstore: CREATE_SYS_NAME and CREATE_SYS_EMAIL env vars are required to mint admin token');
+        }
+        client.options.auth_token = make_auth_token({
+            system: CREATE_SYS_NAME,
+            role: 'admin',
+            email: CREATE_SYS_EMAIL,
+        });

105-110: Security check: ensure make_auth_token is safe in this context

Local admin-token minting in a CLI path can be risky if not backed by a server-held signing key, short TTL, and proper audience. Please confirm:

  • Tokens are signed with a server-private key not shipped to clients.
  • Tokens have short expiration and audience bound to the target address/cluster.
  • This path is intended for controlled environments (e.g., DEV/CI).
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (1)

39-41: Guard missing email env

If process.env.email is unset, auth_params.email becomes undefined. Add an explicit check to fail early with a clear error.

-        const auth_params = { email: process.env.email, system: 'noobaa', role: 'admin' };
+        const email = process.env.email;
+        if (!email) throw new Error('Ceph S3 setup: missing required env var "email" for admin auth');
+        const auth_params = { email, system: 'noobaa', role: 'admin' };
         client.options.auth_token = make_auth_token(auth_params);
src/test/utils/agent_functions.js (1)

8-8: DRY: centralize token assignment

Repeated make_auth_token(auth_params) calls can be wrapped to reduce duplication.

-        client.options.auth_token = make_auth_token(auth_params);
+        set_admin_token(client);

Repeat similarly for Lines 40, 87, 133.

Add helper (outside the changed ranges):

function set_admin_token(client) {
    client.options.auth_token = make_auth_token(auth_params);
}

Also applies to: 15-17, 31-31, 40-40, 87-87, 133-133

src/test/system_tests/test_bucket_access.js (1)

21-21: Local admin token generation looks correct; minor polish possible

Import + make_auth_token usage is consistent with the new flow. Since authenticate() is now synchronous, awaiting it later is redundant (optional cleanup).

Optional diff (outside this hunk) to drop the unnecessary await:

-    await authenticate();
+    authenticate();

Also applies to: 79-83

src/test/system_tests/test_md_aggregator.js (1)

16-16: Auth shift is fine; consider renaming and simplifying call chain

Switch to make_auth_token is good. create_auth() is now synchronous—rename to authenticate() and remove the promise hop for clarity.

Suggested refactor (outside this hunk):

-function create_auth() {
+function authenticate() {
   const auth_params = {
     email: 'demo@noobaa.com',
     role: 'admin',
     system: 'demo',
   };
   client.options.auth_token = make_auth_token(auth_params);
 }
 
 // in run_test()
 return control_services('stop', ['bg_workers'])
-  .then(() => create_auth())
+  .then(() => { authenticate(); })
   .then(() => prepare_buckets_with_objects())

Also applies to: 33-39

src/test/qa/agents_matrix.js (1)

48-49: Good switch; update stale error message

The token setup is correct. The catch block still logs “create_auth_token has failed”. Update to reflect make_auth_token.

-    } catch (e) {
-        console.error(`create_auth_token has failed`, e);
+    } catch (e) {
+        console.error(`make_auth_token failed`, e);

Also applies to: 108-113

src/test/system_tests/test_node_failure.js (1)

17-17: Auth change looks good; await is unnecessary now

make_auth_token usage is consistent. Since authenticate() is synchronous, you can drop the await at its call site for clarity.

Optional diff (outside this hunk):

-        await authenticate();
+        authenticate();

Also applies to: 53-58

src/test/pipeline/run_dataset.js (1)

62-70: Update error message to reflect local token generation.

Message still references create_auth_token; adjust for make_auth_token to reduce confusion.

-        } catch (e) {
-            console.error(`create_auth_token has failed`, e);
+        } catch (e) {
+            console.error(`make_auth_token (local token generation) failed`, e);
             process.exit(1);
         }
src/test/qa/reclaim_test.js (1)

158-165: Rename helper to reflect behavior change.

set_rpc_and_create_auth_token no longer “creates” via RPC; consider set_rpc_and_set_auth_token for clarity.

src/test/utils/server_functions.js (1)

49-55: Deduplicate token setup in tests.

Token building and assignment are duplicated; extract a small helper (e.g., get_admin_token(client)) to reduce repetition and make role/system easy to adjust.

Example:

function set_admin_token(client, { email = 'demo@noobaa.com', system = 'demo' } = {}) {
    client.options.auth_token = make_auth_token({ email, system, role: 'admin' });
}

Also applies to: 71-76

src/tools/md_blow_lifecycle.js (1)

9-9: Gate local admin-token minting to dev/test.

Minting admin tokens client-side is dangerous if this tool ships in prod. Add an explicit env guard.

@@
-        client.options.auth_token = make_auth_token(auth_params);
+        if (process.env.NOOBAA_ALLOW_LOCAL_ADMIN_TOKEN !== '1') {
+            throw new Error('Local admin token minting disabled. Set NOOBAA_ALLOW_LOCAL_ADMIN_TOKEN=1 for dev/test only.');
+        }
+        client.options.auth_token = make_auth_token(auth_params);
src/tools/md_blow.js (1)

36-42: Token flow looks correct; mirror the dev/test guard and remove password vestiges.

You already load master keys; add the safety guard and drop the unused password arg to avoid confusion.

@@
-argv.password = argv.password || 'DeMo1';
@@
-        client.options.auth_token = make_auth_token(auth_params);
+        if (process.env.NOOBAA_ALLOW_LOCAL_ADMIN_TOKEN !== '1') {
+            throw new Error('Local admin token minting disabled. Set NOOBAA_ALLOW_LOCAL_ADMIN_TOKEN=1 for dev/test only.');
+        }
+        client.options.auth_token = make_auth_token(auth_params);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0bf3bf6 and 50064a2.

📒 Files selected for processing (39)
  • src/agent/block_store_speed.js (2 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (3 hunks)
  • src/server/system_services/account_server.js (3 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (2 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (4)
  • src/sdk/nb.d.ts
  • src/tools/bcrypt_cli.js
  • src/test/integration_tests/api/s3/test_bucket_replication.js
  • src/rpc/rpc_schema.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/pipeline/run_dataset.js
  • src/test/qa/cloud_test.js
  • src/test/external_tests/external_tests_utils.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/utils/basic_server_ops.js
  • src/test/system_tests/test_s3_authentication.js
  • src/test/system_tests/sanity_build_test.js
  • src/test/system_tests/test_md_aggregator.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/test/utils/agent_functions.js
  • src/test/pipeline/account_test.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
  • src/test/pipeline/system_config.js
  • src/test/system_tests/test_bucket_placement.js
  • src/test/pipeline/namespace_test.js
  • src/test/utils/server_functions.js
  • src/test/qa/reclaim_test.js
  • src/test/qa/rebuild_replicas_test.js
  • src/test/qa/agents_matrix.js
  • src/test/system_tests/test_cloud_pools.js
  • src/test/integration_tests/internal/test_system_servers.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/test/system_tests/test_node_failure.js
  • src/test/qa/data_availability_test.js
  • src/test/pipeline/quota_test.js
🧬 Code graph analysis (30)
src/test/pipeline/run_dataset.js (4)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • client (22-24)
src/cmd/api.js (3)
src/cmd/backingstore.js (1)
  • require (19-19)
src/agent/block_store_speed.js (2)
  • token (39-43)
  • argv (5-5)
src/server/common_services/auth_server.js (3)
  • token (150-156)
  • token (258-263)
  • process (59-66)
src/test/qa/cloud_test.js (7)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/cmd/backingstore.js (1)
  • require (19-19)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)
  • require (16-16)
  • require (17-17)
src/test/external_tests/external_tests_utils.js (2)
  • require (5-5)
  • require (7-7)
src/test/integration_tests/internal/test_system_servers.js (1)
  • require (16-16)
src/test/external_tests/external_tests_utils.js (3)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/integration_tests/internal/test_system_servers.js (1)
  • require (16-16)
src/test/system_tests/test_bucket_access.js (3)
src/test/system_tests/test_cloud_pools.js (3)
  • require (8-8)
  • require (15-15)
  • auth_params (146-150)
src/test/system_tests/test_node_failure.js (2)
  • require (17-17)
  • auth_params (52-56)
src/test/system_tests/test_s3_authentication.js (4)
  • require (4-4)
  • require (5-5)
  • require (16-16)
  • auth_params (36-40)
src/test/utils/basic_server_ops.js (1)
src/test/system_tests/test_bucket_placement.js (2)
  • require (18-18)
  • auth_params (44-48)
src/test/system_tests/test_s3_authentication.js (2)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/test/system_tests/test_bucket_access.js (4)
  • require (18-18)
  • require (21-21)
  • client (37-39)
  • auth_params (77-81)
src/test/system_tests/sanity_build_test.js (6)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/system_tests/test_cloud_pools.js (1)
  • auth_params (146-150)
src/test/pipeline/account_test.js (1)
  • auth_params (306-311)
src/test/system_tests/test_bucket_access.js (1)
  • auth_params (77-81)
src/test/system_tests/test_md_aggregator.js (2)
src/test/system_tests/test_bucket_placement.js (5)
  • require (18-18)
  • client (31-33)
  • client (108-111)
  • client (129-132)
  • auth_params (44-48)
src/test/utils/basic_server_ops.js (4)
  • require (10-10)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)
src/server/common_services/auth_server.js (2)
  • require (7-7)
  • process (59-66)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/server/common_services/auth_server.js (1)
src/server/system_services/account_server.js (5)
  • req (241-241)
  • req (549-549)
  • req (1362-1362)
  • system_store (18-18)
  • _ (5-5)
src/test/utils/agent_functions.js (5)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/cmd/backingstore.js (1)
  • require (19-19)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/qa/agents_matrix.js (2)
  • require (6-6)
  • require (48-48)
src/test/pipeline/account_test.js (6)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/namespace_test.js (1)
  • auth_params (281-285)
src/test/pipeline/system_config.js (1)
  • auth_params (209-213)
src/test/integration_tests/nsfs/test_nsfs_integration.js (1)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/pipeline/system_config.js (3)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/cmd/backingstore.js (2)
src/cmd/api.js (1)
  • require (14-14)
src/server/common_services/auth_server.js (1)
  • process (59-66)
src/server/system_services/account_server.js (3)
src/server/system_services/stats_aggregator.js (5)
  • support_account (599-599)
  • support_account (1163-1163)
  • support_account (1200-1200)
  • support_account (1233-1233)
  • system_store (16-16)
src/server/system_services/system_server.js (3)
  • support_account (863-863)
  • system_store (32-32)
  • system_store (1188-1188)
src/server/common_services/auth_server.js (2)
  • system_store (9-9)
  • SensitiveString (12-12)
src/agent/block_store_speed.js (2)
src/cmd/api.js (2)
  • token (63-67)
  • api (13-13)
src/server/common_services/auth_server.js (2)
  • token (150-156)
  • token (258-263)
src/test/system_tests/test_bucket_placement.js (4)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • client (22-24)
  • auth_params (39-39)
src/test/system_tests/test_md_aggregator.js (3)
  • require (16-16)
  • client (26-28)
  • auth_params (33-37)
src/test/system_tests/test_node_failure.js (3)
  • require (17-17)
  • client (43-43)
  • auth_params (52-56)
src/test/utils/basic_server_ops.js (4)
  • require (10-10)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
src/test/pipeline/namespace_test.js (3)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/tools/nbcat.js (7)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/account_test.js (1)
  • auth_params (306-311)
src/test/pipeline/namespace_test.js (1)
  • auth_params (281-285)
src/test/pipeline/run_namespace_cache_tests.js (1)
  • auth_params (183-187)
src/test/utils/server_functions.js (4)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/cmd/backingstore.js (2)
  • require (19-19)
  • client (104-104)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • client (22-24)
  • auth_params (39-39)
src/test/qa/reclaim_test.js (6)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/cmd/backingstore.js (2)
  • require (19-19)
  • client (104-104)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • client (22-24)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/integration_tests/internal/test_system_servers.js (1)
  • require (16-16)
src/test/qa/rebuild_replicas_test.js (2)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/qa/agents_matrix.js (6)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/cmd/backingstore.js (1)
  • require (19-19)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)
  • require (16-16)
  • require (17-17)
src/test/utils/agent_functions.js (1)
  • require (8-8)
src/tools/md_blow.js (5)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
  • client (22-24)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/account_test.js (2)
  • auth_params (306-311)
  • client (17-17)
src/test/system_tests/test_cloud_pools.js (3)
src/test/system_tests/test_bucket_access.js (4)
  • require (18-18)
  • require (21-21)
  • client (37-39)
  • auth_params (77-81)
src/test/system_tests/test_s3_authentication.js (5)
  • require (4-4)
  • require (5-5)
  • require (16-16)
  • client (27-29)
  • auth_params (36-40)
src/test/utils/basic_server_ops.js (4)
  • require (10-10)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
src/test/pipeline/run_namespace_cache_tests.js (4)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (4)
  • require (5-5)
  • require (7-7)
  • rpc_client (37-37)
  • auth_params (38-38)
src/test/system_tests/test_node_failure.js (5)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/test/system_tests/test_bucket_access.js (4)
  • require (18-18)
  • require (21-21)
  • client (37-39)
  • auth_params (77-81)
src/test/system_tests/test_bucket_placement.js (5)
  • require (18-18)
  • client (31-33)
  • client (108-111)
  • client (129-132)
  • auth_params (44-48)
src/test/utils/basic_server_ops.js (4)
  • require (10-10)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
src/test/qa/data_availability_test.js (3)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/pipeline/account_test.js (1)
  • auth_params (306-311)
⏰ 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
🔇 Additional comments (21)
src/test/pipeline/run_namespace_cache_tests.js (1)

19-19: Switch to local token generation: LGTM.

Importing make_auth_token here aligns with the repo-wide migration away from server-issued tokens.

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

1385-1386: No remaining password-based auth in account_server.js. A scan of src/server/system_services shows only the disabled verify_authorized_account path handles authentication; no other password checks remain in system services.

src/server/common_services/auth_server.js (1)

619-633: Map systemsystem_name and normalize expiry units

  • Insert before picking options:
 function make_auth_token(options) {
+    const opts = { ...options };
+    if (opts.system && !opts.system_name) opts.system_name = opts.system;
     let auth = _.pick(opts, 'account_id', 'system_id', 'role', 'extra', 'authorized_by', 'email', 'system_name');
  • jsonwebtoken interprets a numeric expiresIn as seconds. If callers pass milliseconds (e.g., k8s flow ×1000), divide by 1000 or pass a string with “ms”/“s” units (unpkg.com)
src/test/qa/cloud_test.js (2)

81-81: Import looks good.

No issues with the source path.


160-167: system vs system_name mismatch will yield missing system in req.auth.

Either rename here to system_name or rely on the proposed make_auth_token alias mapping.

Suggested local change (if not updating make_auth_token):

-    const auth_params = {
-        email: 'demo@noobaa.com',
-        system: 'demo',
-        role: 'admin',
-    };
+    const auth_params = {
+        email: 'demo@noobaa.com',
+        system_name: 'demo',
+        role: 'admin',
+    };
src/test/system_tests/sanity_build_test.js (2)

15-15: Import OK.

Consistent with other test modules.


76-87: Same system vs system_name mismatch here; token won’t bind a system.

Rename to system_name unless make_auth_token maps system → system_name as proposed.

Minimal test-side fix:

     const auth_params = {
         email: 'demo@noobaa.com',
-        role: 'admin',
-        system: 'demo',
+        role: 'admin',
+        system_name: 'demo',
     };
 ...
-    TEST_CTX.client.options.auth_token = make_auth_token(auth_params);
+    TEST_CTX.client.options.auth_token = make_auth_token(auth_params);
src/test/pipeline/quota_test.js (1)

12-12: Consistent test import.

Matches the new auth pattern used elsewhere.

src/test/utils/basic_server_ops.js (1)

10-10: Import fits the new auth flow.

src/test/qa/data_availability_test.js (1)

11-11: Aligned import with repo-wide auth change.

src/test/system_tests/test_s3_authentication.js (1)

16-16: Import matches the new pattern.

src/test/external_tests/external_tests_utils.js (1)

5-5: Switch to local token generation looks good.

Import is appropriate for tests.

src/test/pipeline/account_test.js (1)

9-9: Import of make_auth_token is correct.

src/test/integration_tests/internal/test_system_servers.js (1)

16-16: Import change looks good.

src/test/integration_tests/nsfs/test_nsfs_integration.js (1)

38-38: LGTM: Switch to local token generation import

Importing make_auth_token aligns this suite with the new auth flow.

src/test/pipeline/namespace_test.js (1)

15-15: LGTM: Importing make_auth_token for pipeline tests

Matches the repo-wide auth changes.

src/test/system_tests/test_cloud_pools.js (1)

15-15: Import looks good

Token generation is now local; import is correct and consistent with other changes.

src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (1)

17-17: Import change is appropriate

Matches the new token flow used elsewhere.

src/cmd/api.js (1)

79-79: CLI commands honor client.options.auth_token. Verified no remaining create_auth_token calls or per-call auth_token overrides in src/cmd; all RPC invocations defer to the token set on client.options.auth_token.

src/test/qa/reclaim_test.js (1)

158-165: LGTM: token-based test auth is consistent with the new flow.

Setting client.options.auth_token via make_auth_token is clear and localized.

src/tools/md_blow.js (1)

13-13: LGTM: import aligns with repo-wide token switch.

Comment on lines +39 to +44
const token = argv.token || make_auth_token({
system: argv.system,
role: 'admin',
email: argv.email,
});

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Do not mint admin tokens in the agent; require explicit token (security).

The agent now generates an admin token locally. If the signing secret is present in the environment, any invocation can mint admin tokens without credentials. Require a provided token (flag/env), or at minimum gate local minting behind an explicit DEV flag.

-    const token = argv.token || make_auth_token({
-        system: argv.system,
-        role: 'admin',
-        email: argv.email,
-    });
+    const token = argv.token || process.env.NOOBAA_AUTH_TOKEN;
+    if (!token) {
+        throw new Error('Missing auth token. Pass --token or set NOOBAA_AUTH_TOKEN.');
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const token = argv.token || make_auth_token({
system: argv.system,
role: 'admin',
email: argv.email,
});
// Require an explicit auth token (via flag or env) rather than minting one automatically
- const token = argv.token || make_auth_token({
- system: argv.system,
- role: 'admin',
- email: argv.email,
const token = argv.token || process.env.NOOBAA_AUTH_TOKEN;
if (!token) {
throw new Error('Missing auth token. Pass --token or set NOOBAA_AUTH_TOKEN.');
}
🤖 Prompt for AI Agents
In src/agent/block_store_speed.js around lines 39 to 44, the code currently
auto-mints an admin token via make_auth_token when argv.token is missing;
instead require an explicit token or an explicit developer flag. Change the
logic to: if argv.token or process.env.TOKEN (or a documented token env var) is
provided, use it; else if a specific explicit DEV flag (e.g., argv.dev === true
or process.env.AGENT_DEV === '1') is present, allow make_auth_token for local
testing; otherwise log a clear error and exit with non-zero status. Ensure no
auto-minting occurs when a signing secret is present in production envs without
the explicit DEV flag.

const util = require('util');
const minimist = require('minimist');
const api = require('../api');
const { make_auth_token } = require('../server/common_services/auth_server');
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Stop minting admin tokens client-side; require a provided token (security).

Generating an admin token in the CLI couples it to the signing secret and bypasses server-side authentication. This is a privilege-escalation risk if the CLI ever runs where the secret is present. Prefer requiring a token via flag or env and fail fast if absent.

Apply:

-const { make_auth_token } = require('../server/common_services/auth_server');
+// require user-provided token; do not mint tokens client-side

@@
-        const token = argv.token || make_auth_token({
-            system: process.env.CREATE_SYS_NAME,
-            role: 'admin',
-            email: process.env.CREATE_SYS_EMAIL
-        });
+        const token = argv.token || process.env.NOOBAA_AUTH_TOKEN;
+        if (!token) {
+            console.error('Missing auth token. Pass --token or set NOOBAA_AUTH_TOKEN.');
+            return print_usage();
+        }

Also applies to: 63-68

🤖 Prompt for AI Agents
In src/cmd/api.js around lines 14 and 63-68, the CLI is minting admin tokens
client-side using make_auth_token which embeds the signing secret; remove that
behavior and require a token be supplied via a CLI flag or environment variable.
Replace calls that generate tokens with code that reads a provided token (e.g.,
process.env.ADMIN_TOKEN or parsed flag) and fail fast with a clear error if none
is present; remove any imports or usage of make_auth_token from this file and
update help/usage to document the required token parameter.

Comment on lines 41 to 45
--address <url> (default per api type) Set the address of the rpc server ()
--debug <level> (default 0) Increase debug level
--json Output raw json instead of printaable
--token <token> Token to authorize the request
--json Output raw json instead of printaable
`;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix OPTIONS typos and clarify address help text.

User-facing text: typo “printaable”; dangling “()” after rpc server.

-    --address <url>     (default per api type)           Set the address of the rpc server ()
+    --address <url>     (default per api type)           Set the address of the RPC server
@@
-    --json                                               Output raw json instead of printaable
+    --json                                               Output raw JSON instead of printable
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
--address <url> (default per api type) Set the address of the rpc server ()
--debug <level> (default 0) Increase debug level
--json Output raw json instead of printaable
--token <token> Token to authorize the request
--json Output raw json instead of printaable
`;
--address <url> (default per api type) Set the address of the RPC server
--debug <level> (default 0) Increase debug level
--token <token> Token to authorize the request
--json Output raw JSON instead of printable
`;
🤖 Prompt for AI Agents
In src/cmd/api.js around lines 41 to 45, the options help text contains a
dangling "()" after "rpc server" and a typo "printaable"; update the address
line to remove "()" and clarify it (e.g., "Set the address of the RPC server
(defaults vary by API type)") and fix "printaable" to "printable"; ensure "RPC"
is capitalized consistently and adjust the help string in this block
accordingly.

Comment on lines 36 to 38
function create_auth(req) {

const email = req.rpc_params.email;
const password = req.rpc_params.password;
const system_name = req.rpc_params.system;
let role_name = req.rpc_params.role;
let authenticated_account;
let target_account;
let system;

return P.resolve()
.then(() => {

// if email is not provided we skip finding target_account by email
// and use the current auth account as the authenticated_account
if (!email) return;

// consider email not found the same as bad password to avoid phishing attacks.
target_account = system_store.get_account_by_email(email);
if (!target_account) {
dbg.log0('credentials account not found', email, system_name);
throw new RpcError('UNAUTHORIZED', 'credentials not found');
}

// when password is not provided it means we want to give authorization
// by the currently authorized to another specific account instead of
// using credentials.
if (!password) return;

return P.resolve()
.then(() => bcrypt.compare(password.unwrap(), target_account.password.unwrap()))
.then(match => {
if (!match) {
dbg.log0('password mismatch', email, system_name);
throw new RpcError('UNAUTHORIZED', 'credentials not found');
}
// authentication passed!
// so this account is the authenticated_account
authenticated_account = target_account;
});
})
.then(() => {

// if both accounts were resolved (they can be the same account),
// then we can skip loading the current authorized account
if (!authenticated_account || !target_account) {
// find the current authorized account and assign
if (!req.auth || !req.auth.account_id) {
dbg.log0('no account_id in auth and no credentials', email, system_name);
throw new RpcError('UNAUTHORIZED', 'credentials not found');
}

const account_arg = system_store.data.get_by_id(req.auth.account_id);
target_account = target_account || account_arg;
authenticated_account = authenticated_account || account_arg;

}

// check the accounts are valid
if (!authenticated_account || authenticated_account.deleted) {
dbg.log0('authenticated account not found', email, system_name);
throw new RpcError('UNAUTHORIZED', 'credentials not found');
}
if (!target_account || target_account.deleted) {
dbg.log0('target account not found', email, system_name);
throw new RpcError('UNAUTHORIZED', 'credentials not found');
}

// system is optional, and will not be included in the token if not provided
if (system_name) {

// find system by name
system = system_store.data.systems_by_name[system_name];
if (!system || system.deleted) throw new RpcError('UNAUTHORIZED', 'system not found');

// find the role of authenticated_account in the system
const roles = system.roles_by_account &&
system.roles_by_account[authenticated_account._id];

// now approve the role -
if (
// support account can do anything
authenticated_account.is_support ||
// system owner can do anything
// From some reason, which I couldn't find, system store is
// missing roles_by_account from time to time.
String(system.owner._id) === String(authenticated_account._id) ||
// system admin can do anything
_.includes(roles, 'admin') ||
// operator can do anything
_.includes(roles, 'operator') ||
// non admin is not allowed to delegate roles to other accounts
(role_name && _.includes(roles, role_name) &&
String(target_account._id) === String(authenticated_account._id))) {
// "system admin" can use any role
role_name = role_name || 'admin';
} else {
throw new RpcError('UNAUTHORIZED', 'account role not allowed');
}
}

const token = make_auth_token({
account_id: target_account._id,
system_id: system && system._id,
role: role_name,
extra: req.rpc_params.extra,
expiry: req.rpc_params.expiry,
});

const info = _get_auth_info(
target_account,
system,
'noobaa',
role_name,
req.rpc_params.extra,
);

return { token, info };
});
throw new Error('TODO @tangledbytes');
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Don’t throw generic Error from a public RPC; return RpcError and deprecate clearly.

Throwing a plain Error will surface as 500 and breaks clients still calling this method. Emit a stable RpcError with guidance, or feature-gate while removing client schema.

Proposed minimal fix:

 function create_auth(req) {
-    throw new Error('TODO @tangledbytes');
+    throw new RpcError('UNAUTHORIZED', 'Password-based auth is disabled. Use make_auth_token or create_k8s_auth.');
 }

Run to confirm no remaining server/client callsites:


🏁 Script executed:

#!/bin/bash
rg -nP -C2 '\bcreate_auth\b|\bcreate_auth_token\b' src | sed -n '1,200p'

Length of output: 6739


🏁 Script executed:

sed -n '1,200p' src/server/common_services/auth_server.js

Length of output: 6676


🏁 Script executed:

rg -nP -C3 'create_auth' src/api/auth_api.js

Length of output: 300


🏁 Script executed:

sed -n '1,80p' src/test/system_tests/test_md_aggregator.js

Length of output: 2614


Replace generic Error in create_auth with RpcError
In src/server/common_services/auth_server.js change

throw new Error('TODO @tangledbytes');

to

throw new RpcError('UNAUTHORIZED', 'Password-based auth is disabled. Use make_auth_token or create_k8s_auth.');

Also mark password-based auth as deprecated in the RPC docs (src/api/auth_api.js:17) and update the integration test (src/test/integration_tests/internal/test_system_servers.js) and deploy script (deploy/NVA_build/noobaa_deploy_k8s.sh:341) to expect an UNAUTHORIZED RpcError rather than HTTP 500.

🤖 Prompt for AI Agents
In src/server/common_services/auth_server.js around lines 36-38 replace the
generic throw new Error('TODO @tangledbytes'); with throwing an RpcError: throw
new RpcError('UNAUTHORIZED', 'Password-based auth is disabled. Use
make_auth_token or create_k8s_auth.');; also update src/api/auth_api.js (around
line 17) to mark password-based auth as deprecated in the RPC docs, modify
src/test/integration_tests/internal/test_system_servers.js to expect an
UNAUTHORIZED RpcError instead of an HTTP 500 in the relevant assertions, and
change deploy/NVA_build/noobaa_deploy_k8s.sh at line ~341 to expect/handle an
UNAUTHORIZED RpcError response rather than a 500.

Comment on lines 401 to 391
if (req.auth) {
if (req.auth.account_id) req.account = system_store.data.get_by_id(req.auth.account_id);
else if (req.auth.email) req.account = system_store.data.accounts_by_email[req.auth.email];

if (req.auth.system_id) req.system = system_store.data.get_by_id(req.auth.system_id);
else if (req.auth.system_name) req.system = system_store.data.systems_by_name[req.auth.system_name];

req.role = req.auth.role;
}
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Token uses email/system_name; resolve entities robustly and keep backward-compat.

Directly indexing maps risks key-shape drift and case issues. Also, many callers still pass system (not system_name). Support both and normalize email.

Apply:

     req.load_auth = function() {
         if (req.auth) {
             if (req.auth.account_id) req.account = system_store.data.get_by_id(req.auth.account_id);
-            else if (req.auth.email) req.account = system_store.data.accounts_by_email[req.auth.email];
+            else if (req.auth.email) {
+                const email = String(req.auth.email).toLowerCase();
+                req.account = system_store.get_account_by_email(new SensitiveString(email));
+            }
 
             if (req.auth.system_id) req.system = system_store.data.get_by_id(req.auth.system_id);
-            else if (req.auth.system_name) req.system = system_store.data.systems_by_name[req.auth.system_name];
+            else if (req.auth.system_name || req.auth.system) {
+                const name = String(req.auth.system_name || req.auth.system);
+                req.system = system_store.data.systems_by_name[name];
+            }
 
             req.role = req.auth.role;
         }
     };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (req.auth) {
if (req.auth.account_id) req.account = system_store.data.get_by_id(req.auth.account_id);
else if (req.auth.email) req.account = system_store.data.accounts_by_email[req.auth.email];
if (req.auth.system_id) req.system = system_store.data.get_by_id(req.auth.system_id);
else if (req.auth.system_name) req.system = system_store.data.systems_by_name[req.auth.system_name];
req.role = req.auth.role;
}
};
req.load_auth = function() {
if (req.auth) {
if (req.auth.account_id) {
req.account = system_store.data.get_by_id(req.auth.account_id);
} else if (req.auth.email) {
const email = String(req.auth.email).toLowerCase();
req.account = system_store.get_account_by_email(new SensitiveString(email));
}
if (req.auth.system_id) {
req.system = system_store.data.get_by_id(req.auth.system_id);
} else if (req.auth.system_name || req.auth.system) {
const name = String(req.auth.system_name || req.auth.system);
req.system = system_store.data.systems_by_name[name];
}
req.role = req.auth.role;
}
};
🤖 Prompt for AI Agents
In src/server/common_services/auth_server.js around lines 401 to 410, the
token-handling code indexes maps directly and assumes exact key shapes
(email/system_name) and omits support for legacy auth.system—update it to
robustly resolve account and system: normalize the email (trim and toLowerCase)
before lookup and use safe getters/fallbacks (try system_store.data.get_by_id
for numeric ids, then lookup by normalized email via accounts_by_email, and for
systems support both req.auth.system (id or object) and req.auth.system_name
normalized; fall back to existing req.system/req.account if already present),
and then set req.role as before. Ensure lookups handle missing keys without
throwing.

Comment on lines +49 to 50
client.options.auth_token = make_auth_token(auth_params);
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Client-side admin token: verify signing secret and repo-wide migration.

  • Confirm make_auth_token signs with a secret not embedded in the repo and sourced securely (env/secret store).
  • Ensure token TTL won’t expire mid-test; refresh if TTL < test duration.
  • Verify no remaining create_auth_token calls.

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Leftover server-minted auth calls:"
rg -nP '\bcreate_auth_token\b|client\.create_auth\b' -g '!**/node_modules/**' -S

echo -e "\nAuth token implementation & secret source:"
rg -nP -nC3 '(make_auth_token|jwt|jsonwebtoken|sign|secret|NB_AUTH|JWT|TOKEN)' src/server/common_services/auth_server.js -S || true

echo -e "\nIs make_auth_token exported?"
rg -nP -nC2 'exports\.(make_auth_token)\s*=|module\.exports\s*=\s*{[^}]*\bmake_auth_token\b' src/server/common_services/auth_server.js -S || true

Length of output: 2339


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Definition of make_auth_token and surrounding implementation:"
rg -nP -C3 'function\s+make_auth_token|const\s+make_auth_token' src/server/common_services/auth_server.js || true

echo -e "\nSecret usage (env vars or secret store):"
rg -nP 'process\.env\.(JWT_SECRET|AUTH_SECRET|NB_AUTH_SECRET|NB_AUTH)|secret' src/server/common_services/auth_server.js || true

echo -e "\nToken expiry configuration (expiresIn, ttl, duration):"
rg -nP -C2 'expiresIn|ttl|expiration|duration' src/server/common_services/auth_server.js || true

echo -e "\nExport of make_auth_token:"
rg -nP 'exports\.(make_auth_token)|module\.exports' src/server/common_services/auth_server.js || true

Length of output: 1980


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Full make_auth_token function:"
sed -n '580,720p' src/server/common_services/auth_server.js || true

Length of output: 2419


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate jwt_utils file
jwt_file=$(fd jwt_utils.js -I | head -1)
echo "Found jwt_utils file: $jwt_file"

echo -e "\nmake_internal_auth_token implementation and secret source:"
# Print the function block
sed -n '1,200p' "$jwt_file" | sed -n '/make_internal_auth_token/,/^}/p'

Length of output: 820


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Top of jwt_utils.js (imports & config):"
sed -n '1,50p' src/util/jwt_utils.js || true

echo -e "\nSearch for jsonwebtoken require:"
rg -nP "require\(['\"]jsonwebtoken['\"]\)" src/util/jwt_utils.js -n -C2 || true

echo -e "\nSearch for config usage:"
rg -nP "const\s+config\s*=" src/util/jwt_utils.js -n -C2 || true

Length of output: 2309


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the main config file
config_file=$(fd -I '^config\\.js$' | head -n1)
echo "Config file: $config_file"

echo -e "\nFirst 200 lines of config file:"
sed -n '1,200p' "$config_file" || true

echo -e "\nReferences to JWT_SECRET and NOOBAA_AUTH_TOKEN in config:"
grep -nP 'JWT_SECRET|NOOBAA_AUTH_TOKEN' "$config_file" || true

Length of output: 474


Require secure JWT secret, confirm TTL, and remove legacy auth calls

  • get_jwt_secret() currently falls back to hardcoded 'abcdefgh' when config.JWT_SECRET isn’t set—remove the dummy fallback and enforce a secure secret via JWT_SECRET (or NOOBAA_AUTH_TOKEN).
  • make_auth_token skips exp unless options.expiry is provided—tests default to no expiry, so add an explicit TTL if you need finite token lifetime.
  • Migration is incomplete: search for and replace all remaining create_auth_token calls (e.g. in src/agent/agent_cli.js, src/tools/rpc_shell.js, pipeline scripts, etc.) with make_auth_token.
🤖 Prompt for AI Agents
In src/test/system_tests/test_bucket_placement.js around lines 49-50, remove the
insecure fallback for get_jwt_secret() so it no longer defaults to 'abcdefgh'
and instead requires a secure secret provided via JWT_SECRET or
NOOBAA_AUTH_TOKEN (throw or fail fast if neither is set); update calls to
make_auth_token so they always include an explicit expiry (set TTL from test
config or a reasonable test-only TTL) rather than leaving exp undefined; and
complete the migration by searching the repo for any remaining create_auth_token
usages (e.g., src/agent/agent_cli.js, src/tools/rpc_shell.js, pipeline scripts)
and replace them with make_auth_token calls. Ensure tests read TTL from a single
config/test constant and that missing JWT secret causes a clear error so CI
cannot run with the dummy secret.

Comment on lines +69 to 75
const auth_params = {
email: argv.email,
password: argv.password,
role: 'admin',
system: argv.system,
});
};
client.options.auth_token = make_auth_token(auth_params);
try {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Load root keys before minting the token (otherwise signing can fail).

make_auth_token typically relies on master keys. Unlike md_blow.js, this file doesn’t load them before minting.

Apply:

@@
-        await system_store.load();
+        const mkm = system_store.master_key_manager;
+        await mkm.load_root_keys_from_mount();
+        await system_store.load();
@@
-        client.options.auth_token = make_auth_token(auth_params);
+        client.options.auth_token = make_auth_token(auth_params);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const auth_params = {
email: argv.email,
password: argv.password,
role: 'admin',
system: argv.system,
});
};
client.options.auth_token = make_auth_token(auth_params);
try {
// ensure root keys are loaded before minting the auth token
const mkm = system_store.master_key_manager;
await mkm.load_root_keys_from_mount();
await system_store.load();
const auth_params = {
email: argv.email,
role: 'admin',
system: argv.system,
};
client.options.auth_token = make_auth_token(auth_params);
try {
🤖 Prompt for AI Agents
In src/tools/md_blow_lifecycle.js around lines 69-75, the code mints an auth
token before loading the root/master keys which can cause signing to fail;
update the flow to load the same root/master keys helper used in md_blow.js
(call the function that initializes/loads master/root keys) before calling
make_auth_token, then proceed to set client.options.auth_token; keep existing
try/catch behavior and ensure the key-load call completes (await if it is async)
before token creation.

💡 Verification agent

🧩 Analysis chain

Stop hard-coding the default password ("DeMo1").

Password is no longer used for auth flow; leaving a default secret in code is a liability and confusing.

Choose one:

  • Remove password altogether (preferred) if create_system no longer requires it.
  • Or at least avoid a fixed default:
@@
-argv.password = argv.password || 'DeMo1';
+// Deprecated: avoid fixed default passwords; use a random placeholder only if required by legacy API.
+argv.password = argv.password || Math.random().toString(36).slice(2, 10);

🏁 Script executed:

#!/bin/bash
# Search for hard-coded default password and CLI password handling in md_blow_lifecycle.js
rg -n 'DeMo1' src/tools/md_blow_lifecycle.js
rg -n 'argv.password' src/tools/md_blow_lifecycle.js
rg -n 'password' -C3 src/tools/md_blow_lifecycle.js

Length of output: 957


🏁 Script executed:

#!/bin/bash
sed -n '1,200p' src/tools/md_blow_lifecycle.js

Length of output: 8425


🏁 Script executed:

#!/bin/bash
# Search for create_system implementation in server code to verify password requirement
rg -nP 'create_system\\s*\\(' -C5 src/server

Length of output: 119


🏁 Script executed:

#!/bin/bash
# Search for create_system handler in server code to verify if password is required
rg -n "create_system" -C5 src/server

Length of output: 7910


Require explicit password and remove hard-coded default
– In src/tools/md_blow_lifecycle.js remove the fallback on line 22 (argv.password = argv.password || 'DeMo1';) and instead error if argv.password is unset, e.g.:

if (!argv.password) {
  console.error('Error: --password is required');
  process.exit(1);
}
🤖 Prompt for AI Agents
In src/tools/md_blow_lifecycle.js around lines 69 to 75, remove the insecure
fallback that assigns a hard-coded default password elsewhere (line ~22) and
instead enforce an explicit password: add a pre-check at startup that verifies
argv.password is set and if not writes a clear error to stderr and exits with a
non-zero status; ensure no default value is assigned to argv.password anywhere
in the file so the process fails fast when the password flag is missing.

Comment on lines +72 to 75
const auth_params = {
email: 'demo@noobaa.com',
password: 'DeMo1',
role: 'admin',
system: 'demo',
});
};
client.options.auth_token = make_auth_token(auth_params);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

init_api became sync but callers still use .then()

init_api() no longer returns a Promise; all three call sites chain .then(...). Make init_api async (or return Promise.resolve()).

-function init_api() {
+async function init_api() {
     const auth_params = {
         email: 'demo@noobaa.com',
         role: 'admin',
         system: 'demo',
     };
     client.options.auth_token = make_auth_token(auth_params);
 }

Also applies to: 21-35, 36-49, 50-68

🤖 Prompt for AI Agents
In src/tools/nbcat.js around lines 72-78 (and likewise for ranges 21-35, 36-49,
50-68), init_api was converted to a synchronous function but callers still use
init_api().then(...); update init_api to return a Promise by either marking the
function async or returning Promise.resolve() (and ensure any early returns
return a Promise as well) so existing .then() chains continue to work; keep the
function behavior identical but guarantee a Promise return type.

const util = require('util');
const api = require('../api');
const P = require('../util/promise');
const { make_auth_token } = require('../server/common_services/auth_server');
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Critical: Client-side minting of admin tokens in a user tool is unsafe

Generating an admin token locally in rpc_shell means anyone running this tool can forge admin tokens if the signing secret is reachable. This bypasses any authentication policy and is a high-risk change if this tool is available outside trusted server pods/containers. Gate this behind explicit user-provided tokens and treat local minting as a last-resort dev-only path.

  • Prefer argv.token or NB_ADMIN_TOKEN first.
  • Make role configurable; default should not be hardcoded to admin.
  • Clearly document rpc_shell as dev-only if local minting remains.

Proposed change (within init):

-            const auth_params = {
-                email: argv.email,
-                role: 'admin',
-                system: argv.system,
-            };
-            self.client.options.auth_token = make_auth_token(auth_params);
+            const role = argv.role || 'admin';
+            const auth_params = {
+                email: argv.email,
+                role,
+                system: argv.system,
+            };
+            const token = argv.token || process.env.NB_ADMIN_TOKEN || make_auth_token(auth_params);
+            self.client.options.auth_token = token;

Additionally, argv.password is now unused; consider removing it from defaults and help text.


🏁 Script executed:

#!/bin/bash
# Verify no lingering RPC auth creation calls and audit local token minting usage.

set -euo pipefail

echo "1) Any remaining create_auth_token calls?"
rg -nP '\bcreate_auth_token\s*\('

echo
echo "2) Where is make_auth_token used outside server code?"
rg -nP --glob '!src/server/**' 'make_auth_token\s*\(' -n

echo
echo "3) Does rpc_shell still reference password?"
rg -nP 'argv\.password|password' src/tools/rpc_shell.js -n -C2

Length of output: 5600


Critical: Local admin‐token minting in rpc_shell.js remains unguarded

  • src/tools/rpc_shell.js still sets
    argv.password = argv.password || 'DeMo1';           // line 19
    self.client.options.auth_token = make_auth_token(); // line 56
    Remove the hardcoded password, make role come from argv.role (default non-admin), and gate token creation behind argv.token or NB_ADMIN_TOKEN, falling back to make_auth_token only in a dev-only path.
  • Reapply the proposed diff in init to prefer an explicit token and configurable role:
    -            const auth_params = {
    -                email: argv.email,
    -                role: 'admin',
    -                system: argv.system,
    -            };
    -            self.client.options.auth_token = make_auth_token(auth_params);
    +            const role = argv.role || 'user';
    +            const auth_params = { email: argv.email, role, system: argv.system };
    +            const token = argv.token || process.env.NB_ADMIN_TOKEN || make_auth_token(auth_params);
    +            self.client.options.auth_token = token;
  • Document rpc_shell.js as strictly dev-only if local minting remains.
  • Audit other CLI tools (e.g. nbcat.js, md_blow*.js, cmd/api.js) that call make_auth_token outside server code and apply the same gating pattern.
🤖 Prompt for AI Agents
In src/tools/rpc_shell.js around lines 12–56 (see hardcoded password at ~line 19
and token mint at ~line 56), remove the hardcoded argv.password default, change
role sourcing to argv.role with a non-admin default, and prevent unconditional
local admin token minting by requiring an explicit argv.token or environment
NB_ADMIN_TOKEN; only call make_auth_token as a last-resort fallback inside a
dev-only guarded branch (e.g., NODE_ENV==='development' or an explicit --dev
flag) and log/document that rpc_shell.js local minting is strictly dev-only;
reapply the init diff to prefer an explicit token and configurable role, and
audit other CLI files (nbcat.js, md_blow*.js, cmd/api.js) to apply the same
gating pattern for make_auth_token usage.

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from 50064a2 to a537311 Compare September 5, 2025 16:44
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
src/test/pipeline/system_config.js (2)

221-223: Don’t disconnect RPC before running tests

rpc.disconnect_all() immediately after setting the auth token will break subsequent client calls.

         await set_rpc_and_create_auth_token();
-        rpc.disconnect_all();
 
         server_ops.init_reporter({

1-252: Remove password from auth_params in tests
In src/test/external_tests/external_tests_utils.js line 38, drop the password field from the auth_params object so tests no longer rely on server-side credentials.

src/tools/md_blow_lifecycle.js (2)

103-107: Await update_bucket

Missing await can race subsequent operations.

-    client.bucket.update_bucket({
+    await client.bucket.update_bucket({
         name: argv.bucket,
         versioning: 'ENABLED'
     });

120-123: Await update_bucket

Same issue here.

-    client.bucket.update_bucket({
+    await client.bucket.update_bucket({
         name: argv.bucket,
         versioning: 'ENABLED'
     });
src/server/common_services/auth_server.js (1)

149-156: Fix JWT expiry units
In src/server/common_services/auth_server.js (lines 149–156 & 628–631), you calculate expiry as Math.floor(expires_in * 1000) (ms) but pass it directly to jwt_options.expiresIn, which expects seconds—making tokens valid ~1000× longer. Either change to expiry: Math.floor(expires_in) or divide by 1000 in make_auth_token (jwt_options.expiresIn = Math.floor(options.expiry/1000)).

♻️ Duplicate comments (10)
src/test/pipeline/system_config.js (2)

37-37: Remove password from help text

CLI no longer accepts/uses password; drop this line from usage().

-    --password              -   noobaa management Credentials (password)

205-214: Rename to reflect behavior (no server create); update call sites

Function now sets, not creates, a token. Rename for clarity and consistency.

-async function set_rpc_and_create_auth_token() {
+async function set_rpc_and_set_auth_token() {
@@
-    client.options.auth_token = make_auth_token(auth_params);
+    client.options.auth_token = make_auth_token(auth_params);
 }
@@
-        await set_rpc_and_create_auth_token();
+        await set_rpc_and_set_auth_token();
src/server/system_services/account_server.js (1)

1276-1288: Return the promise from make_changes to avoid race

Without returning/awaiting, callers may proceed before the support account persists.

-            system_store.make_changes({
+            return system_store.make_changes({
                 insert: {
                     accounts: [support_account]
                 }
             }).then(() => console.log('SUPPORT ACCOUNT CREATED'));
src/tools/md_blow_lifecycle.js (2)

21-24: Remove hard-coded default password; require explicit if still needed

Defaulting to 'DeMo1' is insecure and misleading post-password-removal.

 argv.email = argv.email || 'admin@noobaa.io';
-argv.password = argv.password || 'DeMo1';
 argv.system = argv.system || 'noobaa';
+
+if (!argv.password) {
+    console.error('Error: --password is required');
+    process.exit(1);
+}

59-65: Load root/master keys before minting token

Preload keys to avoid signing failures when calling make_auth_token.

-        await system_store.load();
+        const mkm = system_store.master_key_manager;
+        await mkm.load_root_keys_from_mount();
+        await system_store.load();
src/tools/nbcat.js (1)

71-78: init_api must return a Promise

Call sites use .then(...); make init_api async (or return a resolved Promise).

-function init_api() {
+async function init_api() {
     const auth_params = {
         email: 'demo@noobaa.com',
         role: 'admin',
         system: 'demo',
     };
     client.options.auth_token = make_auth_token(auth_params);
 }
src/test/system_tests/test_cloud_pools.js (1)

145-152: Broken promise chain: authenticate() is sync but run_test() still calls .then()

authenticate() no longer returns a Promise; run_test()’s authenticate().then(...) will throw. Make authenticate async (preferred) or return Promise.resolve().

Apply one of:

-function authenticate() {
+async function authenticate() {
   const auth_params = {
     email: 'demo@noobaa.com',
-    role: 'admin',
-    system: 'demo',
+    role: 'admin',
+    system: 'demo',
   };
   client.options.auth_token = make_auth_token(auth_params);
 }

Alternative:

 function authenticate() {
   const auth_params = {
     email: 'demo@noobaa.com',
     role: 'admin',
     system: 'demo',
   };
   client.options.auth_token = make_auth_token(auth_params);
+  return Promise.resolve();
 }

Also applies to: 214-218

src/agent/block_store_speed.js (1)

39-44: Do not auto-mint admin tokens in the agent; require explicit token (security).

If the signing secret is present, any agent run can mint admin tokens. Require a provided token (flag/env), or gate minting behind an explicit DEV flag.

Minimal secure change (require explicit token, no minting):

-const { make_auth_token } = require('../server/common_services/auth_server');
+// Intentionally avoid importing make_auth_token here to prevent local minting.

@@
-    const token = argv.token || make_auth_token({
-        system: argv.system,
-        role: 'admin',
-        email: argv.email,
-    });
+    const token = argv.token || process.env.NOOBAA_AUTH_TOKEN;
+    if (!token) {
+        console.error('Missing auth token. Pass --token or set NOOBAA_AUTH_TOKEN.');
+        process.exit(2);
+    }

If you insist on supporting local minting for dev: guard it explicitly:

-    const token = argv.token || make_auth_token({
-        system: argv.system,
-        role: 'admin',
-        email: argv.email,
-    });
+    const isDev = argv.dev === true || process.env.DEV_MODE === 'true';
+    const token = argv.token || process.env.NOOBAA_AUTH_TOKEN ||
+        (isDev ? require('../server/common_services/auth_server').make_auth_token({
+            system: argv.system, role: 'admin', email: argv.email,
+        }) : null);
+    if (!token) {
+        console.error('Missing auth token. Pass --token, set NOOBAA_AUTH_TOKEN, or use --dev.');
+        process.exit(2);
+    }
src/server/common_services/auth_server.js (2)

37-37: Return RpcError instead of generic Error from create_auth.

Throwing Error produces 500; use a stable UNAUTHORIZED RpcError with guidance.

-function create_auth(req) {
-    throw new Error('TODO @tangledbytes');
-}
+function create_auth(req) {
+    throw new RpcError('UNAUTHORIZED', 'Password-based auth is disabled. Use make_auth_token or create_k8s_auth.');
+}

401-410: Harden account/system resolution; support legacy fields and normalize email.

Direct map indexing is brittle and case-sensitive. Use getters and normalize email; accept system_name or legacy system.

     req.load_auth = function() {
         if (req.auth) {
-            if (req.auth.account_id) req.account = system_store.data.get_by_id(req.auth.account_id);
-            else if (req.auth.email) req.account = system_store.data.accounts_by_email[req.auth.email];
+            if (req.auth.account_id) {
+                req.account = system_store.data.get_by_id(req.auth.account_id);
+            } else if (req.auth.email) {
+                const email = new SensitiveString(String(req.auth.email).trim().toLowerCase());
+                req.account = system_store.get_account_by_email(email);
+            }
 
-            if (req.auth.system_id) req.system = system_store.data.get_by_id(req.auth.system_id);
-            else if (req.auth.system_name) req.system = system_store.data.systems_by_name[req.auth.system_name];
+            if (req.auth.system_id) {
+                req.system = system_store.data.get_by_id(req.auth.system_id);
+            } else if (req.auth.system_name || req.auth.system) {
+                const name = String(req.auth.system_name || req.auth.system);
+                req.system = system_store.data.systems_by_name[name];
+            }
 
             req.role = req.auth.role;
         }
     };
🧹 Nitpick comments (6)
src/test/pipeline/system_config.js (1)

138-138: Fix log to print actual max

Hard-coded 60500 in the message; use the passed max.

-        console.log(`The tcp port range is: ${min} to ${60500} - as should`);
+        console.log(`The tcp port range is: ${min} to ${max} - as should`);
src/server/system_services/account_server.js (2)

203-211: Remove password/has_login from external user creation

Passwords are deprecated; this still sets them and can confuse callers.

-    Object.assign(req.rpc_params, {
-        is_external: true,
-        password: new SensitiveString(chance.string({ length: 16 })),
-        must_change_password: false,
-        has_login: true,
-        s3_access: true,
-        allow_bucket_creation: true,
-        default_resource: default_resource.name
-    });
+    Object.assign(req.rpc_params, {
+        is_external: true,
+        s3_access: true,
+        allow_bucket_creation: true,
+        default_resource: default_resource.name
+    });

1356-1377: Drop password validation branch

has_login/password validation is dead code after removing password auth; consider deleting to prevent inconsistent states.

-    if (req.rpc_params.has_login) {
-        if (!req.rpc_params.password) {
-            throw new RpcError('BAD_REQUEST', 'Password is missing');
-        }
-
-    } else if (req.rpc_params.password) {
-        throw new RpcError('BAD_REQUEST', 'Password should not be sent');
-    }
+    // Password-based login removed; no password checks.
src/tools/md_blow_lifecycle.js (1)

185-186: Fix debug log: id is undefined

Use multipart_id or obj_id.

-    dbg.log0('complete_multipart', params.id);
+    dbg.log0('complete_multipart', complete_params.multipart_id);
src/test/system_tests/sanity_build_test.js (1)

220-228: Align test accounts with password removal

Avoid setting passwords/has_login in test data unless explicitly required by server validation.

     const ac4 = {
         name: "ac_haslogin",
         email: "ac_haslogin@noobaa.com",
-        has_login: true,
-        password: "c1QiGkl2",
+        has_login: false,
         must_change_password: false,
         s3_access: true,
         default_resource: 'COMP-S3-V2-Resource',
         allow_bucket_creation: true
     };
src/server/common_services/auth_server.js (1)

619-633: Document new token fields in make_auth_token JSDoc and validate inputs.

You added email/system_name to the payload; update JSDoc and consider basic validation.

  *      - role
  *      - extra
  *      - expiry
+ *      - authorized_by
+ *      - email
+ *      - system_name
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 50064a2 and a537311.

📒 Files selected for processing (39)
  • src/agent/block_store_speed.js (2 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (3 hunks)
  • src/server/system_services/account_server.js (3 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (4 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (4)
  • src/sdk/nb.d.ts
  • src/tools/bcrypt_cli.js
  • src/test/integration_tests/api/s3/test_bucket_replication.js
  • src/rpc/rpc_schema.js
🚧 Files skipped from review as they are similar to previous changes (27)
  • src/server/system_services/schemas/account_schema.js
  • src/test/utils/basic_server_ops.js
  • src/cmd/backingstore.js
  • src/test/utils/agent_functions.js
  • src/test/qa/agents_matrix.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/system_tests/test_md_aggregator.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/test/qa/cloud_test.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/test/integration_tests/internal/test_system_servers.js
  • src/test/pipeline/account_test.js
  • src/cmd/api.js
  • src/test/pipeline/namespace_test.js
  • src/test/qa/rebuild_replicas_test.js
  • src/test/system_tests/test_bucket_placement.js
  • src/test/system_tests/test_s3_authentication.js
  • src/test/qa/data_availability_test.js
  • src/tools/rpc_shell.js
  • src/test/pipeline/quota_test.js
  • src/test/utils/server_functions.js
  • src/test/external_tests/external_tests_utils.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
  • src/test/system_tests/test_node_failure.js
  • src/test/qa/reclaim_test.js
  • src/tools/md_blow.js
  • src/test/pipeline/run_dataset.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/system_tests/sanity_build_test.js
  • src/test/pipeline/system_config.js
  • src/test/system_tests/test_cloud_pools.js
🧬 Code graph analysis (6)
src/test/system_tests/sanity_build_test.js (4)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • api (15-15)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (4)
  • require (5-5)
  • require (7-7)
  • api (4-4)
  • auth_params (38-38)
src/test/pipeline/quota_test.js (5)
  • require (6-6)
  • require (10-10)
  • require (11-11)
  • require (12-12)
  • api (4-4)
src/test/pipeline/run_namespace_cache_tests.js (4)
  • require (6-6)
  • require (10-10)
  • api (5-5)
  • auth_params (183-187)
src/test/pipeline/system_config.js (8)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • client (22-24)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/quota_test.js (6)
  • require (6-6)
  • require (10-10)
  • require (11-11)
  • require (12-12)
  • client (73-73)
  • client (162-165)
src/test/pipeline/run_dataset.js (3)
  • require (10-10)
  • require (11-11)
  • client (60-60)
src/test/pipeline/run_namespace_cache_tests.js (3)
  • require (6-6)
  • require (10-10)
  • auth_params (183-187)
src/test/system_tests/test_bucket_access.js (2)
  • client (37-39)
  • auth_params (77-81)
src/test/utils/basic_server_ops.js (3)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
src/test/utils/server_functions.js (3)
  • client (27-27)
  • auth_params (49-53)
  • auth_params (70-74)
src/tools/md_blow_lifecycle.js (2)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (1)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (1)
  • auth_params (38-38)
src/server/system_services/account_server.js (4)
src/server/system_services/stats_aggregator.js (5)
  • support_account (599-599)
  • support_account (1163-1163)
  • support_account (1200-1200)
  • support_account (1233-1233)
  • system_store (16-16)
src/server/system_services/system_server.js (3)
  • support_account (863-863)
  • system_store (32-32)
  • system_store (1188-1188)
src/server/system_services/schemas/account_schema.js (1)
  • SensitiveString (4-4)
src/api/account_api.js (1)
  • SensitiveString (4-4)
src/tools/nbcat.js (3)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/pipeline/run_namespace_cache_tests.js (3)
  • require (6-6)
  • require (10-10)
  • auth_params (183-187)
src/test/utils/agent_functions.js (1)
  • auth_params (13-17)
src/test/system_tests/test_cloud_pools.js (4)
src/test/system_tests/test_bucket_access.js (4)
  • require (18-18)
  • require (21-21)
  • client (37-39)
  • auth_params (77-81)
src/test/system_tests/test_md_aggregator.js (3)
  • require (16-16)
  • client (26-28)
  • auth_params (33-37)
src/test/system_tests/test_s3_authentication.js (5)
  • require (4-4)
  • require (5-5)
  • require (16-16)
  • client (27-29)
  • auth_params (36-40)
src/test/utils/basic_server_ops.js (4)
  • require (10-10)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
⏰ 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 (7)
src/test/pipeline/system_config.js (1)

10-10: OK: Local token mint for tests

Import and usage align with repo-wide switch to make_auth_token.

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

1381-1386: No callers for verify_authorized_account exist in the codebase; original comment is not applicable.

Likely an incorrect or invalid review comment.

src/tools/md_blow_lifecycle.js (1)

69-75: OK: Local token mint

Auth params and token assignment look good once keys are loaded first.

src/test/system_tests/sanity_build_test.js (1)

76-87: LGTM: Switched to local token

make_auth_token usage and assignment look correct.

src/tools/nbcat.js (1)

72-78: OK: Local token mint

Auth params and token assignment look good.

src/test/system_tests/test_cloud_pools.js (1)

15-15: Import of make_auth_token is appropriate for the new auth flow.

No issues here.

src/agent/block_store_speed.js (1)

50-50: Setting the token on the client is correct.

This aligns with the new auth model.

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from a537311 to ca9cdb5 Compare September 5, 2025 17:14
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/server/common_services/auth_server.js (1)

264-264: Redact auth tokens from logs.

Leaking tokens to logs is a high-severity security risk.

-    dbg.log0('ACCESS TOKEN:', token);
+    dbg.log1('ACCESS TOKEN issued'); // avoid logging token material
♻️ Duplicate comments (3)
src/test/external_tests/external_tests_utils.js (1)

36-40: Do not embed plaintext password in JWT payload; make role optional with sane default.

This reintroduces sensitive data into signed tokens and contradicts the bcrypt/password removal goal. Keep the password param for backward compatibility but ignore it; default role to 'admin'.

-async function get_rpc_client_by_email_and_password(email, password) {
+async function get_rpc_client_by_email_and_password(email, _password, role = 'admin') {
     const rpc_client = get_global_rpc_client();
-    const auth_params = { email, password, system: 'noobaa', role: 'admin' };
-    rpc_client.options.auth_token = make_auth_token(auth_params);
+    const auth_params = { email, system: 'noobaa', ...(role ? { role } : {}) };
+    rpc_client.options.auth_token = make_auth_token(auth_params);
     return rpc_client;
 }

Run to find and clean any remaining password fields in token payloads and any lingering create_auth_token calls:

#!/bin/bash
set -euo pipefail
echo "Calls to removed client.create_auth_token:"
rg -nP --glob 'src/**' '\bcreate_auth_token\s*\(' -C2 || true

echo -e "\nAuth tokens that still include password fields:"
rg -nP --glob 'src/**' '(auth_params|{)[^}]*password\s*:' -C2 || true

echo -e "\nHardcoded demo password occurrences:"
rg -n --glob 'src/**' 'DeMo1' || true
src/server/common_services/auth_server.js (2)

36-38: Return RpcError instead of throwing a generic Error (avoid 500s; clearly deprecate).

Throwing Error will surface as HTTP 500 and break legacy clients still calling this RPC. Return a stable RpcError('UNAUTHORIZED', ...) with guidance.

 function create_auth(req) {
-    throw new Error('TODO @tangledbytes');
+    throw new RpcError('UNAUTHORIZED', 'Password-based auth is disabled. Use make_auth_token or create_k8s_auth.');
 }

Run to confirm no remaining server/client call-sites:

#!/bin/bash
rg -nP -C2 '\bcreate_auth\b|\bcreate_auth_token\b' src

401-410: Harden token-to-entity resolution (normalize email; support legacy system name; avoid direct map access).

Directly indexing accounts_by_email/systems_by_name is brittle (case/shape drift) and misses legacy auth.system. Normalize and use store helpers.

     req.load_auth = function() {
         if (req.auth) {
             if (req.auth.account_id) req.account = system_store.data.get_by_id(req.auth.account_id);
-            else if (req.auth.email) req.account = system_store.data.accounts_by_email[req.auth.email];
+            else if (req.auth.email) {
+                const email = String(req.auth.email).trim().toLowerCase();
+                req.account = system_store.get_account_by_email(new SensitiveString(email));
+            }
 
             if (req.auth.system_id) req.system = system_store.data.get_by_id(req.auth.system_id);
-            else if (req.auth.system_name) req.system = system_store.data.systems_by_name[req.auth.system_name];
+            else if (req.auth.system_name || req.auth.system) {
+                const name = String(req.auth.system_name || req.auth.system).trim();
+                req.system = system_store.data.systems_by_name[name];
+            }
 
             req.role = req.auth.role;
         }
     };
🧹 Nitpick comments (5)
src/test/qa/cloud_test.js (1)

160-167: Local token generation OK; make role/system configurable via params (keep safe defaults).

Avoid hardcoding; let callers override without touching call sites.

-async function set_rpc_and_create_auth_token(client_to_auth) {
-    const auth_params = {
-        email: 'demo@noobaa.com',
-        system: 'demo',
-        role: 'admin',
-    };
-    client_to_auth.options.auth_token = make_auth_token(auth_params);
+async function set_rpc_and_create_auth_token(
+    client_to_auth,
+    { email = 'demo@noobaa.com', system = 'demo', role = 'admin' } = {}
+) {
+    client_to_auth.options.auth_token = make_auth_token({ email, system, role });
 }
src/test/qa/data_availability_test.js (1)

195-202: Set token locally: good; accept overrides to reduce coupling to 'demo' and 'admin'.

Keep defaults but allow callers/CI to pass different values.

-async function set_rpc_and_create_auth_token() {
-    const auth_params = {
-        email: 'demo@noobaa.com',
-        system: 'demo',
-        role: 'admin',
-    };
-    client.options.auth_token = make_auth_token(auth_params);
+async function set_rpc_and_create_auth_token(
+    { email = 'demo@noobaa.com', system = 'demo', role = 'admin' } = {}
+) {
+    client.options.auth_token = make_auth_token({ email, system, role });
 }
src/tools/md_blow.js (1)

36-42: Token creation is fine; drop unused password option to avoid confusion.

argv.password is no longer used. Remove its default and any help text mentioning it.

Example change outside the diff hunk:

// Remove this line near the args defaults:
// argv.password = argv.password || 'DeMo1';
src/test/utils/server_functions.js (2)

49-55: OK to use locally signed admin token while polling for readiness.

Small nit: consider lifting auth_params to a helper to avoid duplication and ease future changes.


70-76: Same here: local token use LGTM; minor duplication nit.

Factor a tiny helper for auth param assembly to keep consistency across tests.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a537311 and ca9cdb5.

📒 Files selected for processing (39)
  • src/agent/block_store_speed.js (2 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (3 hunks)
  • src/server/system_services/account_server.js (3 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (4 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (4)
  • src/sdk/nb.d.ts
  • src/rpc/rpc_schema.js
  • src/tools/bcrypt_cli.js
  • src/test/integration_tests/api/s3/test_bucket_replication.js
🚧 Files skipped from review as they are similar to previous changes (29)
  • src/test/system_tests/test_s3_authentication.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/utils/basic_server_ops.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/test/system_tests/sanity_build_test.js
  • src/test/integration_tests/internal/test_system_servers.js
  • src/server/system_services/account_server.js
  • src/agent/block_store_speed.js
  • src/cmd/backingstore.js
  • src/server/system_services/schemas/account_schema.js
  • src/tools/rpc_shell.js
  • src/test/pipeline/quota_test.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/cmd/api.js
  • src/tools/md_blow_lifecycle.js
  • src/test/system_tests/test_md_aggregator.js
  • src/test/utils/agent_functions.js
  • src/test/qa/reclaim_test.js
  • src/test/pipeline/run_dataset.js
  • src/test/qa/agents_matrix.js
  • src/tools/nbcat.js
  • src/test/system_tests/test_node_failure.js
  • src/test/qa/rebuild_replicas_test.js
  • src/test/pipeline/system_config.js
  • src/test/pipeline/account_test.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
  • src/test/pipeline/namespace_test.js
  • src/test/system_tests/test_cloud_pools.js
  • src/test/system_tests/test_bucket_placement.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/utils/server_functions.js
  • src/test/qa/cloud_test.js
  • src/test/qa/data_availability_test.js
  • src/test/external_tests/external_tests_utils.js
🧬 Code graph analysis (5)
src/test/utils/server_functions.js (5)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/account_test.js (3)
  • require (7-7)
  • require (9-9)
  • auth_params (306-311)
src/test/pipeline/namespace_test.js (2)
  • require (8-8)
  • auth_params (281-285)
src/test/qa/cloud_test.js (3)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/account_test.js (3)
  • require (7-7)
  • require (9-9)
  • auth_params (306-311)
src/test/qa/data_availability_test.js (3)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)
  • require (16-16)
  • require (17-17)
src/test/external_tests/external_tests_utils.js (2)
  • require (5-5)
  • require (7-7)
src/server/common_services/auth_server.js (3)
src/server/object_services/object_server.js (10)
  • req (631-631)
  • req (652-652)
  • req (695-695)
  • req (730-730)
  • req (749-749)
  • req (799-799)
  • req (901-903)
  • req (1838-1838)
  • system_store (31-31)
  • _ (7-7)
src/server/system_services/bucket_server.js (6)
  • req (1116-1116)
  • req (1149-1149)
  • req (2013-2013)
  • system_store (28-28)
  • _ (7-7)
  • _ (1740-1747)
src/endpoint/sts/sts_rest.js (1)
  • system_store (10-10)
src/test/external_tests/external_tests_utils.js (2)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/pipeline/account_test.js (3)
  • require (7-7)
  • require (9-9)
  • auth_params (306-311)
⏰ 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
🔇 Additional comments (6)
src/test/qa/cloud_test.js (1)

81-81: Import of make_auth_token looks good.

Consistent with the PR objective to drop server-side create_auth_token.

src/test/qa/data_availability_test.js (1)

11-11: Import added is aligned with token-only auth.

No issues.

src/test/external_tests/external_tests_utils.js (1)

5-5: OK to import make_auth_token.

Matches the repo-wide migration.

src/tools/md_blow.js (1)

13-13: Good: switched to make_auth_token.

Aligns this tool with token auth.

src/test/utils/server_functions.js (1)

7-7: Import of make_auth_token looks correct.

Consistent with other suites.

src/server/common_services/auth_server.js (1)

619-633: Normalize email/system_name and confirm expiry units
Remove raw email/system_name from the initial _.pick, then assign normalized values (String(options.email).trim().toLowerCase(), String(options.system_name).trim()). Confirm that jsonwebtoken.sign’s expiresIn is interpreted in seconds (or as a time-span string) and adjust any millisecond inputs accordingly.

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from ca9cdb5 to dcf3156 Compare September 5, 2025 17:38
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/test/qa/agents_matrix.js (1)

108-116: Fix error log and payload key in agents_matrix.js

-        console.error(`create_auth_token has failed`, e);
+        console.error('make_auth_token failed', e);
  • In the make_auth_token call, replace system: 'demo' with system_name: 'demo' (the function picks system_name, not system).
  • make_auth_token invokes jwt.sign synchronously, and when passed expiry uses it as expiresIn to embed exp; iat is added by default.
♻️ Duplicate comments (2)
src/tools/nbcat.js (1)

71-78: Fix: init_api must return a Promise; callers use .then()

init_api() is sync and returns undefined; every call site chains .then(), causing a runtime TypeError.

-function init_api() {
+async function init_api() {
     const auth_params = {
         email: 'demo@noobaa.com',
         role: 'admin',
         system: 'demo',
     };
     client.options.auth_token = make_auth_token(auth_params);
 }
src/server/system_services/account_server.js (1)

1276-1288: Support account creation: minimal fields OK; verify no code needs master_key_id/roles. Good on returning the promise.

Nice job returning the promise from make_changes; that fixes the race noted earlier. Confirm no code path accesses support account’s master_key_id or expects roles; otherwise, create and attach a master key at creation.

Optional enhancement (only if any path needs encryption under support account):

             console.log('CREATING SUPPORT ACCOUNT...');
             const support_account = {
                 _id: system_store.new_system_store_id(),
                 name: new SensitiveString('Support'),
                 email: new SensitiveString('support@noobaa.com'),
                 has_login: false,
                 is_support: true,
             };

-            return system_store.make_changes({
+            // Optional: provision a master key for the support account to avoid NPEs in crypto flows.
+            // const support_mkey = system_store.master_key_manager.new_master_key({
+            //     description: `master key of ${support_account._id} account`,
+            //     cipher_type: system_store.data.systems[0].master_key_id.cipher_type,
+            //     master_key_id: system_store.data.systems[0].master_key_id._id
+            // });
+            // support_account.master_key_id = support_mkey._id;
+
+            return system_store.make_changes({
                 insert: {
-                    accounts: [support_account]
+                    accounts: [support_account],
+                    // master_keys: [support_mkey] // if the optional block above is enabled
                 }
             }).then(() => console.log('SUPPORT ACCOUNT CREATED'));

Verify assumptions:

#!/bin/bash
set -euo pipefail

echo "=== Accesses that may require an account.master_key_id ==="
rg -nP -C2 '(req\.account|account)\.master_key_id' src || true

echo
echo "=== is_support usage hot spots ==="
rg -nP -C2 '\bis_support\b' src || true
🧹 Nitpick comments (4)
src/tools/nbcat.js (3)

21-35: Harden control flow: add .catch to always disconnect RPC on errors

Without a catch, errors will leak connections and crash ungracefully.

@@
-        });
+        })
+        .catch(function(err) {
+            dbg.error('nbcat: list_buckets failed', err);
+            rpc.disconnect_all();
+            process.exitCode = 1;
+        });
@@
-    });
+    })
+    .catch(function(err) {
+        dbg.error('nbcat: read_object_stream failed', err);
+        rpc.disconnect_all();
+        process.exitCode = 1;
+    });
@@
-        });
+        })
+        .catch(function(err) {
+            dbg.error('nbcat: list_objects_admin failed', err);
+            rpc.disconnect_all();
+            process.exitCode = 1;
+        });

Also applies to: 36-49, 50-68


8-8: Reduce coupling: avoid importing server internals in a tool

Importing make_auth_token from server/common_services ties this tool to server code and transitive deps. Consider extracting token creation into a lightweight shared util (e.g., src/util/auth_token.js) used by both server and tools.


72-77: Token hygiene: ensure short-lived tokens

If make_auth_token supports exp/iat/ttl, pass them so nbcat uses short-lived tokens; otherwise tokens may be overly permissive.

src/test/qa/agents_matrix.js (1)

48-48: Decouple tests from server internals (importing auth_server directly).

Importing make_auth_token from server/common_services binds this QA test to server internals and secrets. Prefer a thin test helper (e.g., src/test/utils/auth.js) that wraps token creation, or expose a public API for tests, to avoid tight coupling and accidental production secret bleed-through.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ca9cdb5 and dcf3156.

📒 Files selected for processing (39)
  • src/agent/block_store_speed.js (2 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (3 hunks)
  • src/server/system_services/account_server.js (3 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (4 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (4)
  • src/rpc/rpc_schema.js
  • src/sdk/nb.d.ts
  • src/tools/bcrypt_cli.js
  • src/test/integration_tests/api/s3/test_bucket_replication.js
✅ Files skipped from review due to trivial changes (1)
  • src/server/system_services/schemas/account_schema.js
🚧 Files skipped from review as they are similar to previous changes (31)
  • src/test/qa/cloud_test.js
  • src/test/qa/rebuild_replicas_test.js
  • src/test/integration_tests/internal/test_system_servers.js
  • src/test/pipeline/namespace_test.js
  • src/test/system_tests/test_bucket_placement.js
  • src/tools/md_blow_lifecycle.js
  • src/tools/rpc_shell.js
  • src/test/external_tests/external_tests_utils.js
  • src/test/system_tests/test_md_aggregator.js
  • src/test/pipeline/run_dataset.js
  • src/test/pipeline/system_config.js
  • src/test/utils/agent_functions.js
  • src/cmd/backingstore.js
  • src/tools/md_blow.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/test/system_tests/sanity_build_test.js
  • src/test/system_tests/test_s3_authentication.js
  • src/test/pipeline/quota_test.js
  • src/test/pipeline/account_test.js
  • src/test/qa/reclaim_test.js
  • src/test/qa/data_availability_test.js
  • src/agent/block_store_speed.js
  • src/test/utils/server_functions.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/utils/basic_server_ops.js
  • src/test/system_tests/test_node_failure.js
  • src/test/system_tests/test_cloud_pools.js
  • src/server/common_services/auth_server.js
  • src/cmd/api.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/qa/agents_matrix.js
🧬 Code graph analysis (3)
src/test/qa/agents_matrix.js (3)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/server/system_services/account_server.js (2)
src/server/system_services/stats_aggregator.js (5)
  • support_account (599-599)
  • support_account (1163-1163)
  • support_account (1200-1200)
  • support_account (1233-1233)
  • system_store (16-16)
src/server/system_services/schemas/account_schema.js (1)
  • SensitiveString (4-4)
src/tools/nbcat.js (3)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/pipeline/account_test.js (1)
  • auth_params (306-311)
src/test/pipeline/namespace_test.js (1)
  • auth_params (281-285)
⏰ 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 (1)
src/server/system_services/account_server.js (1)

1386-1386: verify_authorized_account now only allows operator
Only the admin-protected API route (verify_authorized_account in src/api/account_api.js) invokes this function, but it always returns false for admin and user roles. Confirm no clients depend on it for admin/user password verification; if it’s unused, remove it, or rename it to clarify that it only applies to operator flows.

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from dcf3156 to 282b8ab Compare September 5, 2025 18:08
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/server/common_services/auth_server.js (1)

619-633: Fix expiry unit in create_k8s_auth

  • In src/server/common_services/auth_server.js:153, expiry: Math.floor(expires_in * 1000) passes milliseconds into jwt.sign, which interprets expiresIn as seconds. Change to:
    expiry: Math.floor(expires_in),
  • Alternatively, add a defensive conversion in make_auth_token to detect large values (e.g. ≥1e6) and divide by 1000 before assigning to jwt_options.expiresIn.

This mismatch causes tokens to live 1000× longer than intended.

♻️ Duplicate comments (3)
src/server/common_services/auth_server.js (2)

36-38: Return RpcError instead of throwing a generic Error from a public RPC

Throwing Error yields 500s and breaks older clients. Return a stable RpcError with guidance.

 function create_auth(req) {
-    throw new Error('TODO @tangledbytes');
+    throw new RpcError('UNAUTHORIZED', 'Password-based auth is disabled. Use make_auth_token or create_k8s_auth.');
 }

401-410: Harden account/system resolution: normalize email and support legacy system key

Directly indexing into maps with unnormalized keys is brittle; also support auth.system_name/auth.system for backward-compat.

     req.load_auth = function() {
         if (req.auth) {
             if (req.auth.account_id) req.account = system_store.data.get_by_id(req.auth.account_id);
-            else if (req.auth.email) req.account = system_store.data.accounts_by_email[req.auth.email];
+            else if (req.auth.email) {
+                const email = String(req.auth.email).trim().toLowerCase();
+                req.account = system_store.get_account_by_email(new SensitiveString(email));
+            }
 
             if (req.auth.system_id) req.system = system_store.data.get_by_id(req.auth.system_id);
-            else if (req.auth.system) req.system = system_store.data.systems_by_name[req.auth.system];
+            else if (req.auth.system_name || req.auth.system) {
+                const name = String(req.auth.system_name || req.auth.system);
+                req.system = system_store.data.systems_by_name[name];
+            }
 
             req.role = req.auth.role;
         }
     };
src/tools/rpc_shell.js (1)

51-57: Do not unconditionally mint local admin tokens in a user tool

Gate on argv.token/NB_ADMIN_TOKEN; default role non-admin; keep local minting dev-only.

     return P.fcall(function() {
-            const auth_params = {
-                email: argv.email,
-                role: 'admin',
-                system: argv.system,
-            };
-            self.client.options.auth_token = make_auth_token(auth_params);
+            const role = argv.role || 'user';
+            const auth_params = { email: argv.email, role, system: argv.system };
+            const token = argv.token || process.env.NB_ADMIN_TOKEN ||
+                (process.env.NODE_ENV === 'development' ? make_auth_token(auth_params) : null);
+            if (!token) {
+                throw new Error('No auth token provided. Use --token or NB_ADMIN_TOKEN (local minting only in development).');
+            }
+            self.client.options.auth_token = token;
         })
🧹 Nitpick comments (4)
src/server/common_services/auth_server.js (1)

542-549: Docstring polish and accuracy for has_bucket_action_permission

Clarify optional params and avoid TODOs in public docs; align with default of empty bucket_path.

 /**
  * has_bucket_action_permission returns true if the requesting account has permission to perform
  * the given action on the given bucket.
- *
- * The evaluation takes into account
- *  @TODO: System owner as a construct needs to be removed
- *  - system owner must be able to access all buckets
+ * Evaluation considers:
+ *  - system owner access (temporarily allowed for all buckets)
  *  - the bucket's owner account
  *  - the bucket claim owner
  *  - the bucket policy
- * @param {Record<string, any>} bucket requested bucket bucket
+ * @param {Record<string, any>} bucket requested bucket
  * @param {Record<string, any>} account requesting account
  * @param {string} action s3 bucket action (lowercased only)
- * @param {string} bucket_path s3 bucket path (must start from "/")
+ * @param {string} [bucket_path=""] s3 bucket path (if provided must start with "/")
  * @returns  {Promise<boolean>} true if the account has permission to perform the action on the bucket
  */
src/test/pipeline/namespace_test.js (1)

281-287: Prefer explicit token override via NB_ADMIN_TOKEN and tag tokens for auditability

  • Use process.env.NB_ADMIN_TOKEN to override the generated token and add authorized_by: 'pipeline-tests'.
  • Remove or implement argv.token — it’s not defined in any src/test/pipeline tests.
  • Apply this change consistently wherever make_auth_token(...) is used across your pipeline tests.
src/tools/rpc_shell.js (1)

18-21: Remove unused password default

argv.password is no longer used; drop it to avoid confusion.

-argv.password = argv.password || 'DeMo1';
src/test/integration_tests/nsfs/test_nsfs_integration.js (1)

278-283: Setting admin auth via make_auth_token — move earlier to avoid TOCTOU with privileged RPCs

Several privileged RPCs occur before this point (e.g., pool/bucket ops). Set the token in the suite’s before() to guarantee auth is in place for all calls.

Apply:

@@
-        CORETEST_ENDPOINT = coretest.get_http_address();
+        CORETEST_ENDPOINT = coretest.get_http_address();
+        // Ensure RPC is authenticated as admin before any privileged calls
+        rpc_client.options.auth_token = make_auth_token({
+            email: EMAIL,
+            role: 'admin',
+            system: SYSTEM,
+        });

Then remove the late set:

-        rpc_client.options.auth_token = make_auth_token({
-            email: EMAIL,
-            role: 'admin',
-            system: SYSTEM,
-        });
+        // auth configured in suite's before()

Also confirm make_auth_token signs with the same key the server verifies in RPC middleware (to avoid mismatched-token failures). Would you like me to scan other suites and send a bulk diff to hoist this earlier everywhere?

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between dcf3156 and 282b8ab.

📒 Files selected for processing (39)
  • src/agent/block_store_speed.js (2 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (4 hunks)
  • src/server/system_services/account_server.js (3 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (4 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (4)
  • src/sdk/nb.d.ts
  • src/tools/bcrypt_cli.js
  • src/rpc/rpc_schema.js
  • src/test/integration_tests/api/s3/test_bucket_replication.js
✅ Files skipped from review due to trivial changes (1)
  • src/server/system_services/schemas/account_schema.js
🚧 Files skipped from review as they are similar to previous changes (30)
  • src/test/system_tests/test_bucket_placement.js
  • src/test/system_tests/test_s3_authentication.js
  • src/test/utils/agent_functions.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/test/integration_tests/internal/test_system_servers.js
  • src/test/qa/rebuild_replicas_test.js
  • src/test/system_tests/test_node_failure.js
  • src/test/qa/reclaim_test.js
  • src/test/pipeline/quota_test.js
  • src/test/pipeline/account_test.js
  • src/server/system_services/account_server.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/qa/agents_matrix.js
  • src/test/pipeline/system_config.js
  • src/test/qa/cloud_test.js
  • src/test/system_tests/test_md_aggregator.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/agent/block_store_speed.js
  • src/tools/nbcat.js
  • src/test/system_tests/sanity_build_test.js
  • src/cmd/backingstore.js
  • src/tools/md_blow.js
  • src/tools/md_blow_lifecycle.js
  • src/test/pipeline/run_dataset.js
  • src/cmd/api.js
  • src/test/external_tests/external_tests_utils.js
  • src/test/utils/server_functions.js
  • src/test/system_tests/test_cloud_pools.js
  • src/test/utils/basic_server_ops.js
  • src/test/qa/data_availability_test.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/pipeline/namespace_test.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
🧬 Code graph analysis (3)
src/test/pipeline/namespace_test.js (3)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/qa/cloud_test.js (1)
  • auth_params (161-165)
src/tools/rpc_shell.js (11)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • argv (5-5)
src/cmd/api.js (1)
  • require (14-14)
src/cmd/backingstore.js (1)
  • require (19-19)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/account_test.js (2)
  • argv (10-10)
  • auth_params (306-311)
src/test/pipeline/namespace_test.js (3)
  • argv (11-11)
  • argv (58-65)
  • auth_params (281-285)
src/test/pipeline/quota_test.js (2)
  • argv (8-8)
  • argv (20-28)
src/test/pipeline/run_namespace_cache_tests.js (3)
  • argv (8-8)
  • argv (70-79)
  • auth_params (183-187)
src/test/pipeline/system_config.js (3)
  • argv (8-8)
  • argv (23-30)
  • auth_params (208-212)
src/test/integration_tests/nsfs/test_nsfs_integration.js (7)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/cmd/backingstore.js (1)
  • require (19-19)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)
  • require (16-16)
  • require (17-17)
src/test/external_tests/external_tests_utils.js (2)
  • require (5-5)
  • require (7-7)
src/test/integration_tests/internal/test_system_servers.js (1)
  • require (16-16)
src/test/pipeline/account_test.js (2)
  • require (7-7)
  • require (9-9)
⏰ 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 (5)
src/test/pipeline/namespace_test.js (1)

15-16: LGTM: imports make_auth_token for local token minting in tests

This aligns pipeline tests with the new auth flow.

src/tools/rpc_shell.js (1)

12-13: LGTM: importing make_auth_token here matches the new flow

Import is correct and localized.

src/test/integration_tests/nsfs/test_nsfs_integration.js (3)

38-38: Adopt make_auth_token import — good change

Brings tests in line with the bcrypt removal by relying on the server’s token maker.


306-306: Comment-only change

No action needed.


1290-1290: Comment-only change

No action needed.


const coretest = require_coretest();
const { rpc_client, EMAIL, PASSWORD, SYSTEM, get_admin_mock_account_details, NC_CORETEST_CONFIG_FS } = coretest;
const { rpc_client, EMAIL, SYSTEM, get_admin_mock_account_details, NC_CORETEST_CONFIG_FS } = coretest;
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Removed PASSWORD from coretest exports — verify no lingering references

Sweep for any remaining PASSWORD or create_auth_token usage to prevent test breakages.

Run:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -nP '\bPASSWORD\b' -C2 --glob 'src/**'
rg -nP '\bcreate_auth_token\s*\(' -C2 --glob 'src/**'

Length of output: 7771


Remove all lingering PASSWORD exports and references

  • src/test/utils/coretest/coretest.js still defines and exports PASSWORD (lines 81, 683).
  • src/test/utils/coretest/nc_coretest.js still defines and exports PASSWORD (lines 49, 552).
  • src/test/integration_tests/internal/test_system_servers.js still destructures and uses PASSWORD (lines 22, 260).

Remove these exports/imports or update the affected tests to prevent failures.

🤖 Prompt for AI Agents
In src/test/integration_tests/nsfs/test_nsfs_integration.js around line 41, the
file imports PASSWORD via destructuring from coretest but PASSWORD has been
removed from the shared modules; remove PASSWORD from the destructuring on this
line and anywhere else in this file, and in the other affected tests
(src/test/integration_tests/internal/test_system_servers.js) remove the PASSWORD
destructure and usages; then update the coretest modules
(src/test/utils/coretest/coretest.js and src/test/utils/coretest/nc_coretest.js)
to stop exporting PASSWORD (delete the export lines at the referenced locations)
or, if a password value is required, replace calls to PASSWORD with a suitable
existing helper/accessor (e.g., get_admin_mock_account_details or a dedicated
secret getter) and adjust imports accordingly so no test imports or uses a
non-existent PASSWORD export.

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from 282b8ab to 39b0aca Compare September 5, 2025 18:31
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/test/pipeline/account_test.js (2)

364-364: Runtime bug: calling .unwrap() on a string.
create_account() returns a plain string email; .unwrap() will throw.

-    const email = (await create_account(true, fullName)).unwrap();
+    const email = await create_account(true, fullName);

402-403: Same unwrap() bug here.

-            email = (await create_account(true, fullName)).unwrap();
+            email = await create_account(true, fullName);
♻️ Duplicate comments (5)
src/test/external_tests/external_tests_utils.js (1)

36-40: Stop embedding plaintext password in minted token; make role optional

Do not include password in a signed token payload. Accept an optional role (default 'admin') to preserve compatibility.

Apply:

-async function get_rpc_client_by_email_and_password(email, password) {
+async function get_rpc_client_by_email_and_password(email, _password, role = 'admin') {
     const rpc_client = get_global_rpc_client();
-    const auth_params = { email, password, system: 'noobaa', role: 'admin' };
-    rpc_client.options.auth_token = make_auth_token(auth_params);
+    const auth_params = { email, system: 'noobaa', ...(role ? { role } : {}) };
+    rpc_client.options.auth_token = make_auth_token(auth_params);
     return rpc_client;
 }
src/cmd/api.js (3)

41-45: Fix help text typos and clarify token usage

Tidy the OPTIONS text and document NOOBAA_AUTH_TOKEN.

Apply:

-    --address <url>     (default per api type)           Set the address of the rpc server ()
+    --address <url>     (default per api type)           Set the address of the RPC server
@@
-    --token <token>                                      Token to authorize the request
-    --json                                               Output raw json instead of printaable
+    --token <token>                                      Auth token (or set NOOBAA_AUTH_TOKEN)
+    --json                                               Output raw JSON instead of printable

14-14: Do not mint admin tokens in the CLI

Client-side token minting couples the CLI to the signing secret and bypasses server auth. Require a provided token via flag or env.

Apply:

-const { make_auth_token } = require('../server/common_services/auth_server');
+// A token must be supplied via --token or NOOBAA_AUTH_TOKEN

63-68: Require a provided token; fail fast if missing

Stop generating tokens; honor --token or NOOBAA_AUTH_TOKEN and error if absent.

Apply:

-        const token = argv.token || make_auth_token({
-            system: process.env.CREATE_SYS_NAME,
-            role: 'admin',
-            email: process.env.CREATE_SYS_EMAIL
-        });
+        const token = argv.token || process.env.NOOBAA_AUTH_TOKEN;
+        if (!token) {
+            console.error('Missing auth token. Pass --token or set NOOBAA_AUTH_TOKEN.');
+            return print_usage();
+        }
@@
-        client.options.auth_token = token;
+        client.options.auth_token = token;

Also applies to: 79-79

src/test/integration_tests/nsfs/test_nsfs_integration.js (1)

41-41: Removed PASSWORD from coretest destructure — previous concern resolved

This addresses the earlier note about lingering PASSWORD imports in this file. LGTM.

Run to ensure no remaining PASSWORD/create_auth_token references elsewhere:

#!/bin/bash
set -euo pipefail

# Lingering PASSWORD references
rg -nP -C2 --glob 'src/**' '\bPASSWORD\b'

# Old server-side auth flows
rg -nP -C2 --glob 'src/**' '\bcreate_auth_token\s*\('
rg -nP -C2 --glob 'src/**' '\bcreate_auth\s*\('
🧹 Nitpick comments (7)
src/test/pipeline/account_test.js (2)

75-83: Remove obsolete 'reset_password' case from reporter.
Password flows are gone; keeping this case skews reporting.

-    'restrict_ip_access',
-    'reset_password'
+    'restrict_ip_access'

123-124: Redact secrets in logs.
Leaking access and secret keys to stdout is risky, even in tests.

-        console.log("S3 access keys: " + s3AccessKeys.accessKeyId, s3AccessKeys.secretAccessKey);
+        const redactedId = s3AccessKeys.accessKeyId
+            ? `${s3AccessKeys.accessKeyId.slice(0,4)}...${s3AccessKeys.accessKeyId.slice(-4)}`
+            : undefined;
+        console.log("S3 access keys:", redactedId, "***REDACTED***");
src/test/utils/coretest/coretest.js (2)

87-90: Avoid pre-minting an admin token before system bootstrap

Create the client without a token and assign the real token only after create_system() returns. This keeps the bootstrap path unauthenticated and avoids minting a blanket admin token unnecessarily.

Apply:

-const rpc_client = server_rpc.rpc.new_client({
-    auth_token: auth_server.make_auth_token({ system: SYSTEM, email: EMAIL, role: 'admin' }),
-    tracker: req => api_coverage.delete(req.srv),
-});
+const rpc_client = server_rpc.rpc.new_client({
+    tracker: req => api_coverage.delete(req.srv),
+});

94-96: Shallow-copy options when spawning new clients

Passing rpc_client.options by reference couples future mutations; prefer a shallow copy.

Apply:

-function new_rpc_client() {
-    return server_rpc.rpc.new_client(rpc_client.options);
-}
+function new_rpc_client() {
+    return server_rpc.rpc.new_client({ ...rpc_client.options });
+}
src/test/pipeline/namespace_test.js (1)

281-287: Parametrize auth subject; don’t hardcode ‘demo’

Read email/system/role from env/args with sensible defaults to reduce hidden coupling and ease reuse.

Apply:

 async function set_rpc_and_create_auth_token() {
-    const auth_params = {
-        email: 'demo@noobaa.com',
-        system: 'demo',
-        role: 'admin',
-    };
-    client.options.auth_token = make_auth_token(auth_params);
+    const auth_params = {
+        email: process.env.CREATE_SYS_EMAIL || 'demo@noobaa.com',
+        system: process.env.CREATE_SYS_NAME || 'demo',
+        role: process.env.NOOBAA_ROLE || 'admin',
+    };
+    client.options.auth_token = make_auth_token(auth_params);
 }

Also verify no callers depend on this function returning a token (it no longer returns one).

src/server/system_services/schemas/account_schema.js (1)

28-29: Mark fields as deprecated in-schema and plan data cleanup

Good to label as deprecated. Add $comment annotations to surface the status in tooling, and plan a migration to clear legacy password hashes.

Apply:

-        password: { wrapper: SensitiveString }, // bcrypted password - DEPRECATED
-        next_password_change: { date: true }, // DEPRECATED
+        // DEPRECATED: retained for compatibility; remove after data migration
+        password: { wrapper: SensitiveString, $comment: 'DEPRECATED: bcrypted password' },
+        next_password_change: { date: true, $comment: 'DEPRECATED' },

Please confirm new account flows set has_login=false and no code path still writes to password.

src/test/integration_tests/nsfs/test_nsfs_integration.js (1)

278-282: Redundant token assignment — rpc_client already initialized with admin token

coretest initializes rpc_client with an admin token; reassigning mid-suite is unnecessary and risks drift if init logic changes. Consider dropping it or move to a suite-level before if you truly need a refresh.

-        rpc_client.options.auth_token = make_auth_token({
-            email: EMAIL,
-            role: 'admin',
-            system: SYSTEM,
-        });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 282b8ab and 39b0aca.

📒 Files selected for processing (40)
  • src/agent/block_store_speed.js (2 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (4 hunks)
  • src/server/system_services/account_server.js (3 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (4 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/coretest/coretest.js (1 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (4)
  • src/sdk/nb.d.ts
  • src/rpc/rpc_schema.js
  • src/tools/bcrypt_cli.js
  • src/test/integration_tests/api/s3/test_bucket_replication.js
🚧 Files skipped from review as they are similar to previous changes (29)
  • src/test/system_tests/test_bucket_placement.js
  • src/test/qa/rebuild_replicas_test.js
  • src/tools/md_blow_lifecycle.js
  • src/test/integration_tests/internal/test_system_servers.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/test/system_tests/test_md_aggregator.js
  • src/tools/md_blow.js
  • src/test/qa/reclaim_test.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/system_tests/sanity_build_test.js
  • src/test/utils/agent_functions.js
  • src/test/utils/basic_server_ops.js
  • src/test/qa/cloud_test.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/test/system_tests/test_s3_authentication.js
  • src/test/utils/server_functions.js
  • src/test/pipeline/quota_test.js
  • src/test/system_tests/test_cloud_pools.js
  • src/test/qa/agents_matrix.js
  • src/server/system_services/account_server.js
  • src/test/system_tests/test_node_failure.js
  • src/tools/nbcat.js
  • src/cmd/backingstore.js
  • src/agent/block_store_speed.js
  • src/tools/rpc_shell.js
  • src/test/qa/data_availability_test.js
  • src/test/pipeline/system_config.js
  • src/test/pipeline/run_dataset.js
  • src/server/common_services/auth_server.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/external_tests/external_tests_utils.js
  • src/test/pipeline/account_test.js
  • src/test/pipeline/namespace_test.js
  • src/test/utils/coretest/coretest.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
🧬 Code graph analysis (6)
src/test/external_tests/external_tests_utils.js (6)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/cmd/backingstore.js (1)
  • require (19-19)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/integration_tests/internal/test_system_servers.js (1)
  • require (16-16)
src/test/utils/coretest/coretest.js (3)
  • rpc_client (87-90)
  • rpc_client (227-231)
  • rpc_client (413-413)
src/test/pipeline/account_test.js (8)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • client (22-24)
src/test/external_tests/external_tests_utils.js (2)
  • require (5-5)
  • require (7-7)
src/test/integration_tests/internal/test_system_servers.js (1)
  • require (16-16)
src/test/pipeline/namespace_test.js (1)
  • client (84-84)
src/test/pipeline/run_dataset.js (1)
  • client (60-60)
src/test/pipeline/namespace_test.js (6)
src/agent/block_store_speed.js (2)
  • require (13-13)
  • require (14-14)
src/cmd/api.js (1)
  • require (14-14)
src/cmd/backingstore.js (1)
  • require (19-19)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/integration_tests/internal/test_system_servers.js (1)
  • require (16-16)
src/test/utils/coretest/coretest.js (2)
src/test/external_tests/external_tests_utils.js (1)
  • rpc_client (37-37)
src/test/pipeline/run_namespace_cache_tests.js (1)
  • rpc_client (100-100)
src/cmd/api.js (3)
src/cmd/backingstore.js (1)
  • require (19-19)
src/agent/block_store_speed.js (2)
  • token (39-43)
  • argv (5-5)
src/server/common_services/auth_server.js (3)
  • token (150-156)
  • token (258-263)
  • process (59-66)
src/test/integration_tests/nsfs/test_nsfs_integration.js (1)
src/test/utils/coretest/coretest.js (4)
  • rpc_client (87-90)
  • rpc_client (227-231)
  • rpc_client (413-413)
  • EMAIL (76-76)
⏰ 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 (4)
src/test/pipeline/account_test.js (1)

9-9: Import of make_auth_token looks correct.
Pathing is right for tests under src/test/pipeline.

src/test/integration_tests/nsfs/test_nsfs_integration.js (3)

38-38: Adopt make_auth_token import — aligns with passwordless auth

Directly importing make_auth_token is correct for the new flow. LGTM.


306-306: Comment-only change

No action needed.


1290-1290: Comment-only change

No action needed.

Comment on lines 306 to 316
const auth_params = {
email,
password: 'DeMo1',
system: 'demo'
system: 'demo',
role: 'admin'
};
try {
const auth_token = await client.create_auth_token(auth_params);
if (auth_token.token !== null && auth_token.token !== '') {
console.log(`Account ${email} has access to server`);
} else {
saveErrorAndResume(`Account can't auth`);
failures_in_test = true;
}
client.options.auth_token = make_auth_token(auth_params);
} catch (e) {
throw new Error(`failed to create_auth_token for ${auth_params.email}`);
}
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Don’t mint admin tokens for all users; drop unused password; fix error text.
Minting an admin token for arbitrary emails defeats permission semantics and can mask bugs. Also, password is no longer used. Update the params and message.

Apply:

-    const auth_params = {
-        email,
-        password: 'DeMo1',
-        system: 'demo',
-        role: 'admin'
-    };
+    const role = email === DEFAULT_EMAIL ? 'admin' : 'user';
+    const auth_params = { email, system: 'demo', role };
@@
-        throw new Error(`failed to create_auth_token for ${auth_params.email}`);
+        throw new Error(`failed to make_auth_token for ${auth_params.email}`);

Verification (grep for other hard-coded admin tokens in tests):


🏁 Script executed:

#!/bin/bash
rg -nP --type=js -C2 "role:\s*'admin'" src/test | sed -n '1,200p'

Length of output: 11284


Consolidate test auth-token generation and eliminate hard-coded admin/passwords

  • Extract a shared helper (e.g. buildAuthParams(email, role?)) in src/test/utils and replace all inline { email, system: 'demo', role: 'admin', … } calls with it.
  • Drop the unused password field from every make_auth_token invocation.
  • In src/test/pipeline/account_test.js, update the error to failed to make_auth_token for ${email} (and align similar messages elsewhere).
🤖 Prompt for AI Agents
In src/test/pipeline/account_test.js around lines 306 to 317, the test builds
auth params inline (including a hard-coded password) and throws a nonstandard
error message; extract a shared helper buildAuthParams(email, role?) into
src/test/utils that returns { email, system: 'demo', role: role || 'admin' },
replace all inline auth param objects with calls to that helper, remove the
unused password property from every make_auth_token invocation, and change the
catch error to throw new Error(`failed to make_auth_token for ${email}`) (also
update equivalent messages in other tests to match).

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from 39b0aca to c0aed74 Compare September 5, 2025 19:11
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: 3

♻️ Duplicate comments (3)
src/test/pipeline/system_config.js (1)

37-37: Remove obsolete --password from usage

Help text still advertises a password flag that’s no longer supported.

Apply:

-    --password              -   noobaa management Credentials (password)
src/agent/block_store_speed.js (1)

39-43: Do not auto-mint admin tokens in the agent; require an explicit token and gate dev-only minting with TTL.

Auto-minting admin tokens is a high-risk escalation vector when the signing secret is present. Require --token or NOOBAA_AUTH_TOKEN; allow minting only behind an explicit dev flag with short TTL.

Apply this diff:

-    const token = argv.token || make_auth_token({
-        system: argv.system,
-        role: 'admin',
-        email: argv.email,
-    });
+    // Prefer explicit token; allow dev-only minting with TTL.
+    let token = argv.token || process.env.NOOBAA_AUTH_TOKEN;
+    if (!token) {
+        if (argv.dev || process.env.NOOBAA_AGENT_DEV === '1') {
+            const ttlSec = Number(argv.token_ttl_sec || process.env.NOOBAA_AUTH_TOKEN_TTL_SEC || 3600);
+            const { make_auth_token } = require('../server/common_services/auth_server');
+            token = make_auth_token({
+                system: argv.system,
+                role: 'admin',
+                email: argv.email,
+                expiry: Date.now() + ttlSec * 1000,
+                authorized_by: 'agent-dev',
+            });
+            console.warn('block_store_speed: using dev-minted token (TTL=%ds)', ttlSec);
+        } else {
+            throw new Error('Missing auth token. Pass --token or set NOOBAA_AUTH_TOKEN.');
+        }
+    }

Additionally (outside the selected lines), avoid leaking secrets in logs:

// replace console.log('ARGS', argv);
const { token, ...rest } = argv;
console.log('ARGS', { ...rest, token: token ? '<redacted>' : undefined });

Please verify make_auth_token’s expiry semantics (absolute vs. relative). If it expects a relative value, adjust accordingly.

src/tools/nbcat.js (1)

71-78: init_api() is sync but callers use .then() — make it async (same behavior, Promise-returning).

Call sites at Lines 21-35, 36-49, 50-68 chain .then(...). Keep API contract by returning a Promise.

-function init_api() {
+async function init_api() {
     const auth_params = {
         email: 'demo@noobaa.com',
         role: 'admin',
         system: 'demo',
     };
     client.options.auth_token = make_auth_token(auth_params);
 }
🧹 Nitpick comments (11)
src/test/pipeline/system_config.js (3)

205-214: Rename for clarity and drop unnecessary async

Function no longer “creates” a token over RPC and doesn’t await anything.

Apply:

-async function set_rpc_and_create_auth_token() {
+function set_rpc_and_set_auth_token() {
   rpc = api.new_rpc_from_base_address('wss://' + mgmt_ip + ':' + mgmt_port_https, 'EXTERNAL');
   client = rpc.new_client({});
   const auth_params = {
       email,
       role: 'admin',
       system
   };
   client.options.auth_token = make_auth_token(auth_params);
 }
-        await set_rpc_and_create_auth_token();
+        set_rpc_and_set_auth_token();

Also applies to: 221-221


213-213: Directly setting client.options.auth_token is fine

No RPC round-trip; aligns with the removal of server-side create_auth. Ensure other tests follow the same pattern to avoid drift.


138-139: Fix log message: hardcoded max port

The message always prints 60500 instead of the provided max.

Apply:

-        console.log(`The tcp port range is: ${min} to ${60500} - as should`);
+        console.log(`The tcp port range is: ${min} to ${max} - as should`);
src/test/qa/agents_matrix.js (2)

108-112: Initialize auth at client construction to avoid any handshake timing risk

Pass the token when creating the client instead of mutating options later.

Apply this diff to remove the late assignment:

-        client.options.auth_token = make_auth_token({
-            email: 'demo@noobaa.com',
-            role: 'admin',
-            system: 'demo'
-        });
+        // auth_token is passed via rpc.new_client(...) at construction time.

And set it at creation (outside this range, shown for clarity):

// Line 50
const client = rpc.new_client({
    auth_token: make_auth_token({ email: 'demo@noobaa.com', role: 'admin', system: 'demo' }),
});

114-114: Fix stale error message

Update to reflect make_auth_token.

-        console.error(`create_auth_token has failed`, e);
+        console.error(`make_auth_token has failed`, e);
src/agent/block_store_speed.js (2)

14-14: Avoid coupling agent code to server auth internals.

Top-level importing make_auth_token from server/common_services ties the agent to server-only code. Prefer a shared lightweight util or lazy-require only in a guarded dev path (see next comment).

// In the guarded dev path only:
// const { make_auth_token } = require('../server/common_services/auth_server');

50-50: Propagate auth to all RPC clients that need it.

If signal_client performs authenticated calls, set its token too.

-    client.options.auth_token = token;
+    client.options.auth_token = token;
+    // If required by n2n signaling:
+    // signal_client.options.auth_token = token;
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)

17-17: Decouple from server internals: import token helper via test utils

Reduce brittleness by importing a helper from external_tests_utils (and re-exporting there) rather than reaching into server internals with a deep relative path.

Apply this diff here:

-const { make_auth_token } = require('../../../server/common_services/auth_server');
+const { get_admin_auth_token } = require('../external_tests_utils');

And add this minimal helper in src/test/external_tests/external_tests_utils.js:

function get_admin_auth_token(email = process.env.email) {
  if (!email) throw new Error('Missing env var: email');
  return make_auth_token({ email, system: 'noobaa', role: 'admin' });
}
module.exports.get_admin_auth_token = get_admin_auth_token;

This centralizes auth claims and avoids duplicate logic across tests.


39-44: Fail fast on missing email; fix log grammar; preserve error cause

If process.env.email is unset the token may be malformed; also tweak the error message and keep the original cause for easier debugging.

Apply:

-        const auth_params = { email: process.env.email, system: 'noobaa', role: 'admin' };
-        client.options.auth_token = make_auth_token(auth_params);
+        const email = process.env.email;
+        if (!email) throw new Error('Missing env var: email');
+        const auth_params = { email, system: 'noobaa', role: 'admin' };
+        client.options.auth_token = make_auth_token(auth_params);
@@
-        console.error('Failed create auth token', err);
-        throw new Error('Failed create auth token');
+        console.error('Failed to create auth token', err);
+        // Preserve the underlying error for better diagnostics
+        throw new Error('Failed to create auth token', { cause: err });

If Node <16 is targeted, replace the { cause } form with: throw new Error('Failed to create auth token: ' + err.message);

src/test/system_tests/test_md_aggregator.js (2)

31-39: Align comment, harden token assignment, and standardize admin claims

- // Does the Auth and returns the nodes in the system
+ // Set admin auth token on the RPC client
  function create_auth() {
-    const auth_params = {
+    const ADMIN_AUTH = { email: 'demo@noobaa.com', role: 'admin', system: 'demo' };
-    client.options.auth_token = make_auth_token(auth_params);
+    const token = make_auth_token(ADMIN_AUTH);
+    if (typeof client.set_auth_token === 'function') {
+      client.set_auth_token(token);
+    } else {
+      client.options.auth_token = token;
+    }
  }

Verify that make_auth_token accepts the {email, role, system} payload shape (or adjust to use {system_id, account_id} if required).


16-16: Use test utils for auth tokens
In test_md_aggregator.js (line 16), replace

const { make_auth_token } = require('../../server/common_services/auth_server');

with an import from your test utility (e.g.

const { make_auth_token } = require('../utils/basic_server_ops');

or server_functions.js) to decouple tests from server internals.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 39b0aca and c0aed74.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (41)
  • package.json (0 hunks)
  • src/agent/block_store_speed.js (2 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (4 hunks)
  • src/server/system_services/account_server.js (3 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (4 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/coretest/coretest.js (1 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (5)
  • src/rpc/rpc_schema.js
  • src/sdk/nb.d.ts
  • package.json
  • src/test/integration_tests/api/s3/test_bucket_replication.js
  • src/tools/bcrypt_cli.js
🚧 Files skipped from review as they are similar to previous changes (30)
  • src/test/qa/cloud_test.js
  • src/test/utils/agent_functions.js
  • src/test/pipeline/quota_test.js
  • src/test/qa/reclaim_test.js
  • src/test/qa/rebuild_replicas_test.js
  • src/test/pipeline/account_test.js
  • src/test/external_tests/external_tests_utils.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/server/system_services/account_server.js
  • src/test/system_tests/sanity_build_test.js
  • src/test/integration_tests/internal/test_system_servers.js
  • src/test/system_tests/test_s3_authentication.js
  • src/test/system_tests/test_cloud_pools.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/qa/data_availability_test.js
  • src/cmd/api.js
  • src/test/utils/basic_server_ops.js
  • src/test/pipeline/namespace_test.js
  • src/test/system_tests/test_bucket_placement.js
  • src/test/utils/server_functions.js
  • src/server/common_services/auth_server.js
  • src/test/pipeline/run_dataset.js
  • src/test/system_tests/test_node_failure.js
  • src/tools/md_blow_lifecycle.js
  • src/cmd/backingstore.js
  • src/test/utils/coretest/coretest.js
  • src/tools/md_blow.js
  • src/tools/rpc_shell.js
  • src/server/system_services/schemas/account_schema.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/system_tests/test_md_aggregator.js
  • src/test/pipeline/system_config.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/test/qa/agents_matrix.js
🧬 Code graph analysis (4)
src/test/system_tests/test_md_aggregator.js (2)
src/test/system_tests/test_bucket_placement.js (5)
  • require (18-18)
  • client (31-33)
  • client (108-111)
  • client (129-132)
  • auth_params (44-48)
src/test/utils/basic_server_ops.js (4)
  • require (10-10)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
src/agent/block_store_speed.js (2)
src/cmd/api.js (3)
  • require (14-14)
  • token (63-67)
  • api (13-13)
src/server/common_services/auth_server.js (3)
  • require (7-7)
  • token (150-156)
  • token (258-263)
src/test/pipeline/system_config.js (6)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • client (46-46)
src/cmd/api.js (2)
  • require (14-14)
  • client (78-78)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • client (22-24)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/account_test.js (2)
  • client (17-17)
  • auth_params (306-311)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)
src/server/common_services/auth_server.js (2)
  • require (7-7)
  • process (59-66)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
⏰ 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-package-lock-validation
  • GitHub Check: run-jest-unit-tests
🔇 Additional comments (4)
src/test/pipeline/system_config.js (3)

10-10: Good switch to local token generation

Importing make_auth_token from the server auth service is correct for test-only token creation.


210-211: Auth params look right for admin tests

Explicit role: 'admin' with email/system matches the new token flow.


221-223: Double-check early disconnect

You disconnect immediately after setting the token. If RPC lazily reconnects on first call, fine; if not, subsequent operations will fail.

Would you like me to scan the RPC client for lazy reconnect semantics and validate this assumption across tests?

src/test/qa/agents_matrix.js (1)

48-48: Local token minting via make_auth_token — LGTM

Eliminates a network round-trip and reduces test flakiness. Good direction for test auth.

Comment on lines +48 to 49
const { make_auth_token } = require('../../server/common_services/auth_server');
const rpc = api.new_rpc_from_base_address(`wss://${mgmt_ip}:${mgmt_port}`, 'EXTERNAL');
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify full removal of server-side auth and bcrypt usages

Quick sanity check across the repo to ensure no stragglers remain (API create_auth, create_auth_token, bcrypt).


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Searching for server-side auth issuance still in use..."
rg -nP -C2 '\bcreate_auth_token\b|\bcreate_auth\s*\(' src || true

echo "2) Searching for bcrypt references..."
rg -nP -C2 '\bbcrypt\b' || true

echo "3) Auditing tests now mint tokens locally..."
rg -nP -n '\bmake_auth_token\s*\(' src/test || true

echo "4) Spot any remaining direct mutations after client creation?"
rg -nP -n 'client\.options\.auth_token\s*=' src || true

Length of output: 16033


Remove all remaining server-side authentication and bcrypt code

  • Eliminate calls to auth_server.make_auth_token, create_auth/create_auth_token in server code (e.g. src/server/system_services/pool_server.js:254–255, src/server/common_services/auth_server.js:36)
  • Remove all test and tooling references to create_auth/create_auth_token (e.g. src/test/system_tests/*, src/test/qa/agents_matrix.js)
  • Remove bcrypt imports/usages (e.g. awscli_iwgdirl7.sreq)
🤖 Prompt for AI Agents
In src/test/qa/agents_matrix.js around lines 48-49, the test still requires
make_auth_token from the server auth module and references server-side auth;
remove the require(".../auth_server") and any calls to make_auth_token or
create_auth/create_auth_token in this file, replacing any usage with the
non-authenticated flow (or pass no token) consistent with the refactor; also
search this test file for other auth/bcrypt references and remove them so tests
no longer call server-side auth helpers, then run the test suite to ensure no
remaining auth imports/usages remain.

const size_utils = require('../util/size_utils');
const api = require('../api');
const ObjectIO = require('../sdk/object_io');
const { make_auth_token } = require('../server/common_services/auth_server');
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Local token minting in a CLI breaks the trust boundary — gate it behind a dev flag (or remove).

Importing server/common_services/auth_server lets this tool mint arbitrary admin tokens if the signing secret is available, effectively bypassing auth. If this is dev/test-only, guard it explicitly and prefer an env-provided token for normal use.

Apply:

-const { make_auth_token } = require('../server/common_services/auth_server');
+// Dev-only local signing: enable with NOOBAA_LOCAL_SIGN=1
+const DEV_LOCAL_SIGN = process.env.NOOBAA_LOCAL_SIGN === '1';
+let make_auth_token;
+if (DEV_LOCAL_SIGN) {
+    ({ make_auth_token } = require('../server/common_services/auth_server'));
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/tools/nbcat.js around line 8, importing make_auth_token from
server/common_services/auth_server allows the CLI to mint admin tokens and
breaks the trust boundary; remove that direct import and instead require an
explicit, deliberate dev-only flow: either (a) remove local token minting
entirely and read a token from an environment variable or CLI argument (fail
fast if not provided), or (b) gate token minting behind a strict --dev or
NODE_ENV=development guard so the minting code runs only when that flag is
present; ensure you do not call into server signing code in production and add
an explanatory error message when a non-dev environment attempts to use the
minting path.

Comment on lines 71 to 75
function init_api() {
return client.create_auth_token({
const auth_params = {
email: 'demo@noobaa.com',
password: 'DeMo1',
role: 'admin',
system: 'demo',
});
};
client.options.auth_token = make_auth_token(auth_params);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid hard-coded admin token minting; prefer env token with optional dev-sign path.

Reduce risk and make usage explicit. Fails fast if no token provided in non-dev mode.

-async function init_api() {
-    const auth_params = {
-        email: 'demo@noobaa.com',
-        role: 'admin',
-        system: 'demo',
-    };
-    client.options.auth_token = make_auth_token(auth_params);
-}
+async function init_api() {
+    if (!DEV_LOCAL_SIGN) {
+        const token = process.env.NOOBAA_AUTH_TOKEN;
+        if (!token) {
+            throw new Error('Set NOOBAA_AUTH_TOKEN or enable dev signing with NOOBAA_LOCAL_SIGN=1');
+        }
+        client.options.auth_token = token;
+        return;
+    }
+    const auth_params = {
+        email: process.env.NOOBAA_DEV_EMAIL || 'demo@noobaa.com',
+        role: process.env.NOOBAA_DEV_ROLE || 'admin',
+        system: process.env.NOOBAA_DEV_SYSTEM || 'demo',
+    };
+    client.options.auth_token = make_auth_token(auth_params);
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/tools/nbcat.js around lines 71 to 78, the function currently mints a
hard-coded admin auth token; replace this with reading an ADMIN_TOKEN (or
similar) from environment and only fall back to a dev-signing code path when
running in a dev mode (e.g., NODE_ENV==='development' or a DEV_SIGN env flag).
Concretely: remove the hard-coded auth_params, set client.options.auth_token =
process.env.ADMIN_TOKEN when present, if missing and DEV_SIGN is enabled
generate a token via the existing make_auth_token/dev helper, and if missing and
not in dev mode throw/exit immediately with a clear error so the process fails
fast. Ensure any dev-sign path is explicitly gated and logged so production
never mints a token implicitly.

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from c0aed74 to 91a59f2 Compare September 5, 2025 19:30
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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
src/server/common_services/auth_server.js (4)

132-137: Expiry units bug: jwt expiresIn expects seconds, not milliseconds.
OAuth expires_in is seconds; multiplying by 1000 makes tokens 1000x longer-lived.

-        expiry: Math.floor(expires_in * 1000),
+        // expires_in is seconds; pass through as-is
+        expiry: Math.floor(expires_in),

Optionally: expiry: ${Math.floor(expires_in)}s``.


239-245: Role escalation in access-key auth: token hardcodes role 'admin'.
This mints admin tokens for any account with valid access keys, regardless of actual role.

-    const token = make_auth_token({
-        system_id: system._id,
-        account_id: account._id,
-        role: 'admin',
-        s3_auth: auth_extra,
-    });
+    const token = make_auth_token({
+        system_id: system._id,
+        account_id: account._id,
+        role: role.role,
+        authorized_by: 'access_key',
+        s3_auth: auth_extra,
+    });

Add a test to assert non-admin accounts don’t receive admin tokens.


420-441: Authorize should verify the account actually has the claimed role in the system.
Currently it trusts the role embedded in the token. Cross-check against roles to prevent forged “admin” claims.

         if (req.system) {
             let allowed_role;
             if ((req.account && req.account.is_support) || req.auth.role === 'operator') {
                 allowed_role = true;
             } else if (typeof options.system === 'string') {
                 allowed_role = options.system === req.auth.role;
             } else if (Array.isArray(options.system)) {
                 allowed_role = _.includes(options.system, req.auth.role);
             } else {
                 allowed_role = allow_missing_system;
             }
 
             if (!allowed_role) {
                 dbg.warn('role not allowed in system', options, req.auth, req.account, req.system);
                 throw new RpcError('UNAUTHORIZED', 'role not allowed in system');
             }
+
+            // NEW: enforce role membership
+            if (req.account && !req.account.is_support) {
+                const has_role = system_store.data.roles.some(r =>
+                    String(r.system._id) === String(req.system._id) &&
+                    String(r.account._id) === String(req.account._id) &&
+                    r.role === req.auth.role
+                );
+                if (!has_role) throw new RpcError('UNAUTHORIZED', 'account does not have the claimed role');
+            }
         }

601-614: Stop exposing make_auth_token to client code
make_auth_token is imported in numerous CLI tools (src/tools/*, src/cmd/*), agents (src/agent/*, src/hosted_agents/*) and even blob endpoints, enabling users to craft arbitrary email/system/role claims. Remove it from auth_server.js exports and refactor all clients/tools/agents to obtain tokens via a server‐side API or use the private make_internal_auth_token exclusively on the server.

♻️ Duplicate comments (2)
src/test/integration_tests/nsfs/test_nsfs_integration.js (1)

41-41: Past concern resolved: PASSWORD removed from coretest destructuring.

src/server/common_services/auth_server.js (1)

383-389: Lookup by raw email/system is brittle; normalize and support legacy keys.
Use store helpers and normalization to avoid case/shape mismatches and keep backward-compat with system_name/system.

Apply:

-            if (req.auth.account_id) req.account = system_store.data.get_by_id(req.auth.account_id);
-            else if (req.auth.email) req.account = system_store.data.accounts_by_email[req.auth.email];
+            if (req.auth.account_id) {
+                req.account = system_store.data.get_by_id(req.auth.account_id);
+            } else if (req.auth.email) {
+                const email = String(req.auth.email).trim().toLowerCase();
+                req.account = system_store.get_account_by_email(new SensitiveString(email));
+            }-            if (req.auth.system_id) req.system = system_store.data.get_by_id(req.auth.system_id);
-            else if (req.auth.system) req.system = system_store.data.systems_by_name[req.auth.system];
+            if (req.auth.system_id) {
+                req.system = system_store.data.get_by_id(req.auth.system_id);
+            } else if (req.auth.system_name || req.auth.system) {
+                const name = String(req.auth.system_name || req.auth.system);
+                req.system = system_store.data.systems_by_name[name];
+            }
🧹 Nitpick comments (11)
src/server/system_services/account_server.js (2)

1266-1272: Support account shape: OK, but clarify has_login semantics

Creating a minimal, passwordless support account is aligned with removing bcrypt. However, get_account_info() later forces info.has_login = true for support accounts, while here has_login is set to false. Either set has_login: true here or stop overriding it in get_account_info() to avoid confusing consumers.

 const support_account = {
   _id: system_store.new_system_store_id(),
   name: new SensitiveString('Support'),
   email: new SensitiveString('support@noobaa.com'),
-  has_login: false,
+  has_login: true,
   is_support: true,
 };

1274-1278: Return/await persistence — good; prefer dbg over console.log

Returning the make_changes promise fixes the race. Replace console.log with the repo’s debug logger for consistency.

-            }).then(() => console.log('SUPPORT ACCOUNT CREATED'));
+            }).then(() => dbg.log0('SUPPORT ACCOUNT CREATED'));
src/test/system_tests/sanity_build_test.js (1)

79-87: Centralize auth token setup into a shared helper
Tests across src/test/** repeatedly hand-roll { make_auth_token } imports, build identical auth_params, and set client.options.auth_token. Extract this into a single utility (e.g. src/test/utils/auth.js) to DRY up the code. Also clean up lingering password fields in auth parameters now that bcrypt support has been removed.

src/test/qa/cloud_test.js (1)

160-167: Token assignment inline is fine; consider shared helper

Same suggestion as other tests: extract auth token creation to a shared helper to keep tests consistent.

src/test/system_tests/test_node_failure.js (1)

53-58: Auth params updated — LGTM; consider using shared helper

Consistent with new auth model. Suggest centralizing token creation to reduce duplication across tests.

src/test/integration_tests/internal/test_system_servers.js (1)

257-261: Avoid re-minting admin token in-test (rpc_client already starts authenticated).
Coretest initializes rpc_client with an admin token; reassigning here is redundant and risks cross-test leakage. Either rely on the existing token or save/restore it around the section.

Apply one of:

-            rpc_client.options.auth_token = make_auth_token({
-                system: SYSTEM,
-                email: EMAIL,
-                role: 'admin',
-            });
+            // rpc_client is already admin; no need to reassign

or

+            const prev = rpc_client.options.auth_token;
             rpc_client.options.auth_token = make_auth_token({
                 system: SYSTEM,
                 email: EMAIL,
                 role: 'admin',
             });
             const res = await rpc_client.system.read_system();
             …
+            rpc_client.options.auth_token = prev;

Also applies to: 287-291

src/cmd/backingstore.js (2)

96-113: Bootstrap flow fragility: missing env validation and error messaging.
If CREATE_SYS_NAME/CREATE_SYS_EMAIL are unset, the omitBy in make_auth_token yields a token lacking system/account, leading to opaque UNAUTHORIZED later. Add explicit validation now.

(Guard patch included in the previous diff.)


102-113: Consider accepting a pre-provisioned install string to remove admin dependency.
Support an INSTALL_STRING or CREATE_NODE_TOKEN env/file to skip the admin call altogether in air-gapped/locked-down setups.

src/test/integration_tests/nsfs/test_nsfs_integration.js (2)

38-38: Import added is fine, but may be unnecessary.
If you drop the manual token reassignment below, remove this import to keep the file lean.


278-283: Redundant token reassignment.
rpc_client from coretest is already authenticated as admin; reassigning here isn’t needed. Prefer relying on the initial token or save/restore if you must switch identities mid-test.

-        rpc_client.options.auth_token = make_auth_token({
-            email: EMAIL,
-            role: 'admin',
-            system: SYSTEM,
-        });
+        // Already authenticated as admin via coretest setup.
src/server/common_services/auth_server.js (1)

549-551: Return RpcError, not generic Error, for RPC-facing validation.

-        throw new Error('has_bucket_action_permission: action is required');
+        throw new RpcError('BAD_REQUEST', 'has_bucket_action_permission: action is required');
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c0aed74 and 91a59f2.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (43)
  • package.json (0 hunks)
  • src/agent/block_store_speed.js (2 hunks)
  • src/api/account_api.js (0 hunks)
  • src/api/auth_api.js (0 hunks)
  • src/cmd/api.js (4 hunks)
  • src/cmd/backingstore.js (2 hunks)
  • src/rpc/rpc_schema.js (0 hunks)
  • src/sdk/nb.d.ts (0 hunks)
  • src/server/common_services/auth_server.js (3 hunks)
  • src/server/system_services/account_server.js (2 hunks)
  • src/server/system_services/schemas/account_schema.js (1 hunks)
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2 hunks)
  • src/test/external_tests/external_tests_utils.js (2 hunks)
  • src/test/integration_tests/api/s3/test_bucket_replication.js (0 hunks)
  • src/test/integration_tests/internal/test_system_servers.js (3 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (4 hunks)
  • src/test/pipeline/account_test.js (2 hunks)
  • src/test/pipeline/namespace_test.js (2 hunks)
  • src/test/pipeline/quota_test.js (2 hunks)
  • src/test/pipeline/run_dataset.js (2 hunks)
  • src/test/pipeline/run_namespace_cache_tests.js (2 hunks)
  • src/test/pipeline/system_config.js (2 hunks)
  • src/test/qa/agents_matrix.js (2 hunks)
  • src/test/qa/cloud_test.js (2 hunks)
  • src/test/qa/data_availability_test.js (2 hunks)
  • src/test/qa/rebuild_replicas_test.js (2 hunks)
  • src/test/qa/reclaim_test.js (2 hunks)
  • src/test/system_tests/sanity_build_test.js (2 hunks)
  • src/test/system_tests/test_bucket_access.js (2 hunks)
  • src/test/system_tests/test_bucket_placement.js (2 hunks)
  • src/test/system_tests/test_cloud_pools.js (2 hunks)
  • src/test/system_tests/test_md_aggregator.js (2 hunks)
  • src/test/system_tests/test_node_failure.js (2 hunks)
  • src/test/system_tests/test_s3_authentication.js (2 hunks)
  • src/test/utils/agent_functions.js (5 hunks)
  • src/test/utils/basic_server_ops.js (2 hunks)
  • src/test/utils/coretest/coretest.js (1 hunks)
  • src/test/utils/server_functions.js (3 hunks)
  • src/tools/bcrypt_cli.js (0 hunks)
  • src/tools/md_blow.js (2 hunks)
  • src/tools/md_blow_lifecycle.js (2 hunks)
  • src/tools/nbcat.js (2 hunks)
  • src/tools/rpc_shell.js (2 hunks)
💤 Files with no reviewable changes (7)
  • package.json
  • src/test/integration_tests/api/s3/test_bucket_replication.js
  • src/api/account_api.js
  • src/api/auth_api.js
  • src/rpc/rpc_schema.js
  • src/tools/bcrypt_cli.js
  • src/sdk/nb.d.ts
🚧 Files skipped from review as they are similar to previous changes (27)
  • src/test/qa/reclaim_test.js
  • src/server/system_services/schemas/account_schema.js
  • src/test/qa/data_availability_test.js
  • src/test/utils/agent_functions.js
  • src/agent/block_store_speed.js
  • src/test/pipeline/run_namespace_cache_tests.js
  • src/cmd/api.js
  • src/test/system_tests/test_s3_authentication.js
  • src/tools/md_blow.js
  • src/test/pipeline/quota_test.js
  • src/test/qa/agents_matrix.js
  • src/test/pipeline/namespace_test.js
  • src/test/external_tests/external_tests_utils.js
  • src/test/system_tests/test_md_aggregator.js
  • src/test/system_tests/test_cloud_pools.js
  • src/test/qa/rebuild_replicas_test.js
  • src/tools/rpc_shell.js
  • src/test/pipeline/system_config.js
  • src/tools/md_blow_lifecycle.js
  • src/test/system_tests/test_bucket_access.js
  • src/test/utils/server_functions.js
  • src/test/system_tests/test_bucket_placement.js
  • src/test/utils/basic_server_ops.js
  • src/test/utils/coretest/coretest.js
  • src/test/pipeline/account_test.js
  • src/tools/nbcat.js
  • src/test/pipeline/run_dataset.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/system_tests/sanity_build_test.js
  • src/test/system_tests/test_node_failure.js
  • src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js
  • src/test/qa/cloud_test.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
  • src/test/integration_tests/internal/test_system_servers.js
🧬 Code graph analysis (9)
src/test/system_tests/sanity_build_test.js (5)
src/agent/block_store_speed.js (3)
  • require (13-13)
  • require (14-14)
  • api (9-9)
src/server/common_services/auth_server.js (1)
  • require (7-7)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (4)
  • require (16-16)
  • require (17-17)
  • api (15-15)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (4)
  • require (5-5)
  • require (7-7)
  • api (4-4)
  • auth_params (38-38)
src/test/system_tests/test_cloud_pools.js (1)
  • auth_params (146-150)
src/test/system_tests/test_node_failure.js (1)
src/test/utils/basic_server_ops.js (4)
  • require (10-10)
  • client (136-138)
  • client (143-143)
  • auth_params (147-151)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (2)
src/server/common_services/auth_server.js (2)
  • require (7-7)
  • process (40-47)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/qa/cloud_test.js (4)
src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (3)
  • require (16-16)
  • require (17-17)
  • auth_params (39-39)
src/test/external_tests/external_tests_utils.js (3)
  • require (5-5)
  • require (7-7)
  • auth_params (38-38)
src/test/pipeline/account_test.js (1)
  • auth_params (305-310)
src/test/pipeline/namespace_test.js (1)
  • auth_params (281-285)
src/server/system_services/account_server.js (2)
src/server/system_services/system_server.js (3)
  • support_account (863-863)
  • system_store (32-32)
  • system_store (1188-1188)
src/server/system_services/stats_aggregator.js (5)
  • support_account (599-599)
  • support_account (1163-1163)
  • support_account (1200-1200)
  • support_account (1233-1233)
  • system_store (16-16)
src/test/integration_tests/nsfs/test_nsfs_integration.js (2)
src/test/integration_tests/internal/test_system_servers.js (3)
  • require (16-16)
  • coretest (6-6)
  • coretest (22-22)
src/test/utils/coretest/coretest.js (4)
  • rpc_client (87-90)
  • rpc_client (227-231)
  • rpc_client (413-413)
  • EMAIL (76-76)
src/cmd/backingstore.js (2)
src/cmd/api.js (1)
  • require (14-14)
src/server/common_services/auth_server.js (1)
  • process (40-47)
src/test/integration_tests/internal/test_system_servers.js (1)
src/test/utils/coretest/coretest.js (5)
  • rpc_client (87-90)
  • rpc_client (227-231)
  • rpc_client (413-413)
  • SYSTEM (75-75)
  • EMAIL (76-76)
src/server/common_services/auth_server.js (2)
src/server/system_services/account_server.js (5)
  • req (241-241)
  • req (539-539)
  • req (1353-1353)
  • system_store (18-18)
  • _ (5-5)
src/server/object_services/object_server.js (10)
  • req (631-631)
  • req (652-652)
  • req (695-695)
  • req (730-730)
  • req (749-749)
  • req (799-799)
  • req (901-903)
  • req (1838-1838)
  • system_store (31-31)
  • _ (7-7)
⏰ 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-package-lock-validation
  • GitHub Check: run-jest-unit-tests
🔇 Additional comments (8)
src/server/system_services/account_server.js (1)

1376-1376: verify_authorized_account unused—no call sites found
Ripgrep across src shows only its own definition and no invocations; restricting to operator only has no impact.

src/test/system_tests/sanity_build_test.js (1)

15-15: Switch to local token generation — LGTM

src/test/qa/cloud_test.js (1)

81-81: Import make_auth_token — LGTM

src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js (1)

17-17: Import make_auth_token — LGTM

src/test/system_tests/test_node_failure.js (1)

17-17: Import make_auth_token — LGTM

src/test/integration_tests/internal/test_system_servers.js (2)

16-16: Import looks right; path resolves correctly.


22-22: Good: removed PASSWORD from coretest destructuring.
Prevents stale references after password removal.

src/cmd/backingstore.js (1)

19-19: Sweep local-auth-token pattern across all CLI tools
Other command-line entrypoints also import and use make_auth_token (for example: src/cmd/api.js, src/agent/block_store_speed.js, and tools under src/tools/ such as rpc_shell.js, nbcat.js, md_blow.js, and md_blow_lifecycle.js). Apply the same local-token handling changes to each of these scripts.

const fs_utils = require('../util/fs_utils');
const nb_native = require('../util/nb_native');
const json_utils = require('../util/json_utils');
const { make_auth_token } = require('../server/common_services/auth_server');
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Do not import server-side token minting into a client CLI.
Pulling make_auth_token into CLI expands the trust boundary: anyone running this code can mint “admin” JWTs if the signing secret is bundled/available, bypassing server-side role checks. Replace with a server-issued flow (e.g., create_k8s_auth, a challenge/response, or a one-time bootstrap token), and keep signing keys server-only.

Would you like a proposal for a minimal bootstrap RPC (short-lived, single-use token) to replace this?

🤖 Prompt for AI Agents
In src/cmd/backingstore.js around line 19, the CLI imports the server-side
make_auth_token which allows local minting of privileged JWTs and expands the
trust boundary; remove this import and replace the client-side token generation
with a server-issued flow. Update the CLI to call a server endpoint (e.g.,
create_k8s_auth, a challenge/response, or request a one-time bootstrap token) to
obtain a short-lived token, ensure signing keys remain server-only, and wire the
CLI to use the server response for authentication instead of locally generating
tokens. Use an RPC that issues single-use, time-limited tokens or a bootstrap
handshake; add error handling for token requests and remove any references to
make_auth_token from the CLI code.

Comment on lines +105 to 109
client.options.auth_token = make_auth_token({
system: process.env.CREATE_SYS_NAME,
email: process.env.CREATE_SYS_EMAIL,
password: process.env.CREATE_SYS_PASSWD,
role: 'admin',
email: process.env.CREATE_SYS_EMAIL
});
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Client-minted admin token is a privilege-escalation vector.
Even with correct signing, authorize() currently trusts the embedded role string without verifying membership; any locally minted token with role: 'admin' will pass method checks. Avoid minting here; at minimum, validate required env vars and fail fast to avoid producing ambiguous tokens.

Apply basic guards:

-        client.options.auth_token = make_auth_token({
-            system: process.env.CREATE_SYS_NAME,
-            role: 'admin',
-            email: process.env.CREATE_SYS_EMAIL
-        });
+        const sys = process.env.CREATE_SYS_NAME;
+        const email = process.env.CREATE_SYS_EMAIL;
+        if (!sys || !email) {
+            throw new Error('Missing CREATE_SYS_NAME/CREATE_SYS_EMAIL for authentication. Refuse to mint local admin tokens.');
+        }
+        // TODO: Replace with server-issued auth (e.g., create_k8s_auth or a dedicated bootstrap flow).
+        // client.options.auth_token = <server_issued_token>;

I can sketch a secure bootstrap exchange for this command.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
client.options.auth_token = make_auth_token({
system: process.env.CREATE_SYS_NAME,
email: process.env.CREATE_SYS_EMAIL,
password: process.env.CREATE_SYS_PASSWD,
role: 'admin',
email: process.env.CREATE_SYS_EMAIL
});
const sys = process.env.CREATE_SYS_NAME;
const email = process.env.CREATE_SYS_EMAIL;
if (!sys || !email) {
throw new Error('Missing CREATE_SYS_NAME/CREATE_SYS_EMAIL for authentication. Refuse to mint local admin tokens.');
}
// TODO: Replace with server-issued auth (e.g., create_k8s_auth or a dedicated bootstrap flow).
// client.options.auth_token = <server_issued_token>;

Comment on lines +39 to 41
const auth_params = { email: process.env.email, system: 'noobaa', role: 'admin' };
client.options.auth_token = make_auth_token(auth_params);
} catch (err) {
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Local token generation is correct; sweep remaining password-based test code

Some test utilities still pass password in auth_params (see external_tests_utils.js). Please remove those remnants to align with passwordless auth.


🏁 Script executed:

#!/bin/bash
# Verify and list remaining password-based test code and removed RPCs
rg -nP --glob 'src/test/**' '\bauth_params\b.*password|create_auth_token' -C2
rg -nP '\bcreate_auth_token\b|\breset_password\b' src -C2

Length of output: 10686


Remove password‐based auth utilities
Delete the get_rpc_client_by_email_and_password function (lines 36–40) in src/test/external_tests/external_tests_utils.js, remove all password fields from auth_params in your tests, and update any calls to use passwordless token creation only.

🤖 Prompt for AI Agents
In src/test/external_tests/ceph_s3_tests/test_ceph_s3_config_setup.js around
lines 39–41 and in src/test/external_tests/external_tests_utils.js lines 36–40,
remove any use of password-based auth: delete the
get_rpc_client_by_email_and_password function from external_tests_utils.js
(lines 36–40), strip the password property from all auth_params objects in tests
(e.g., here build auth_params with only email/system/role), and update any call
sites to stop calling the removed function and instead rely on passwordless
token creation via make_auth_token(auth_params) (ensure
client.options.auth_token = make_auth_token(auth_params) remains and adjust
imports/uses accordingly).

replicas_in_tier = tier.chunk_coder_config.replicas;
files_bucket_tier = tier;
});
authenticate();
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest replacing this with async/await on the way. It will clear the confusion with the promises and what the functions return

@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch 2 times, most recently from 6054b43 to 5dba449 Compare September 8, 2025 15:15
@dannyzaken
Copy link
Member

@tangledbytes, hope I understand correctly, correct me if I got anything wrong

  1. There is no longer a way to authenticate using email and password.
  2. An auth token can be either created locally using the JWT secret or returned from create_system

What about the operator side? I see there are several calls to CreateAuthAPI
https://github.com/dannyzaken/noobaa-operator/blob/d20e8d888d86f795966844be176880d3db88279a/pkg/system/phase4_configuring.go#L156-L160
https://github.com/dannyzaken/noobaa-operator/blob/d20e8d888d86f795966844be176880d3db88279a/pkg/system/phase4_configuring.go#L219-L234
https://github.com/dannyzaken/noobaa-operator/blob/d20e8d888d86f795966844be176880d3db88279a/pkg/noobaaaccount/reconciler.go#L364-L368

@tangledbytes
Copy link
Member Author

@tangledbytes, hope I understand correctly, correct me if I got anything wrong

  1. There is no longer a way to authenticate using email and password.
  2. An auth token can be either created locally using the JWT secret or returned from create_system

What about the operator side? I see there are several calls to CreateAuthAPI https://github.com/dannyzaken/noobaa-operator/blob/d20e8d888d86f795966844be176880d3db88279a/pkg/system/phase4_configuring.go#L156-L160 https://github.com/dannyzaken/noobaa-operator/blob/d20e8d888d86f795966844be176880d3db88279a/pkg/system/phase4_configuring.go#L219-L234 https://github.com/dannyzaken/noobaa-operator/blob/d20e8d888d86f795966844be176880d3db88279a/pkg/noobaaaccount/reconciler.go#L364-L368

@dannyzaken you are right. The operator has some changes as well - not a lot actually, operator creates and is the owner of the JWT_SECRET so it is capable of create tokens itself if needed. I wanted to get this merged first then create operator PR and include new core image sha.

Signed-off-by: Utkarsh Srivastava <srivastavautkarsh8097@gmail.com>
@tangledbytes tangledbytes force-pushed the utkarsh/prune/password branch from 5dba449 to d759e90 Compare September 8, 2025 16:09
@tangledbytes tangledbytes merged commit 3afc81f into noobaa:master Sep 8, 2025
18 checks passed
nimrod-becker added a commit that referenced this pull request Sep 15, 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.

3 participants