docs: add ADR-0009 for Akrites CDP public API authentication (CM-1333)#4345
docs: add ADR-0009 for Akrites CDP public API authentication (CM-1333)#4345joanagmaia wants to merge 2 commits into
Conversation
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
PR SummaryLow Risk Overview The ADR records how Akrites will authenticate to CDP’s read-only public API: LFX Auth0 M2M with a dedicated resource server and This PR is documentation only; the described middleware, config, and Terraform changes are not in the diff. Reviewed by Cursor Bugbot for commit 31719fc. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Pull request overview
Adds a proposed ADR for Akrites machine-to-machine authentication to the CDP public API.
Changes:
- Defines the Auth0 token exchange and authorization flow.
- Outlines implementation across four affected repositories.
- Adds ADR-0009 to the ADR index.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
docs/adr/0009-akrites-cdp-public-api-authentication.md |
Documents the proposed authentication architecture and implementation plan. |
docs/adr/README.md |
Adds ADR-0009 to the index. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| expires. | ||
| 4. Attach Bearer token to all CDP requests via `Authorization` header. | ||
| 5. On `invalid_client`: discard cached key → re-read from vault → retry token | ||
| exchange once. LF rotates the keypair without notice. |
| | [ADR-0006](./0006-database-schema-types-as-source-of-truth.md) | Database schema types as the source of truth | accepted | 2026-07-09 | | ||
| | [ADR-0007](./0007-test-factory-primitives-and-defaults.md) | Test factory primitives and defaults | accepted | 2026-07-10 | | ||
| | [ADR-0008](./0008-how-we-write-unit-tests.md) | How we write unit tests | accepted | 2026-07-13 | | ||
| | [ADR-0009](./0009-akrites-cdp-public-api-authentication.md) | Akrites → CDP public API authentication | proposed | 2026-07-14 | |
| ```ts | ||
| export const AKRITES_AUTH0_CONFIG: Auth0Configuration = config.get<Auth0Configuration>('auth0Akrites') | ||
| ``` | ||
| `Auth0Configuration` interface (`backend/src/conf/configTypes.ts` lines 68–73) is reused as-is. |
| Note over Akrites,Auth0: Token exchange (repeated on expiry) | ||
| Akrites->>Akrites: sign client_assertion JWT (RS256) | ||
| Akrites->>Auth0: POST /oauth/token (client_credentials + jwt-bearer) | ||
| Auth0-->>Akrites: Bearer access_token (scope=read:<resource>) |
| CDP->>Auth0: fetch JWKS (cached) | ||
| CDP->>CDP: oauth2Middleware: verify sig + iss + aud | ||
| CDP->>CDP: azpAllowlistMiddleware: assert azp == AKRITES_CLIENT_ID | ||
| CDP->>CDP: requireScopes: assert read:<resource> |
| resource_server_identifier = auth0_resource_server.cdp_akrites_api.identifier | ||
| scopes { | ||
| name = "read:<resource>" |
| resource "auth0_client_grant" "akrites_cdp" { | ||
| client_id = auth0_client.m2m_clients["Akrites"].id | ||
| audience = auth0_resource_server.cdp_akrites_api.identifier | ||
| scopes = ["read:<resource>"] |
|
|
||
| Add to `SCOPES` const: | ||
| ```ts | ||
| READ_RESOURCE: 'read:<resource>', |
| '/akrites', | ||
| oauth2Middleware(AKRITES_AUTH0_CONFIG), | ||
| azpAllowlistMiddleware([AKRITES_AUTH0_CONFIG.clientId]), | ||
| requireScopes([SCOPES.READ_AKRITES], 'all'), |
| Akrites->>Auth0: retry token exchange once | ||
| ``` | ||
|
|
||
| ## Affected Repositories |
| Add to `SCOPES` const: | ||
| ```ts | ||
| READ_RESOURCE: 'read:<resource>', | ||
| ``` |
| oauth2Middleware(AKRITES_AUTH0_CONFIG), | ||
| azpAllowlistMiddleware([AKRITES_AUTH0_CONFIG.clientId]), | ||
| requireScopes([SCOPES.READ_AKRITES], 'all'), | ||
| akritesRouter(), |
| "auth0Akrites": { | ||
| "issuerBaseURLs": "CROWD_AUTH0_AKRITES_ISSUER_BASE_URLS", | ||
| "audience": "CROWD_AUTH0_AKRITES_AUDIENCE", | ||
| "clientId": "CROWD_AUTH0_AKRITES_CLIENT_ID" | ||
| } |
| **`backend/src/conf/index.ts`** (line 106) | ||
|
|
||
| Add: | ||
| ```ts | ||
| export const AKRITES_AUTH0_CONFIG: Auth0Configuration = config.get<Auth0Configuration>('auth0Akrites') | ||
| ``` |
| | [ADR-0006](./0006-database-schema-types-as-source-of-truth.md) | Database schema types as the source of truth | accepted | 2026-07-09 | | ||
| | [ADR-0007](./0007-test-factory-primitives-and-defaults.md) | Test factory primitives and defaults | accepted | 2026-07-10 | | ||
| | [ADR-0008](./0008-how-we-write-unit-tests.md) | How we write unit tests | accepted | 2026-07-13 | | ||
| | [ADR-0009](./0009-akrites-cdp-public-api-authentication.md) | Akrites → CDP public API authentication | proposed | 2026-07-14 | |
| 3. POST to Auth0 `/oauth/token` — cache the returned Bearer token until it | ||
| expires. |
Summary
auth0-terraform,lfx-secrets-management,crowd.dev, and Akrites (external)Context
Akrites is a new upstream consumer needing read-only CDP API access. This ADR formalizes the M2M auth strategy: dedicated Auth0 resource server,
read:akritesscope, and anazpallowlist middleware for single-consumer lockdown.🤖 Generated with Claude Code