Skip to content

ADR-0011: Credentials and sign-in sessions

Status: Accepted — 2026-09-23. The project owner approved this decision. Acceptance establishes the architectural contract; it does not establish a completed implementation or successful execution of outstanding checks.

Accepted refinement — 2026-09-24: credentials, subject identity, acting-client identity and task authority remain separate across CLI, MCP and delegation. The original acceptance date, authentication horizons and outstanding checks are unchanged.

English | Русский

ADR-0005 gives identity, authorization and discovery separate roles behind a trusted core boundary. ADR-0007 also needs credentials for approved artifact sources. Their protected references need one meaning across branded CLIs, several running CLI processes, user accounts and noninteractive service identities. A successful login, a usable API token and permission for an action are different facts.

ADR-0003 authenticates possession of an invocation’s private process channel. Its IPC session is not a sign-in session and conveys no general credential authority. ADR-0002 keeps identity in the core, and ADR-0004 already stops new protected actions after cancellation or finalization. Credential use must compose with those boundaries.

The public baseline in ADR-0009 needs neither organizational sign-in nor a credential store. This ADR defines the additional contract when a selected identity, service or registry integration needs secrets. ADR-0012 separately defines access-decision validity; this record does not classify extensions by connectivity or authorization frequency.

  • Keep login and general service/registry credentials inside trusted core integrations.
  • Preserve exact authority, account, target and owner configuration bindings without accidental sharing between CLIs.
  • Support OS-protected persistence and an explicit process-only mode through portable registered adapters.
  • Serialize renewal and invalidation across cooperating processes, including crashes, rotated refresh tokens and late replies.
  • Make local logout durable and honest about failed deletion, unavailable storage and remote revocation.
  • Support user sign-in and explicitly configured noninteractive service identities without hidden interaction.
OptionBenefitLimitation
Credentials in each extension or its environmentSimple direct API callsExposes general authority and duplicates account, renewal and revocation rules
Automatic plaintext fallback when a secure store is absentWorks in minimal environmentsSilently changes persistence and secret protection
One encrypted file with a secret bundled into the CLIUniform storage formatA distributed client secret does not establish a protected storage boundary
OS-protected adapters with only per-process locksUses platform storageConcurrent CLIs can reuse rotating refresh tokens or publish after logout
Core-owned credential contract, protected adapters and one durable coordinatorExplicit scope, rotation and invalidation across CLI instancesRequires crash-consistent metadata, platform capability checks and recovery tests

The core owns sign-in sessions and general identity, service and registry credentials. Trusted registered adapters implement secret storage and authentication. Persistent sessions use a shared local coordinator for atomic metadata transitions; process-only storage is an explicit choice. Extensions receive scoped service results or separately authorized limited credentials, never the general credential-store interface.

ADR-0010 defines registration in the branded CLI. The owner selects a credential namespace, approved connection profiles, storage adapter, authentication adapters and capabilities at composition/configuration time. A descriptor, catalog, extension message or provider response cannot install an adapter, select a storage backend or change the namespace. The store is a library responsibility; a separate credential daemon is not required.

ModeSelected behavior
persistentStore secret payloads through a registered OS-protected adapter; maintain durable session fences and references in the coordinator shared by this OS account and exact owner namespace. This is the default for profiles requiring persistence.
volatileKeep secrets, sessions and coordination only in the current core process. Explicit owner-approved selection is required before authentication; status shows the process-only lifetime. Nothing can resume that session after process exit or through another CLI process.
No credentials requiredUse the explicit local principal and public/local policy. Do not initialize storage or request login merely to display help or use this baseline.

Persistent adapters may use Windows Credential Manager, macOS Keychain or an approved Secret Service implementation on a supported desktop. These facilities have different availability, item-size, unlock and access-control behavior; a registered adapter advertises its actual capabilities. Their existence does not establish a common transaction or application-isolation guarantee. Windows credential writes, Apple Keychain services, Secret Service access-control limits.

