Fresh authentication for one release gate exception
CCP-082 source contract, under qualification. This document does not authorize an account, client permission, provider activation, factor or key enrollment, artifact publication, or deployment. Normal Console login requests no release:gate-bypass scope. The operation flow uses the current Authority role resolution and the existing enrolled operator decision key.
Verified source: f48729a6a96be99687530c55021b119367aaa92d. Re-verify the owner flow with pwsh tools/scripts/test-targeted-xunit.ps1 -Project src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj -Class "*ReleaseGateOperationFlowTests" -BuildProjectReferences and the atomic owner path with the Release Orchestrator integration project’s ReleaseGateOperationPersistenceTests. These isolated tests do not qualify live identities, factors, configured providers or an enrolled key.
Operation flow
- A signed-in security risk manager selects a blocked gate, a time limit of 1–365 days, a justification and explicit risk acknowledgment. The Console opens a separate authentication window and keeps its PKCE verifier in the originating tab’s memory. The gate form supports time-limited exceptions only. Conditional/permanent modes and attachment uploads are unavailable in this owner submission contract.
POST /connect/release-gate-exception/startvalidates the authenticated actor, tenant and client, the canonical registered authorization-code grant and scope ceiling, and the exact registered redirect URI. An administrator role alone does not substitute for the security risk manager role.- Authority resolves the configured OIDC provider and requests authorization code authentication with PKCE S256, state, nonce,
prompt=login,max_age=0and its canonical MFA assurance value. The requested assurance is not proof. GET /connect/release-gate-exception/callbackconsumes the protected pending transaction before exchanging the code with that provider. The production OIDC adapter verifies the ID token’s signature, issuer, audience, authorized party, nonce, subject, signed tenant and actual authentication time/methods. Missing, stale, future or pre-challenge authentication refuses the operation.- A second protected, one-time continuation resumes the original Authority authorization request at the registered public
/connect/authorizeendpoint. Missing registration refuses the continuation; another authorization endpoint is not a fallback. The ordinary authorization-code token exchange checks the originating client’s PKCE verifier. It issues onlyopenidandrelease:gate-bypass, with no refresh token. - The Console keeps that token in memory, reads the current approval and gate again, obtains the owner’s exact signing payload, and asks the operator to confirm. It signs the returned PAE bytes using the existing enrolled key. Only the prepare and exact gate-exception submit requests receive operation authority. Cancellation, navigation, actor/tenant change or expiry discards it.
- Release Orchestrator reconstructs the expected signed predicate from its current approval and gate, validates the operation and enrolled signature, and atomically compares and updates the pending approval. The existing approval action records the operation nonce. This does not approve or deploy the release. A requester cannot grant their own gate exception.
Required configuration and identity
Authority:GateException:OidcProvider names an existing trusted OIDC provider registration. It is not supplied by the caller. The provider must support authorization codes and have issuer, audience and lifetime validation enabled. Its configured redirect URI must equal the Authority issuer’s /connect/release-gate-exception/callback URI. Provider discovery and code exchange use its existing configured client identity and credentials; credentials remain in operator-managed configuration and are never entered into this flow.
The supported proof uses acr=urn:stellaops:acr:mfa and actual amr methods pwd and otp; the additional mfa marker is accepted but cannot replace those methods. Unknown method/assurance vocabulary fails closed. Provider role mapping must resolve the authenticated user to the existing security risk manager role. The ID token must contain the canonical signed stellaops:tenant matching the original session. A requested tenant cannot fill in a missing signed tenant.
Provider integration rules (verified against 3e4cc9b5bd):
- The upstream identity is linked by subject, not by username. The ID token
sub, which must also equal the provider’s configured subject claim, must be the Authority subject of the signed-in actor. - The OIDC adapter keeps only the upstream roles listed in
roleMapping.mappingsunlessincludeUnmappedRolesis set. Map the provider’s role torole/security-risk-manager; roles are read from the configured role claim types (defaultroles,role,groups). - A provider without a configured client secret is used only when its discovery document lists
noneintoken_endpoint_auth_methods_supported. Otherwise configure a confidential client;client_secret_basicis used when the provider lists it. - The adapter uses
clientSecretas a literal value and does not resolveenv:,file:,vault:orsecret:references, while the global identity-provider admin API acceptsclientSecretonly as such a reference. Supply a confidential provider’s secret in the provider’s mounted descriptor configuration file. - The provider must be loaded from a mounted, signed OIDC provider bundle whose adapter implements this operation. An adapter without it refuses with
operation_identity_provider_unsupported.
The source client-ceiling proposal is to permit authorization_code, openid and release:gate-bypass for the already selected Console client and its exact registered callback. This is a ceiling for the separate operation only, not a change to normal login’s requested scopes. Applying that permission or activating the provider requires separate operator authorization.
Binding and custody
The signed access token binds the actor, client, tenant, release ID, approval ID, gate ID, exception kind, duration, condition, justification, risk acknowledgment and an unpredictable operation nonce. Its binding JSON is carried in stellaops:release_gate_operation; the canonical-field digest is carried in stellaops:release_gate_operation_digest. The digest uses the configured central SHA-256 interoperability purpose, and a conflicting purpose algorithm refuses. The canonical digest also binds the contract version. Challenge, grant and operation-expiry claims accompany the actual auth_time, acr, amr, token ID, issue time and expiry.
No operation lasts more than 300 seconds from its challenge or authenticated instant. Whole-second auth_time is compared against a challenge rounded upward, so an authentication that cannot prove it occurred after the challenge must be repeated. The upstream token’s shorter lifetime also limits the operation.
Pending PKCE verifier and verified continuation payloads are encrypted by the configured OpenIddict request-token JWE pipeline and retained in the existing Authority oidc_tokens.payload. Protected claims bind their purpose, token ID, actor, client and tenant. Existing token-store atomic redemption and expiry are used; no new token table, repository, key or protected encoding is introduced. The pending and verified purposes are distinct. Loss of the configured encryption key makes retained state unusable; there is no plaintext recovery fallback. These rows remain operational credential state under the existing Authority retention contract: known-expired rows are eligible thirty days after their recorded expiry, and valid or unknown-expiry rows are preserved. The existing one-million-row capacity budget and Doctor checks still apply; the five-minute operation lifetime is an authorization boundary, not an immediate deletion rule.
Release Orchestrator retains the nonce and signed decision in its existing approvals.approval_json and decision_envelope homes. The dedicated envelope column retains JSONB semantics. The gate’s recorded exception also retains the original envelope string, token ID, client, operation digest and prior gate status. No additional ledger or historical-row conversion is required. The final write checks database time for both operation and approval expiry, current owner queue state, the exact locked approval snapshot, and prior consumption of the nonce. The existing approval capacity guardrails remain 64 MiB, 100,000 rows and 1 MiB/day. Additional operation history does not increase those budgets.
Refusal and recovery
Password, client-credentials and refresh grants cannot issue an unbound bypass. Current client tenant assignments and tenant availability are checked again at continuation and code issuance. Removing assignments does not permit all tenants. A cancelled or failed upstream exchange consumes its pending state. Start a new operation after correcting the reported provider, permission or identity issue. Do not paste a token or an authentication assertion into the Console. An expired ordinary session without a usable refresh token must sign in again. The Console reports Authority authentication refusals separately from failures of the later Release Orchestrator prepare or submission request.
A changed approval/gate, consumed operation, expired authorization or invalid signature records no exception. Read the current approval before starting again. For a new mutation, Release Orchestrator resolves the configured issuer through the authenticated IssuerDirectory read contract and the request tenant through the existing canonical tenant resolver. The returned canonical issuer and tenant must match the key record; comparing a configured slug directly to an owner UUID is not sufficient. The key must belong to the signing subject, be active and approved, and be valid at admission time. A recently revoked, retired or expired key cannot authorize a new mutation merely because it was valid at the signed decision’s earlier time. This request-side admission check does not change the shared verifier’s historical signature-validation contract. A failed submission with an unknown transport outcome is not retried automatically: inspect the existing action history first. Database write failure rolls back the update; a commit followed by a failed response may already have recorded the action. An existing signed exception cannot be renewed on the same approval, including after it expires.
Source tests and isolated browser/provider fixtures are qualification evidence. Live CA-05 acceptance still requires the separately approved non-admin identity, trusted MFA provider, exact client ceiling, existing enrolled decision key, compatible Authority/Web/Release Orchestrator candidates and real tenant scenario.
