Run bounded authentication tests
This source adds a custom Atlas test-session broker. It is dormant until a separately approved TEST_SESSION_POLICY activation. It uses GitHub OIDC assertions for real GitHub Actions workloads and a custom human-approved session grant for other interactive clients. It is not an OAuth server or an implementation of RFC 8628. No workload identity capability is claimed for the dot browser.
Prepare the exact scope
Keep human sign-in, test runner and release operator identities separate. A test credential cannot acquire owner, platform-superadmin, deployment, delegated-token or standing internal human authority. The release operator signs in independently. Do not add platform privileges to hello@forth.ai or move credential files.
Immutable organisation IDs are enforced server-side: staging permits for-dev and uat-org; production permits only uat-org. Display names never authorize access. Every target must already have an active atlas_people membership with an explicit matching role_override; an owner or platform-roster principal cannot be a test target. Tenant role permissions are capped by role defaults and current organisation grants.
Activation handoff (not executed)
- The existing release coordinator reviews the exact PR/source and independently verified service matrix. Deploy every affected consumer of
@atlas/corebefore enabling issuance, including Auth, CRM, Agent, Tasks, EKB, Governance and legacy Knowledge if used. A stale worker cannot enforce the new grant. - Separately approve and apply only additive Auth migration
0024_test_session_grants.sqlto the exact shared session database. Retain audit/replay records; do not replay historical seed migrations. - Approve existing synthetic test principal memberships and exact role overrides separately. This source creates no accounts, memberships, keys, grants or real tokens.
- Approve each exact
TEST_SESSION_POLICYvalue for its environment through the registered Auth configuration/publication procedure. Record its exact issuer/audience/subject, immutable repository and owner IDs, workflow/ref/environment, human approvers and target tuples. No wildcard trust. Repository subject formats vary; copy the reviewed real subject, do not assume the older name-based format. - Only a real workload-capable runner obtains the OIDC assertion. Its reviewed workflow requires the provider's appropriate OIDC permission and environment protection. No workflow or trust relationship is configured here. Run the acceptance matrix below before any production enablement; production requires its own exact approval.
Policy fields
The existing Auth authority manifest includes the exact TEST_SESSION_POLICY bytes whenever present; issuance requires matching registered readiness and refuses pending, missing or mismatched registration. When absent, the existing four-field descriptor is preserved.
The issuer and JWKS URL are fixed to https://token.actions.githubusercontent.com and /.well-known/jwks. The verified algorithm is RS256. Policy fields are audience, subject, repositoryId, repositoryOwnerId, workflowRef, ref, workloadEnvironment, humanApprovers, and targets. Each target has exactly its approved key, email, orgId, role (rep, manager or admin). Workflow must be in Forth-AI/atlas-agentics at the approved branch ref; workload environment equals deployment environment. Unknown/missing/unreadable policy, primary store or rate limiter fails closed.
Establish the browser session
Use the trusted adapter tools/test-session/browser-session.ts in the test runner process. Its getWorkloadAssertion(audience) callback comes from the actual supported runtime. Its browserRequest is Playwright's BrowserContext.request, which shares that context's cookie jar. It returns no credential. Keep network traces, storageState and screenshots containing privileged content out of model-facing output. Never commit Playwright authentication state.
| Request | Authority and body |
|---|---|
POST /auth/test-sessions/workload | OIDC Bearer assertion in header, no Cookie or Origin; JSON {challenge}. Challenge is base64url SHA-256 of a random 32-byte runner verifier. Validates issuer, signature, single audience, subject, immutable repository/owner IDs, workflow, ref, environment, iat/nbf/exp and persistent unique jti. Maximum assertion age 5 minutes, lifetime 10 minutes. |
POST /auth/test-sessions/approve | Existing authenticated human, same-origin Origin, JSON {approve:true,challenge}. Exact configured human approver, current admin/owner membership in the same approved test organisation as every target. Platform/test credentials refused. This explicit human-approved POST is a custom grant; no automatic approval or CI identity substitution. |
POST /auth/test-sessions/exchange | Same-origin Origin, JSON {grant_id,exchange_code,verifier,target}. Grant creation returns these first two sensitive values over HTTPS to the trusted process. Exchange is proof-bound, expires in 60 seconds and can succeed once, including concurrent attempts. It sets an HttpOnly, SameSite=Lax, Secure atlas_session cookie and returns only {ok:true}. |
GET /auth/me | Returns effective identity, test environment, originating actor and configured target choices. Test sessions cannot enter normal Auth org-switch, account vault, delegation or platform routes. |
POST /auth/test-sessions/switch | Same-origin test cookie; {target} selects only a stored target key. Atomically retires the previous session, rotates sid and preserves the original grant expiry. |
POST /auth/test-sessions/revoke | Same-origin test cookie; {} revokes the whole grant and every associated test session. Current-only POST /auth/logout or POST /auth/accounts/logout instead revokes only the current test session. |
All writes require JSON and HTTPS, reject query parameters, and share a fail-closed limit of 10 requests per client per minute. Body maximum is 24 KB. Bearer credentials never travel in URLs or logs. Grant life is 15 minutes, with no refresh or extension on switching. Ordinary business tenants are inaccessible even if a caller supplies their IDs. Every service checks live grant, exact session identity, membership, role, permission ceiling, organisation suspension and runtime environment. Grant/store failure refuses access.
Grant and session rows separate originating actor from effective email/role/organisation; correlate an effect's session ID through atlas_test_sessions to its grant. Do not mislabel effective test identity as the human approver or release operator.
Refusals and current limits
401 invalid assertion/session; 403 scope, proof, CSRF or membership refusal; 409 replay/session changed; 429 missing/unavailable/exhausted limiter; 503 disabled policy or unavailable storage. No exception text or token is logged. A consumed exchange followed by a storage failure requires a new grant; replay never recovers it. There is no public global login-as endpoint.
Direct cookie-backed service paths and explicitly mapped short-lived action assertions to CRM, Tasks and EKB enforce the live grant. Assertion receivers must opt in with their primary session database and runtime environment; other receivers fail closed. Revoke-during-dispatch refuses an already signed assertion. Persistent delegation, policy proof, team human authority and integrations authority still refuse test sessions: these are human or standing-authority workflows, not test identity elevation. Their test acceptance remains outside this broker until separately scoped adapters exist.
Acceptance and rollback
Offline evidence uses only synthetic RSA keys, mocked JWKS and local SQLite/D1, plus browser transport/session tests. Before activation: prove the exact deployed SHA of all consumers, negative business-tenant tests for every service API, wrong issuer/audience/repository/workflow/environment, rotated/unknown keys, expiry, replay/concurrent exchange/switch, stolen code without verifier, CSRF, revoked/suspended/demoted principal, missing store/limiter, actor attribution, visible EN/中文 test labels at desktop and 390 px, unsent-work handling, cross-tab requests, browser Back, logout/current/grant-all and fixture cleanup. No paid services or real grants were provisioned for source tests.
Rollback: first revoke active grants (current test session's revoke action or separately approved exact database operation), then remove policy to stop issuance through registered release configuration. Policy removal alone does not revoke existing grants. Retain tables and replay/audit records. Old fixed-code mechanisms remain unchanged; retiring them is a separately approved rollout only after replacement acceptance passes. UAT cleanup belongs to the coordinated cleanup owner; this source performs no live deletion.
Protocol references
GitHub OIDC · Playwright authentication · OAuth device authorization standard. The standard explains the alternative protocol; Atlas's custom approval endpoint does not claim standards compliance.