An unsupported, locked or unavailable persistent store returns a typed error. No automatic plaintext file, environment export, alternate OS account, arbitrary helper or volatile fallback is allowed. An explicitly selected volatile attempt uses a fresh session and cannot import an inaccessible persistent session. Unlock interaction follows the activity’s declared interactive mode; noninteractive use cannot unexpectedly open an OS prompt.

The selected view separates secret use from extension-facing operations; arrows do not imply separate processes.

Accepted credential ownership boundary
Accepted credential ownership boundaryExtensions request scoped core operations. Trusted identity, service and source adapters obtain request-bound credential use through the core coordinator. The coordinator maintains session fences and delegates secret payload storage to the selected protected or explicit volatile adapter.Command extensionCore action boundaryTrusted identity, service orsource adapterCredential and sessioncoordinatorProtected storage or explicitvolatile storageIdentity provider, service orregistryScoped operation requestValidated context and permittedtargetRequest-bound credential usePublished secret referenceCurrent session epochApproved target onlyAccepted credential ownership boundaryExtensions request scoped core operations. Trusted identity, service and source adapters obtain request-bound credential use through the core coordinator. The coordinator maintains session fences and delegates secret payload storage to the selected protected or explicit volatile adapter.Command extensionCore action boundaryTrusted identity, service orsource adapterCredential and sessioncoordinatorProtected storage or explicitvolatile storageIdentity provider, service orregistryScoped operation requestValidated context and permittedtargetRequest-bound credential usePublished secret referenceCurrent session epochApproved target only

Logical keys, records and principal bindings

Section titled “Logical keys, records and principal bindings”

These logical types are independent of the chosen SDK language and physical store layout. They do not define a new public IPC method or configuration schema. Exact credential selection uses the complete key; omission never means wildcard matching.

FieldMeaning and validation
ownerNamespaceStable owner-assigned identifier for this CLI product’s credential boundary. Human branding, executable names and a common issuer do not merge namespaces. Sharing or migration requires explicit owner configuration and validation.
profileId, accessDomainStable approved connection-profile ID and the domain in which this credential is used. ownerConfigRevision records the exact approved registration and trust bindings; a changed configuration must revalidate compatibility before reuse.
authority, subjectKind, subjectVerified credential authority and stable account ID; subjectKind is user or service. An identity token uses its validated issuer and subject. A service/registry adapter uses its registered authority and verified account mapping; a username alone is insufficient.
audience, scopesExact approved target audience and canonical finite scope set. Preserve protocol-defined case and spelling; sort/deduplicate sets without broadening them. Distinct audiences/scopes remain separate records, even for one account or hostname.
authFlow, clientId, purposeRegistered authentication flow, application registration where applicable, and identity, service or registry purpose. An explicitly inapplicable clientId is a tagged absence, not a wildcard. A shared client ID does not merge accounts or brands.
credentialRefOpaque core-owned reference to one selected credential record. It is neither secret material, an access grant nor a selector accepted from an extension. Resolving it requires the current trusted activity, target, binding and deadline.
credentialRevisionMonotonically increasing record version used for compare-and-swap (CAS) and refresh rotation. A new secret cannot overwrite a newer version.
authSessionId, sessionEpochCore-generated authentication-session identity and monotonically increasing durable invalidation fence. They are distinct from ADR-0003’s IPC session ID and are never bearer credentials. Session IDs are never reused.
accountSelectionRevisionCAS version of the selected account for future invocations in this profile. It does not rewrite an existing invocation.

The complete credentialKey contains ownerNamespace, profileId, accessDomain, authority, subjectKind, subject, audience, scopes, authFlow, clientId and purpose. Before an identity is verified, a sign-in attempt has a separate random attempt ID; guessed subject data cannot reserve or overwrite a credential key. Secrets are bound to their full metadata inside the protected payload, so a swapped OS-store item fails validation. Storage lookup labels use opaque IDs, without tokens, account emails or raw subjects. Secret Service lookup attributes, for example, are not secret storage. Secret Service lookup attributes.

principalBinding retains ADR-0005’s kind, bindingId, authority-qualified subject and identity-provider registration. For a verified principal, its authenticationContext is {authSessionId, sessionEpoch, authenticationExpiresAt}. Each new sign-in or account selection creates a fresh bindingId. A local principal has no invented authentication session. The authority’s stable subject rules remain authoritative; OIDC uses the issuer and sub, not a display name or email. OIDC subject stability.

OIDC requires checking exp when accepting an ID token and explicitly separates that expiry from authenticated-session lifetime. A refresh response may omit an ID token; any returned ID token follows the refresh validation rules. OIDC ID token semantics, ID token validation, refresh response.

This decision therefore selects three separate validity boundaries: acceptance of authentication evidence, the core authentication session, and use of each API credential. At sign-in, the adapter validates current evidence and the profile’s required authentication assurance before creating a session. authenticationExpiresAt is fixed at session establishment from the owner’s finite, non-sliding session lifetime, with a default maximum of 12 hours. Any earlier authoritative session deadline supplied by the registered provider/adapter shortens it. If the profile requires a maximum age of the original user authentication, the adapter must obtain and validate auth_time and cap the session by that age; required assurance claims such as acr must satisfy the owner’s declared mapping. Missing required evidence rejects sign-in. A profile requiring an authoritative provider-session bound cannot substitute the local default when that bound is unavailable.

The initial ID token’s exp is not automatically the core session deadline. The core retains its validated binding and original evidence provenance; it never presents an expired ID token as fresh authentication proof. A continuing local session under owner policy does not assert that the provider’s own session still exists or that access remains authorized. Each actual API credential retains its independent issuer/adapter expiry and per-use validation. Neither a stored refresh token nor a new access/ID token extends authenticationExpiresAt. Extending the core authentication lifetime requires a new explicit sign-in or explicitly requested noninteractive authentication operation and a new binding. An owner policy change may shorten or invalidate an existing context, never silently lengthen it.

Token renewal may retain bindingId, authSessionId and sessionEpoch only within that original deadline and with the same verified authority, subject kind/ID, registration, target and scope bounds. credentialRevision changes. A narrowed or changed identity/authority/scope cannot silently replace an invocation’s binding; it invalidates that context and requires a new one. Related credential records sharing one rotating refresh-token family also share a coordinator-owned refreshFamilyId; refreshing any member serializes the whole family. The family mapping comes from the trusted authentication adapter, never from an extension or a guessed token claim.

Trusted operation contract and bounded use

Section titled “Trusted operation contract and bounded use”

Every operation carries a core-generated requestId, owning activityId, exact profile/configuration, deadline and cancellation signal. Mutations carry their expected session epoch and record/selection revision. The coordinator validates inputs before allocation or store access. A request ID correlates work; it does not make a remote authentication exchange idempotent.

Logical operationInput and successful result
inspectSessionExact trusted profile/account selection; returns safe metadata, storage mode and state. It neither retrieves secrets nor renews or signs in.
signInApproved flow, requested exact target/scopes, interaction mode and expected selection revision; returns a newly verified and committed binding plus protected references. Incomplete or uncommitted credentials are not a successful login.
useCredentialTrusted component registration, activity, published reference, target/purpose and required remaining validity; obtains bounded use inside the trusted integration after all context checks. It returns an operation result, never a general token through extension IPC.
renewCredentialExact reference/family, session epoch and expected credential revision; publishes one validated replacement or a typed failure. No browser or account switch is implicit.
selectAccountExplicit exact verified account, expected selection revision and compatible approved profile; commits a new selection/binding and invalidates the previous selected authentication context. An unavailable/expired target requires authentication, not name-based rebinding.
signOutExplicit session or profile scope and expected selection revision; returns localInvalidation, secretCleanup and remoteRevocation separately. It never reports unconfirmed local invalidation as success.

useCredential is available only to trusted registered components. The component must match the record’s target, transport trust, purpose and bound identity. It receives a short-lived use handle or secret view for that one operation and releases it on completion/cancellation; it cannot retain a general credential reference as an extension-facing result. A final coordinator check precedes admission of the actual protected action. Secret reads and refreshing alone do not authorize that action; ADR-0012 still supplies the permission decision.

The profile declares renewalMode: on-demand / explicit-only; the selected default is on-demand when its registered adapter supports renewal. It may perform one bounded noninteractive renewal before admitting an operation whose credential lacks the required remaining validity, while the authentication context itself remains valid. explicit-only instead returns authentication_required with a renewal-needed reason. inspectSession, base help, completion and describe never renew credentials; contextual help retains ADR-0002’s existing prerequisites. Neither mode initiates a new sign-in, extends a binding or repeats a protected action already attempted. Missing renewal support or a refresh error remains explicit.

The loader may use registry credentials only with its approved source binding. Authorization-provider service credentials authenticate that provider connection; they do not replace the requesting user’s principal. Revoking an independent registry/service session stops actions depending on it without inventing a different user identity or globally invalidating unrelated user sessions. A user logout invalidates its session and credentials derived from that session, not every independent service account in the OS store.

General login, refresh, provider-service and registry secrets never enter invocation arguments, inherited environment, logs, stdout, descriptors, catalogs or extension IPC. A separately registered ADR-0002 operation may issue a deliberately limited credential only after its own action/resource check, with explicit recipient, scope, expiry and revocation semantics; it cannot return this store’s general references or refresh tokens. Source redirects are revalidated and never carry credentials to another origin, preserving ADR-0007.

Interactive OIDC uses ADR-0005’s external browser, Authorization Code with PKCE S256, approved loopback redirect, request correlation and token validation. The listener and temporary state close on completion, error, timeout or cancellation. Rukh does not collect the account password or embed a shared confidential-client secret in a distributed CLI. This follows the native public-client boundary. Native application OAuth.

Device authorization is explicitly selected and supported by the registered provider profile. The interaction displays only the approved verification destination and user code through the core terminal; it honors polling intervals, slow_down, expiry and cancellation. It is not a fallback after a browser failure and is not an unattended CI flow. Device Authorization Grant.

CI and service accounts select a registered noninteractive adapter and subjectKind=service. Supported choices can include externally provisioned workload credentials, a platform/domain identity or a confidential-client flow whose secret/private-key use is supplied by an approved credential adapter. OAuth client credentials are for confidential clients; distributing one shared secret in every CLI is not that arrangement. OAuth client credentials. The common contract requires a verified service identity and bounded target authority; it does not claim that every adapter supports every flow.

A provisioned secret arrives through the approved adapter or an explicitly requested protected input channel, never a token-valued command-line argument or implicit environment scan. Owner-approved CI integration may consume its explicitly named protected injection mechanism inside the trusted adapter; the value must be removed from inherited extension environments and excluded from diagnostics. This does not turn environment contents into a verified identity. Noninteractive operations return interaction_required when a browser, device-code confirmation or unlock prompt would be needed. Help, discovery, completion and an ordinary protected request never secretly initiate sign-in.

Login stages new credentials and validates them before its selection CAS. Failure or cancellation before metadata publication begins leaves the prior selection unchanged, subject to its existing validity. Successful replacement atomically invalidates the old selected session and publishes a new selection/binding. Once publication begins, an interrupted or unconfirmed write returns commit_unknown; the core reconciles the durable operation ID before reporting which selection is active. It neither assumes the old selection survived nor rolls back a committed replacement because cancellation arrived late. A concurrent logout or selection change defeats the stale CAS; a late callback cannot select an account or resurrect its old session. The user must explicitly retry a rejected sign-in; the core does not replay a consumed authorization code, and an unresolved publication is reconciled before any new attempt.

Persistent coordination and refresh rotation

Section titled “Persistent coordination and refresh rotation”

All cooperating instances using the same persistent namespace and OS account use one core-owned local coordinator. It maintains crash-consistent metadata with atomic CAS, a durable journal of pending/committed transitions and OS-enforced mutual exclusion for short local transactions. No network request runs while holding that local transaction. The concrete platform binding must demonstrate these properties before advertising persistent support; OS secret-store writes alone do not provide them.

The coordinator is authoritative for published references, session epochs, selections and refresh-family state. It never reconstructs live sessions by scanning secret-store items. Metadata contains no secret bytes and has owner-only OS access; private identity metadata receives the same access restrictions. Secret payloads occupy immutable revision slots through the protected adapter. Publication follows this order:

  1. Durably reserve an operation ID and its expected epoch/revisions in a metadata transaction.
  2. Write the candidate to a new protected slot and confirm the write. Never overwrite the live slot in place.
  3. CAS the published reference under the same expected fence/revisions; commit metadata durably before reporting success.
  4. Remove unreferenced old/staged slots with bounded cleanup. Failed cleanup retains its protective record and is reported; it cannot make an unpublished secret usable.

Readers follow only committed references and verify embedded metadata. A new namespace is initialized explicitly with a fresh store identity before its first sign-in; initialization never imports existing secret slots. Missing state in a previously initialized namespace, corrupt state or ambiguous coordinator state is storage_error, not an empty successfully cleared store. Startup recovers committed transitions and marks unresolved remote exchanges uncertain before any dependent action. It does not downgrade to volatile state or restore an old credential from a backup. Store migration must preserve invalidation fences or explicitly invalidate all transferred sessions; copying protected slots alone never imports an account.

A family has at most one in-flight renewal across processes. The winner durably marks refresh_started before sending the refresh request. Other callers wait within their deadlines and then reread the committed revision, or receive credential_busy; they do not send another request. Rotation publishes replacement access/refresh material together. No use of the old refresh token is permitted after a replacement commits. Public-client refresh-token replay defenses and rotation are protocol requirements at the authorization server; the local serialization described here is Rukh’s additional design. OAuth refresh-token guidance.

A lost response, process death after refresh_started, or failed publication after a possibly successful exchange produces refresh_uncertain. The coordinator blocks the family and invalidates its authentication session; recovery requires explicit authentication creating a new session. A timeout/expired lock never authorizes replay of the old refresh token. Even a configured retry budget cannot override this rule. A failure proven to occur before any remote exchange may return a retryable transport error; protocol-level rejection such as invalid_grant makes the session unusable. An API authentication failure never automatically repeats the protected operation, even if renewal later succeeds.

This selected sequence shows the ordering when logout wins a race with renewal. Remote effects already started remain possible.

Accepted refresh and logout race
Accepted refresh and logout raceOne CLI records refresh ownership before contacting the provider. A second CLI durably invalidates the session. The late refresh response fails its epoch comparison, is never published and cannot restore the logged-out account.CLI instance BIdentity providerShared coordinatorCLI instance ACLI instance BIdentity providerShared coordinatorCLI instance AReserve family refresh at epoch E and revision RPersisted refresh_startedOne refresh exchangeSign out expected sessionCommit epoch E+1, invalidate bindings and detach referencesLocal invalidation confirmed, cleanup statusReplacement credentialsPublish only if epoch E and revision R still matchcontext_invalidatedDiscard staged secret and bound remote cleanupAccepted refresh and logout raceOne CLI records refresh ownership before contacting the provider. A second CLI durably invalidates the session. The late refresh response fails its epoch comparison, is never published and cannot restore the logged-out account.CLI instance BIdentity providerShared coordinatorCLI instance ACLI instance BIdentity providerShared coordinatorCLI instance AReserve family refresh at epoch E and revision RPersisted refresh_startedOne refresh exchangeSign out expected sessionCommit epoch E+1, invalidate bindings and detach referencesLocal invalidation confirmed, cleanup statusReplacement credentialsPublish only if epoch E and revision R still matchcontext_invalidatedDiscard staged secret and bound remote cleanup

Logout, account changes and action admission

Section titled “Logout, account changes and action admission”

Successful persistent logout first commits a tombstone with an increased session epoch, invalidates its binding IDs, detaches every published credential derived from that session and clears the affected selection. That durable commit is the local logout boundary. Secret deletion and optional remote revocation follow it and cannot reverse it. Repeated logout of the exact already-invalidated session is idempotent; signing out another account/profile requires its explicit scope and revision.

Every new protected action, including one using a cached permission or a process-local secret view, compares the invocation’s bound session epoch and authentication deadline with the coordinator. Admission and invalidation are serialized under the coordinator’s local transaction boundary. Admission means the trusted implementation has reached the protected-action start boundary, not a queued promise for later use; delayed work must recheck there. Notifications may drop cached state sooner, but correctness never depends on their delivery or a polling interval. If the persistent coordinator cannot be read, protected actions requiring that session stop.

An action already admitted before invalidation may finish or have an uncertain outcome. A returned token cannot be pulled back from an external service. Native extension processes retain their ordinary OS capabilities: this core contract neither sandboxes them nor guarantees kernel-enforced termination or rollback. The first accepted cancellation and the single shutdown budget from ADR-0004 remain unchanged. Cleanup and mandatory audit keep only their established scope; they cannot reopen ordinary protected requests.

An existing invocation is never rebound to the newly selected account. Account changes and new sign-in invalidate the previous selected authentication context; old invocations return context_invalidated for further protected actions. A new invocation obtains a new binding. Expiry returns authentication_required with a safe expired reason; known invalidation returns context_invalidated. Credential usability is checked separately from ADR-0012 permission validity, and authentication invalidation immediately makes cached decisions for that binding unusable.

Logout result fieldValues and meaning
localInvalidationconfirmed only after the durable fence commits, or after the process-local fence commits in explicit volatile mode; otherwise unconfirmed with storage_error.
secretCleanupcomplete, pending or failed; a definitely absent slot is complete, while permission/IO/locked-store failures are not treated as absence. Retained tombstones prevent failed cleanup from restoring use.
remoteRevocationconfirmed, unsupported, failed, uncertain or not_requested; confirmation concerns the configured revocation request only, not every service/browser session.

If durable invalidation fails, the calling process blocks the session in memory and reports unconfirmed logout; it cannot promise that other processes or a restart are logged out. If the durable fence succeeds but deletion fails, local logout remains confirmed with explicit incomplete cleanup. Tombstones are retained across restarts; garbage collection cannot remove a fence while any old writer, staged slot or reference could publish against it. On quota pressure the implementation rejects new sign-ins rather than evicting protective records. A later fresh login receives a new session ID, never reopens the tombstoned one.

When supported and requested by the profile, remote revocation uses the already selected authority and bounded credentials solely for revocation after the local fence; it cannot publish new usable material. The logout transaction may retain a cleanup-only protected reference for that purpose; it is never a live credential reference and cannot pass ordinary useCredential. Network revocation is best effort and its failures stay visible. A successful RFC 7009 response can also mean the submitted token was already invalid, and related-token revocation depends on server policy. It does not establish logout from every service or clear browser SSO cookies. OAuth token revocation.

The following are selected conservative defaults, not measurements or protocol-wide limits. Owners may choose lower limits; a higher finite value requires explicit supported configuration. Adapter/platform restrictions always apply too. Provider deadlines can shorten an activity but never lengthen its owner/activity deadline. Every wait, exchange and cleanup also fits the remaining parent activity and applicable operation budget. For an invocation entering shutdown, ADR-0004’s single non-renewable 5-second shutdown budget caps all remaining cleanup; a standalone sign-out allowance cannot add time to it. Insufficient remaining time leaves explicit pending cleanup and retained protective references.

BoundAccepted default
Complete protected credential payload64 KiB, further limited by the selected adapter; an oversized payload is rejected without ad hoc plaintext spill or unregistered splitting
One identifier/text field; exact scope set2 KiB UTF-8 per field; 64 scopes, at most 256 bytes each; control characters and malformed Unicode rejected
Active stored credentials per namespace256; at most 32 sign-in sessions; protective tombstones/pending records retained under a separate 10,000-record quota
Concurrent activityOne sign-in/selection mutation per profile; one refresh per family; 32 waiting requests per family
Interactive login/device activity5 minutes, capped by provider expiry and activity deadline, consistent with ADR-0005
Noninteractive exchange or renewal30 seconds total; one exchange attempt after refresh_started
Store access/coordination wait; logout network cleanup5 seconds per operation within the owning deadline; 10 seconds total for optional remote cleanup of a standalone sign-out, further bounded by any remaining parent/shutdown budget
Core authentication session upper bound12 hours from session establishment; shorten by any authoritative provider/adapter session deadline and required original-authentication age. ID token acceptance expiry and API credential expiry remain separate; renewal cannot extend the bound core context.
Expiry margin30 seconds for obtaining a usable credential; reject if its remaining life does not cover the bounded request. This margin never extends token or authentication expiry.

Time checks combine validated absolute expiry with a monotonic in-process deadline; rollback or unreliable time never lengthens an existing context. After restart the core rechecks absolute expiry, coordinator fences and registration compatibility before deriving a new invocation binding. If time validity cannot be established, authentication is required. A maximum-duration admission check cannot promise the provider will accept the credential for the entire operation; earlier remote revocation remains possible.

The error vocabulary is invalid_request, invalid_response, authentication_required, interaction_required, context_invalidated, unsupported, unavailable, storage_locked, storage_error, revision_conflict, commit_unknown, credential_busy, refresh_uncertain, deadline_exceeded, cancelled and limit_exceeded. Errors carry a safe message and operation-defined reason; store adapters preserve definite absence separately from failure. No error becomes successful logout, an anonymous/local subject or permission. Invocation outcome mapping follows ADR-0002/0004; these are not new final outcomes.

Core diagnostics may record activity/request ID, adapter ID, safe profile ID, state transition, revision, duration and typed failure. Account identifiers are minimized or redacted under owner policy. Token responses, authorization headers, refresh/device secrets, passwords, private keys, callback query strings and complete provider error bodies are never diagnostics or stdout. A device user code is shown only in its intended interactive prompt. Required audit uses the existing trusted gate and failure rules; this record does not introduce a token-bearing audit stream.

Refinement: acting clients and task authority — 2026-09-24

Section titled “Refinement: acting clients and task authority — 2026-09-24”

ADR-0014 adds a core-owned task binding and a separately established actorBinding; it does not turn a credential into task authority. principalBinding continues to identify the subject whose permissions apply. A local actor need not have an organizational account, but cannot impersonate one. The MCP adapter obtains the acting-client binding through its trusted configured launch/transport path, not clientInfo, tool arguments, an agent’s name or a forwarded subject token.

The baseline task handle is an opaque taskAuthorityRef resolved through protected state and bound to its recipient. It is not an access/refresh token, a credential-store selector or permission merely by possession. Delegation validates a narrower child authority and its actor under ADR-0014; it neither hands a parent’s credentials to the child nor clones the parent’s refresh family. A registered limited-credential service retains its explicit recipient, scope, expiry and revocation contract, plus the task and current-policy checks before issuance.

Each credential use remains bound to the exact task, actor, subject, approved destination and activity of the protected operation. Credential renewal preserves the established subject only under the original authentication horizon; it cannot extend notAfter, clear taskEpoch, restore a revoked ancestor, replenish task budgets or rebind an invocation. A new login does not silently migrate old tasks to the new bindingId. Lost or inaccessible task state is not repaired by reading credentials or selecting an account with the same display name.

Final admission checks both credential/session validity and current task authority under ADR-0012/0014. Invalidating a task blocks new task-bound credential use without inventing logout of unrelated sessions. Conversely, logout or account invalidation prevents further use of tasks depending on that session. Existing fences and stale-response rules remain mandatory. Neither operation proves that an already admitted external effect was undone; its reservation and uncertainty remain under ADR-0016.

Additional implementation checks remain unrun: reuse the same authenticated subject from distinct actor/task bindings; reject copied handles and unapproved delegation; race renewal/logout with task expiry and ancestor revocation; and verify that a late valid token cannot revive task authority or release an uncertain-effect reservation.

  • Small public CLIs remain usable without sign-in, secure-store setup or a server. Protected profiles have explicit extra requirements.
  • One logical boundary supports multiple platforms and service identities, but each advertised adapter must prove its storage, unlock and coordination behavior.
  • Logout and account changes stop further core-mediated protected actions across cooperating persistent instances; they cannot revoke arbitrary OS access or guarantee universal server logout.
  • Durable fences, staged slots and CAS add local recovery work. Conservative uncertain-refresh handling may require signing in again instead of risking token-family replay.
  • Credential validity and action permission remain independently testable, and command extensions need no general credential API.

The project owner accepted this decision on 2026-09-23. The following list remains required implementation verification, not a claim that these checks passed at acceptance.

No credential adapter, coordinator or authentication lifecycle test is implemented or reported as passed by this decision. For implementation verification, review the selected lifetime limits, per-platform storage capabilities and the following reference checks. Before advertising an implementation, execute them against its actual supported platforms and providers:

  1. Isolate brands/namespaces, profiles, authorities, user/service subjects, client IDs, audiences, scope sets and auth flows. Swapped protected slots and unqualified identities fail without widening access.
  2. Verify the no-sign-in public baseline, absent/locked secure store, explicit volatile selection, noninteractive errors and no plaintext/environment fallback. Exercise oversized payloads and backend limits before publication.
  3. Check browser correlation, cancellation, device polling and noninteractive adapter behavior. Failure/cancellation before publication must not replace an existing selection; publication uncertainty must reconcile its operation ID without replay or assumed rollback, and stale login CAS must not defeat logout.
  4. Race two processes refreshing one family, account selection, logout and late callbacks. Inject failure before/after journal commit, secret write, remote refresh and publication. A possibly consumed refresh token is never replayed; tombstones survive restart and late writers cannot restore references.
  5. Exercise missing versus inaccessible secrets, failed durable invalidation, failed deletion and failed/uncertain network revocation. Verify the three logout result fields and retained protective records, including quota pressure.
  6. Admit protected actions against authentication expiry, logout and account switch, including cached ADR-0012 allows and process-local secret views. Use a short-lived ID token with renewable access credentials to check that its expiry alone does not end an established core session, while expired evidence cannot establish a new one. Enforce earlier authoritative session/required authentication-age bounds and prove renewal never extends the original core deadline. Old invocations never acquire the new subject; already admitted effects remain honestly reported.
  7. Inspect extension IPC, child environments, terminal output, logs and audit using distinctive test secrets. No general credentials escape; limited credential operations preserve their separate recipient/scope/expiry contract.

Document and diagram checks establish only the consistency of this decision. OAuth references and existing ADR-0002/0003 experiments do not validate these unimplemented persistence, race or cross-platform guarantees.

Diagram

Drag to move · + / − to zoom · 0 to fit · Esc to closeDrag to move and pinch to zoom

100%