@@ -1304,19 +1304,19 @@ replaced; do not carry obsolete compatibility code forward to satisfy this secti
13041304 attached Vault or anonymous MCP. Already-resolved tokens and running Sessions
13051305 are not revoked. Exact hosted archive, visibility, overlapping-mutation and error
13061306 semantics remain unverified; row removal does not prove physical storage erasure.
1307- - Static-bearer Credentials are children of tenant-owned Vaults in the execution
1307+ - Static-bearer and OAuth Credentials are children of tenant-owned Vaults in the execution
13081308 database. Creation admits the owner in the same SQL statement as the insert;
1309- retrieval joins the owning Vault and selects public metadata only. No public
1310- operation decrypts or returns a token . Encrypt before passing secret values to
1309+ retrieval joins the owning Vault and selects public metadata only. Public reads do not decrypt or return a token. OAuth replacement authenticates
1310+ the stored grant before applying a partial update . Encrypt before passing secret values to
13111311 SQL, using the execution service's separately configured random 32-byte key and
13121312 the standard library's random-nonce AES-GCM. The versioned authenticated binding
13131313 includes tenant, Vault, Credential, authentication purpose and exact destination.
13141314 Never reuse product master-key conventions or daemon transport encryption for
13151315 this storage boundary. Missing key configuration disables credential writes;
13161316 malformed explicit configuration fails startup. See
13171317 [ ` services/agents-api/credentials.md ` ] ( services/agents-api/credentials.md ) for
1318- key persistence and current limits. OAuth and storage -key rotation remain
1319- separate gaps ; resource creation never contacts the destination.
1318+ key persistence and current limits. Storage -key rotation remains
1319+ separate work ; resource creation never contacts the destination.
13201320- ` GET /v1/vaults/{vault_id}/credentials ` lists safe metadata only, with both
13211321 project and Vault ownership enforced on the parent, cursor and row query. An
13221322 inaccessible parent returns not-found, even when the collection would be empty.
@@ -1327,10 +1327,10 @@ replaced; do not carry obsolete compatibility code forward to satisfy this secti
13271327 Synthetic archived fixtures prove filtering only. There is no public archive writer,
13281328 timestamp or delete-to-archive inference; existing create/retrieve/token replacement,
13291329 Session bindings and dispatch keep their rules. Migration rollback refuses to lose
1330- archived classification. Archive/revocation lifecycle, OAuth and hosted
1331- query/concurrency semantics remain gaps.
1332- - Credential ` POST /v1/vaults/{vault_id}/credentials/{credential_id} ` replaces only
1333- the static-bearer token and update time. Require ` auth.type=static_bearer ` and a
1330+ archived classification. Archive lifecycle and hosted query/concurrency
1331+ semantics remain gaps.
1332+ - For static auth, Credential ` POST /v1/vaults/{vault_id}/credentials/{credential_id} `
1333+ replaces only the token and update time. Require ` auth.type=static_bearer ` and a
13341334 string ` auth.token ` , preserving opaque bytes; reject extra mutation fields before
13351335 writing. Reuse safe metadata for the immutable encryption binding, then scope the
13361336 atomic SQL mutation independently by tenant, Vault, Credential, static auth type
@@ -1340,7 +1340,29 @@ replaced; do not carry obsolete compatibility code forward to satisfy this secti
13401340 and Session snapshots stay unchanged. Subsequent dispatch reads use the committed
13411341 replacement through existing scoped lookup; already-resolved requests may retain
13421342 the old token. This is not storage-key rotation, in-flight revocation or hot reload.
1343- OAuth and exact hosted concurrent-update/retry/timestamp semantics remain gaps.
1343+ Exact hosted concurrent-update/retry/timestamp semantics remain gaps.
1344+ - OAuth grant ownership stays in Core. The application performs authorization and
1345+ provider revocation; do not add public login/callback/refresh/revoke routes.
1346+ Store access/refresh/client secrets together under existing authenticated tenant,
1347+ Vault, Credential, auth-type and destination encryption. Authenticate refresh
1348+ metadata against its encrypted copy before using an endpoint or grant. Read/list
1349+ queries still select safe metadata only. Shared MCP selection admits both auth
1350+ types and freezes one identity without changing native adapter contracts.
1351+ At dispatch, a known-expired grant is refreshed through the declared endpoint
1352+ auth method, with stored scope/resource, then persisted before returning access.
1353+ Serialize refresh and replacement with the same PostgreSQL Credential row lock;
1354+ deletion and Vault cascade cannot be undone by a stale refresh. Network exchanges
1355+ are bounded and fail closed; never return provider error bodies or claim an
1356+ uncertain grant exchange was committed. No background scheduler, 401 retry,
1357+ hot replacement, output repair or harness-specific OAuth path is introduced.
1358+ Refresh uses verified HTTPS, rejects redirects, and checks resolved addresses
1359+ before dialing them. Private issuer origins need explicit operator configuration
1360+ in ` AGENTS_API_OAUTH_TRUSTED_ORIGINS ` ; tenants cannot relax that boundary and TLS
1361+ verification remains mandatory. Keycloak is acceptance infrastructure only.
1362+ Preserve the pinned update omission/null and immutable-field rules described in
1363+ [ OAuth credentials] ( services/agents-api/oauth-credentials.md ) ; record unspecified
1364+ hosted semantics. Native processes receive only access tokens. Provider revocation,
1365+ withdrawal of already-dispatched tokens and Session cancellation remain distinct.
13441366- Credential ` DELETE /v1/vaults/{vault_id}/credentials/{credential_id} ` removes one
13451367 owned row, including ciphertext, with tenant/Vault/ID checked in the same SQL
13461368 mutation. It needs no encryption key, secret read or network call. Local reads,
@@ -1387,7 +1409,7 @@ replaced; do not carry obsolete compatibility code forward to satisfy this secti
13871409 pinned resource types. Saved-Agent updates never change existing Session
13881410 snapshots; per-Session tools replace the whole field. The initial profile admits
13891411 HTTP(S), boolean ` required ` (default false), empty/null metadata and empty/null headers.
1390- Static bearer authentication requires HTTPS and the attached-Vault rules below.
1412+ Static and OAuth bearer authentication require HTTPS and the attached-Vault rules below.
13911413 Inline authorization, URL userinfo/query/fragment,
13921414 other origins and stdio remain explicitly unsupported.
13931415- Codex required MCP initialization additionally needs ` mcp_http_required ` , advertised
@@ -1426,19 +1448,19 @@ replaced; do not carry obsolete compatibility code forward to satisfy this secti
14261448 with TLS verification.
14271449 This execution profile rejects empty values and bytes outside RFC 6750 b64token
14281450 syntax with generic errors; it never trims tokens or narrows opaque Credential
1429- storage. OAuth and hosted redirect/error equivalence
1430- remain separate work.
1451+ storage. Core-managed OAuth uses this same access-token path; native OAuth
1452+ login/refresh and hosted redirect/error equivalence remain separate work.
14311453- Session ` vault_ids ` omission/null/empty means ` [] ` ; nonempty attachments must all
14321454 belong to the authenticated tenant. Preserve caller order and public MCP
14331455 ` credential_id ` . Saved Agents may store a nullable/nonempty credential reference
14341456 without authorizing its use. Session admission resolves an explicit credential
14351457 only inside attached Vaults for the exact declared URL, or selects the unique
1436- matching static credential when the ID is omitted/null. No match remains
1458+ matching static or OAuth credential when the ID is omitted/null. No match remains
14371459 anonymous; ambiguity is a local 400 and unavailable references use the same 404.
14381460 Resolve before any Session, initial input or event write. Freeze safe bindings,
14391461 including anonymous decisions, in private Session configuration; never populate
14401462 the public credential field from implicit resolution. At actual dispatch, recheck
1441- tenant, attached Vault, selected ID, static auth type and exact URL before scoped
1463+ tenant, attached Vault, selected ID, frozen auth type and exact URL before scoped
14421464 decryption. Metadata queries select no ciphertext; tokens enter only the existing
14431465 transient daemon request. Selected authentication requires ` mcp_http_bearer_auth `
14441466 during device selection and the final preclaim check. Missing/wrong keys or
0 commit comments