Skip to content

KMS-690: Fix KMS authorizer handling of EDL level 5 bearer tokens created through the EDL "Generate Token" flow.#116

Merged
cgokey merged 7 commits into
mainfrom
KMS-690
Jul 8, 2026
Merged

KMS-690: Fix KMS authorizer handling of EDL level 5 bearer tokens created through the EDL "Generate Token" flow.#116
cgokey merged 7 commits into
mainfrom
KMS-690

Conversation

@cgokey

@cgokey cgokey commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Overview

What is the feature?

Fix KMS authorizer handling of EDL level 5 bearer tokens created through the EDL "Generate Token" flow.

What is the Solution?

This updates bearer-token validation in fetchEdlProfile so KMS no longer relies on GET /oauth/userInfo for bearer tokens. Instead, it:

  • validates bearer/user tokens with POST /oauth/tokens/user
  • authenticates that validation call with Authorization: Basic <EDL_CLIENT_ID:EDL_PASSWORD>
  • decodes the JWT locally to read assurance_level
  • keeps the existing Launchpad token flow unchanged
  • adds EDL_CLIENT_ID to Bamboo/CDK/runtime wiring

What areas of the application does this impact?

  • EDL authorizer bearer-token validation
  • Bamboo/CDK runtime env wiring for EDL_CLIENT_ID
  • Unit tests for fetchEdlProfile and authorizer behavior
  • Deployment documentation in README.md

Testing

  1. Add bamboo_EDL_CLIENT_ID to Bamboo and deploy this branch. (done)
  2. Call a protected KMS endpoint with an MMT-generated level 5 bearer token and verify access is still allowed.
  3. Call the same protected KMS endpoint with an EDL-generated level 5 user token (Bearer <token>) and verify access is allowed.
  4. Confirm the authorizer no longer fails on the EDL-generated token with Unauthorized / 403.

I ran:

KMS_AUTHORIZATION="Bearer ..." ALLOW_MUTATING_CORRECTION_ENDPOINT=true ./scripts/local/find_collection_with_positive_manual_sync_result.mjs sit dif10 AMD_KOPRI

which requires authentication and should work with both tokens (MMT generated one and EDL generated one)

Checklist

  • I have added automated tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings

Summary by CodeRabbit

  • New Features

    • Improved EDL bearer-token handling to validate tokens through the service’s token endpoint and return richer profile details.
    • Added support for a new required EDL client ID setting across deployment and runtime configuration.
  • Bug Fixes

    • Updated profile lookup behavior and error handling for invalid tokens, missing configuration, and malformed validation responses.
    • Adjusted offline and Launchpad-related profile requests to use the correct EDL host in tests and deployment flows.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7c9b90c3-d771-4711-8f89-01f44daa5689

📥 Commits

Reviewing files that changed from the base of the PR and between a43159a and c6ca697.

📒 Files selected for processing (2)
  • serverless/src/edlAuthorizer/__tests__/handler.test.js
  • serverless/src/shared/__tests__/fetchEdlProfile.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • serverless/src/shared/tests/fetchEdlProfile.test.js

📝 Walkthrough

Walkthrough

This PR replaces the EDL bearer-token profile lookup with a token-validation flow calling POST /oauth/tokens/user using new Basic auth and JWT-claim-decoding helpers, requiring EDL_CLIENT_ID/EDL_PASSWORD. Deployment scripts, CDK stacks, and README are updated to propagate EDL_CLIENT_ID. Tests are updated accordingly, plus a minor authorizer test logging spy addition.

Changes

EDL bearer token validation

Layer / File(s) Summary
Deployment config for EDL client id
README.md, bin/deploy-bamboo.sh, cdk/app/lib/KmsStack.ts, cdk/app/lib/helper/KmsLambdaFunctions.ts, cdk/bin/main.ts
Adds EDL_CLIENT_ID as a required environment variable across deployment docs, scripts, and CDK stack/lambda environment typings and wiring.
Bearer token validation and claims decoding
serverless/src/shared/fetchEdlProfile.js
Adds buildBasicAuthorizationHeader and decodeJwtClaims helpers, and rewrites fetchProfileWithEdlAccessToken to validate tokens via POST /oauth/tokens/user with Basic auth, verify profile.uid, and build the returned profile from validation data and decoded JWT claims.
Bearer token tests
serverless/src/shared/__tests__/fetchEdlProfile.test.js
Updates tests to build synthetic JWT tokens, mock EDL host config, assert the new token-validation request/response handling, add missing-config and malformed-payload error tests, and align Launchpad/offline URL expectations with the mocked host.
Authorizer logging test setup
serverless/src/edlAuthorizer/__tests__/handler.test.js
Adds a logger.info spy alongside the existing logger.error spy in test setup and teardown.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant fetchEdlProfile
  participant EDLTokenEndpoint

  Client->>fetchEdlProfile: request profile with bearer token
  fetchEdlProfile->>fetchEdlProfile: check EDL_CLIENT_ID / EDL_PASSWORD present
  fetchEdlProfile->>EDLTokenEndpoint: POST /oauth/tokens/user (Basic auth, client_id, token)
  EDLTokenEndpoint-->>fetchEdlProfile: validation response (profile.uid)
  fetchEdlProfile->>fetchEdlProfile: decodeJwtClaims(token)
  fetchEdlProfile-->>Client: { name, uid, assuranceLevel }
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: updating KMS authorizer handling for EDL bearer tokens from the Generate Token flow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch KMS-690

Warning

Tools execution failed with the following error:

Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error)


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.

@codecov-commenter

codecov-commenter commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.82%. Comparing base (338fc77) to head (c6ca697).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #116   +/-   ##
=======================================
  Coverage   99.82%   99.82%           
=======================================
  Files         225      225           
  Lines        5582     5599   +17     
  Branches     1603     1600    -3     
=======================================
+ Hits         5572     5589   +17     
  Misses         10       10           

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
serverless/src/edlAuthorizer/__tests__/handler.test.js (1)

11-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

loggerInfoSpy is created/restored but never asserted on.

The spy only suppresses logger.info noise during tests; none of the new logger.info calls added in handler.js (request received, resolved token, retrieved profile, authorization successful) are verified. Consider adding at least one assertion (e.g., on the success path) to lock in the new structured info-logging behavior.

Also applies to: 33-33

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

In `@serverless/src/edlAuthorizer/__tests__/handler.test.js` around lines 11 - 15,
The new logger.info spy in edlAuthorizer handler tests is only being used to
silence output and is never verified, so the structured info logging in
handler.js is not covered. Add at least one assertion in the success-path tests
using loggerInfoSpy to confirm the expected info log calls (for example, request
received, token/profile handling, or authorization success), and keep the spy
setup/restore around those handler tests.
serverless/src/edlAuthorizer/handler.js (1)

40-57: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor: tokenType can report 'bearer' while tokenPresent is false.

If the header is "Bearer " (whitespace-only after the scheme), bearerMatch succeeds so tokenType is set to 'bearer', but tokenValue trims to empty, so tokenPresent is false. Logs would then show a contradictory { tokenType: 'bearer', tokenPresent: false }. Purely cosmetic for logging purposes, but worth tightening.

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

In `@serverless/src/edlAuthorizer/handler.js` around lines 40 - 57, The token
summary in summarizeTokenForLogs can produce inconsistent log output because
bearerMatch sets tokenType to bearer even when the trimmed tokenValue is empty.
Update the tokenType assignment so it only reports bearer when tokenValue is
actually present, and otherwise keep missing when the header is empty or
whitespace-only. Keep the behavior of tokenPresent and tokenLength aligned with
tokenType so logs from summarizeTokenForLogs stay consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@serverless/src/edlAuthorizer/handler.js`:
- Around line 59-71: The “redacted” profile summary in summarizeProfileForLogs
still exposes raw uid and auid values, so update this helper in handler.js to
avoid logging sensitive identifiers directly. Either remove uid/auid from the
returned summary or replace them with a masked/truncated/hashed representation,
and make sure all call sites that log the summary on deny/error/success paths
continue using the sanitized output.

In `@serverless/src/shared/fetchEdlProfile.js`:
- Around line 158-163: The assurance level is currently being read from
decodeJwtClaims(edlToken), which relies on the access token and not a trusted
server-side source. Update fetchEdlProfile to get assuranceLevel from the
backend-validated profile or token-validation response already associated with
profile, and remove the dependency on decoding the EDL token for this field.

---

Nitpick comments:
In `@serverless/src/edlAuthorizer/__tests__/handler.test.js`:
- Around line 11-15: The new logger.info spy in edlAuthorizer handler tests is
only being used to silence output and is never verified, so the structured info
logging in handler.js is not covered. Add at least one assertion in the
success-path tests using loggerInfoSpy to confirm the expected info log calls
(for example, request received, token/profile handling, or authorization
success), and keep the spy setup/restore around those handler tests.

In `@serverless/src/edlAuthorizer/handler.js`:
- Around line 40-57: The token summary in summarizeTokenForLogs can produce
inconsistent log output because bearerMatch sets tokenType to bearer even when
the trimmed tokenValue is empty. Update the tokenType assignment so it only
reports bearer when tokenValue is actually present, and otherwise keep missing
when the header is empty or whitespace-only. Keep the behavior of tokenPresent
and tokenLength aligned with tokenType so logs from summarizeTokenForLogs stay
consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4c569630-734b-4ee5-bc7e-a07fd28416b7

📥 Commits

Reviewing files that changed from the base of the PR and between 338fc77 and 69432f0.

📒 Files selected for processing (4)
  • serverless/src/edlAuthorizer/__tests__/handler.test.js
  • serverless/src/edlAuthorizer/handler.js
  • serverless/src/shared/__tests__/fetchEdlProfile.test.js
  • serverless/src/shared/fetchEdlProfile.js

Comment thread serverless/src/edlAuthorizer/handler.js Outdated
Comment thread serverless/src/shared/fetchEdlProfile.js
@cgokey cgokey changed the title Kms 690 KMS-690: Fix KMS authorizer handling of EDL level 5 bearer tokens created through the EDL "Generate Token" flow. Jul 7, 2026
Comment thread serverless/src/shared/__tests__/fetchEdlProfile.test.js
Comment thread serverless/src/shared/__tests__/fetchEdlProfile.test.js Outdated
@cgokey cgokey merged commit 0c0d3df into main Jul 8, 2026
6 of 7 checks passed
@cgokey cgokey deleted the KMS-690 branch July 8, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants