# Service authority contracts

## Account connection census

`mintAccountCensusCreds` creates a host-only SYS user with at most five minutes of authority.
It can request CONNZ for one DATA account and subscribe only to an account-qualified reply prefix.
It grants neither KICK nor account events. The host supplies a registered SYS signer; the helper
does not find, persist or renew that signer, and the broker verifies its authority on connection.
`observeAccountCensusWithCreds` requires this narrow scope and a pinned server key. It reads one
bounded page. Malformed, incomplete, multiple-server or cluster-declared replies are unknown,
with no connection list. A complete result describes only that server's observed account page.
The host still needs independent topology and restore guarantees, deny-new, a fixed cutoff and
lifecycle fencing before using an observation for retirement. These helpers do not grant service
registration or terminal retirement.

## Service authority contracts

`@cotal-ai/core` exports closed service-authority request, proof and result types and their
runtime parsers. The parsers bind a result to the submitted request and registration witness.
`AuthProvider.serviceEndpointAuthority` is an optional provider hook for this protocol. A provider
without the hook must refuse service setup. The user-auth provider implements the HTTP client,
including `serviceEndpointInfo` for the DATA-account binding. It uses the pinned exchange origin,
refuses redirects and does not retry an unknown mutation outcome. Server-side HTTP failures
remain unconfirmed even when their bodies resemble a protocol denial. A registered snapshot must
name the submitted closure set. Inline artifacts include each closure manifest as well as its
documents, within the envelope byte limit; native per-closure walk limits still apply. The client does not transmit
the local host capability or read callout signing material. Local setup needs the client sentinel
projection written by `prepareServer`; a missing projection refuses rather than reading server secrets.

### Host lifecycle requirements

`@cotal-ai/auth` exports host request and view types with `parseServiceHostRequest`. Parsing checks
structure only, not owner consent, current grants or admission state. A context opened with `serviceEndpoints` now composes the native host operations and service registration described in [Service endpoint hosting](/docs/embedding-service-host/). Terminal lifecycle retirement and restore remain unsupported.
The native endpoint gate also carries service approval and activation fields. Registration and
serving guards retain those fields and refuse expired or revoked approval; these guards are not
a replacement for authenticated host admission. Internal host gate transitions bind approval to a
current native root and make activation monotonic. Registration completion is stamped in the
reopen CAS; a definite abort preserves the previous stamp. The opt-in host provides consent decisions and public handlers; these gate transitions alone provide neither. Terminal retirement remains unavailable. Pre-activation registration requires an empty issuance family, including
deleted records, and release rechecks fixed expiry after asynchronous work.

### Renewal proofs

`UserTokenIssuer.issueServiceRenewal` signs a separate registration-bound renewal proof.
`validateServiceRenewalProof` checks its signature, fixed expiry and full witness binding.
It is not a connect bearer. These primitives do not authenticate a current approval or native root;
the host must do that before issuing or accepting authority. `AuthProvider.serviceEndpointRenewal` now provides the client renewal source described in [Service endpoint access](/docs/embedding-service-access/).

### Service access

`UserTokenIssuer.issueServiceAccess` signs a serve-only user bearer with the full registration
witness and a fixed deadline of at most 60 seconds. Validation requires empty scope and rejects
ordinary parent, manager, session and transfer claims. Ordinary exchange and permission construction
refuse this view before actor lookup. Callout
refuses it unless a sealed native service authority is configured. The private composition binds
the current assignment, native root, registered serving grant and receipt before an encrypted
response. Default authority-plane startup keeps this composition off. `serviceEndpoints` explicitly enables the service callout and public registration. Restore and coordinated terminal root retirement remain unsupported.

Internal service-access reads retain native credential-root authorization and check the activated
registration, assignment, current name and fixed expiry. They do not create a serving grant or
release a native JWT. The private callout composition performs native issuance and final
authorization when explicitly configured.

Service serving-issuance evidence binds the authenticated broker user key, server key and client id.
The native release fence rechecks that record and the gate after its CAS. Ordinary serving and
credential-root records cannot use this service binding. This is not proof of broker acceptance;
the opt-in authority plane now composes this evidence, while terminal retirement remains unfinished.

`mintServiceCalloutJwt` is a host-only mint seam. It uses the native serving grant, the actual
principal name and tags, the authenticated broker user key and a separate client inbox nonce.
Expiry stays bounded by the original admission and access deadline. It does not authenticate the
callout request, record natkey evidence or release an encrypted response; the host must do those.

Native service receipts bind the same epcred connection and registration witness to the broker user
key. Recording rechecks the evidence, receipt, native authority and fixed expiry. Expired service
receipts are retained, not pruned on elapsed JWT time. The opt-in authority plane now records this evidence for service connections. Qualified terminal retirement remains unsupported.

### Service name bindings

Internal service-name bindings are create-only and return owner and revision from one native read.
The trusted host must authenticate the operator and verify the namespace claim before writing.
Native auth, delivery and manager names keep their existing authority; they cannot be application
service bindings. An operator uses the loopback host `name-bind` operation after verifying the claim. No transfer, release, or public name-binding handler is implemented.

### Caller policy storage

Internal caller-policy storage uses the sealed native registry and binds each row to one account,
space and grantee UID. Grant ids are immutable; an append cannot replace or reactivate one.
Initial writes require no prior native key history. A deletion arriving after an absence read
cannot recreate a policy or a pending service gate.
Revocation begins with a revision-pinned deny-new intent that unrelated appends preserve.
These are storage operations, not entitlement checks; the [service endpoint host](/docs/embedding-service-host/) is their only writer. The effective resolver and native issuance are described under [service endpoint callers](/docs/embedding-service-callers/). Receipts and terminal caller revocation remain unsupported.

### Describe observations

Scoped Describe callbacks also receive an optional immutable local context with the actual subject,
complete-envelope fingerprint, serving identity and receive-relative deadline information.
`parseDescribeObservation` shares native syntax and full-JSON fingerprint checks with trusted observers.
Neither the context nor a fingerprint proves broker receipt to a remote authority. The remote
observer and policy projection are not implemented yet. The client contract admits an explicit
read-only `describe-view` operation using only service-access proof. It checks witness, observation,
principal-policy basis and remaining validity, requires no-store responses, and bounds preparation,
HTTP streaming and validation by the same local deadline. Cancellation cannot restart that deadline.
The native handler and serving adapter are still required before this can authorize a remote view.

### Capability containment

`parseEndpointCapabilities` normalizes the native caller capability shape. `endpointCapabilitiesWithin`
checks route, instance, target and journal containment using the native grant builders. The host
still authenticates the granter and checks current grantee, parent and approval records.
Cross-principal relative-target comparisons refuse when containment is unproved.

### Read-only serving contracts

`authorizeServeGrant` accepts a read-only `ServiceSpecReader`. A trusted provider can supply
verified registration and contract reads without constructing a writable KV adapter. The function
still derives the complete serving surface and creates the process-local grant.

## Owner-bound platform supervisors

A host can start one user's supervisor without retaining that user's login. Pass
`platformSupervisor: { authorizePlatformAdmin, observeAssignment }` to `startAuthService`, then call
`handle.platformSupervisorAuthority(owner)` inside the trusted authority process. The first callback
must authenticate the platform's administrative caller through the host's own authority. The second
reads that owner's recorded `PlatformSupervisorAssignment` fresh on every call. An absent,
ended, expired, foreign-account or wrong-revision assignment refuses issuance.

### Assignment termination

To end a supervisor, record its assignment `ended` and call
`handle.endPlatformSupervisorAssignment(owner)`. It rechecks platform-admin authority and refuses
unless your record already reads `ended`. It retires the manager gate and the issued supervisor and
executor generations. After that, registration, activation and renewal refuse material returned
earlier, even before it expires, with `platform supervisor assignment for owner <owner> has ended`
or the retired-gate refusal. Stop the worker as well: an open broker connection lives until its
credential's capped expiry.

### Assignment shape

The assignment has `kind: "platform-supervisor"`, `scope: ["supervise"]`, one derived owner,
one manager instance, one lifecycle UID, a revision and a finite `expiresAt` in Unix seconds. It is
not an interactive or managed-agent ledger row and grants no `admin`. The returned door is bound to
that owner and accepts `PlatformSupervisorAuthorityRequest` with the same owner, assignment revision
and an existing `RemoteManagerAuthorityRequest`. It serves only `prepare`, `activate`, `renew` and
`renewStandingBundle`. Unknown fields, generic profiles, mint, human exchange and another owner
are refused before issuance. Do not give the worker the auth handle, loopback capability or signer.
The host carries only the bound door over its authenticated worker channel.

### Registration limits

Use `remoteManagerClient` and `registerRemoteManagerAuthority` from `@cotal-ai/manager` for the
existing registration ceremony. The result keeps the stock manager material shape and five nkeys.
All returned credentials expire no later than the assignment. The supervisor and executor ceilings
are recorded in the native issued store. The recorded permission set must be byte-identical to the
authority plane's signed native permission set at issuance and every renewal, and must never widen.
These JWTs are signed by the authority plane, not returned by the user-token callout. The door
adds no human bearer, callout view, owner ledger grant or enrollment authority. Run admission,
host-backed enrollment and shutdown maintenance need their own host composition.

See [the issuance design](https://github.com/Cotal-AI/Cotal/blob/main/docs/design/user-auth-run-start.md#platform-supervisor-registration).

## Hosted run revocation

The authenticated manager-service authority door accepts `manager-run-revoke` with the registered
manager envelope and `revoke: { runId, reason }`. The issuing host reads the admission's recorded
owner and requires the verified requester to be that owner or to hold `admin` in its fresh actor
ledger row. It verifies the current manager registration proof, space, account and epoch. It accepts
no owner or attribution from the body.

`AuthAuthorityPlane.revokeManagerRun` implements the operation. `AuthProvider.requestRemoteRunRevoke`
transports it, and `remoteManagerClient.remoteRunHosting` supplies `RunHostingContext.revokeRun` for a signerless
manager. The callback returns the stored `RunRevocation`, including on repeats. A host composing
its own remote authority must supply that callback to revoke. No signer reaches the participant.
CLI and MCP revoke verbs are a follow-up described in the [run-start design](https://github.com/Cotal-AI/Cotal/blob/main/docs/design/user-auth-run-start.md).

## Private tool-result prerequisites

`@cotal-ai/auth` exports `createToolResultRevocationCustody`,
`recordToolResultRevocation`, `snapshotToolResultRevocations` and one-shot
`consumeToolResultSnapshot`. These are host-only prerequisites, not material issuance,
service registration or a browser/private-result path. `requireToolResultClockPrerequisite`
always refuses `unavailable`: no native runtime clock-domain/generation/suspension proof
exists, and no numeric delta is invented.

### Custody creation

### Credential lifetime

Custody exclusively creates a **fresh** auth store after a private fsynced intent/generation.
Existing stores or journals are never adopted. Only a standalone broker and owner-private local ext4 journal parent are supported. Only the creating process may use its sealed,
non-reconnecting reader/writer custody. Unknown writes, missing/changed journals, stream
identity/configuration drift or connection loss invalidate it. Crash/rebind recovery stays
unavailable. Routine broker restart, upgrade, network loss or process restart therefore leaves
gate 1 permanently unavailable for that space. Recognize this as `revocation custody lost; no reopen from current INFO`.
No retirement/reprovision recovery protocol exists in this increment. Gate 2 cannot assume
custody survives broker maintenance. The trusted composition supplies current authenticated consent/target authorizers
and exclusively holds account/provisioning keys. Independently running privileged provisioners,
uncontrolled legacy writers and existing roots have no qualified custody and are unsupported.
This is not protection from a malicious host administrator or copied signing keys.
The separate internal custody profile uses two non-expiring, non-reconnecting credentials,
without planeCandidate or a renewal timer. With the two sealed scanners this is four standing
connections across three profiles. The CREATE provisioner still expires and closes after CREATE.
A leaked custody JWT plus user seed no longer has a 900-second expiry bound. Stopping the
service closes its own sockets, not copied credentials. Signing-key removal invalidates copied
credentials as well. This remains inside the trusted-process/account-signer residual.

### Revocation outcomes

Revocation creates only `revocation.<targetDigest>.<consentId>` with native expected-last-subject
sequence zero, no operation/TTL headers and independently fsynced acknowledgement receipts.
Consent bytes must match the recorded target and expiry. Persistence uncertainty reports effect
outcome `unknown`. Acknowledged writes report `executed` even if receipt or later custody checks
fail. Refusals before publication report `not-executed`. No automatic repeat follows uncertainty.
Markers persist indefinitely in this
slice. A separate bounded-retention successor must prove consent expiry plus
`EP_AUTH_MARKER_TTL_MS` and snapshot safety before a pruner/TTL may exist.

### Snapshot evidence

A snapshot fixes T0 before IO and a leader W once, walks only through W, bounds count/bytes/time,
and compares exact native sequence/subject/payload evidence to custody receipts. The committed-W
artifact is a process-private invocation seal binding that evidence, account, generation and
native created/config identity. It cannot be parsed, copied, reused or used after custody loss.
No current INFO equality or operator safe flag establishes historical integrity. Journals are
exclusive 0600 files with file and directory fsync, checked before/after IO, not adopted on restart.
Clustered brokers and leader failover are unsupported. Any connection loss refuses; current INFO cannot restore custody.

### Grant boundaries

### Verification suites

A short-lived create-only provisioner holds API discovery and exact auth-stream CREATE, then closes.
Separate package-internal grants split revocation-only publish from INFO/MSG.GET reader authority.
Retained issuance writers **already can enumerate** auth metadata. Raw ACLs cannot enforce CAS,
DEL/TTL/schema/target conventions. Every raw MSG.GET profile carries SPEC13.9's caller-selected
reply **foreign-subject response-injection** residual, even with only its own inbox subscription.
Routine PR CI runs `smoke:tool-result-prerequisites`: bounded fixtures, broker-observed
non-expiring exact grants, a no-renewal timer probe, census and actual KICK/key-removal
refusals. It does not wait for credential expiry and is not serving acceptance.
`pnpm smoke:tool-result-custody-lifetime` additionally waits `AUTHORITY_CLIENT_TTL_SEC + 15`
seconds and checks unchanged identities plus record/snapshot success. Run it explicitly or
through the manual/weekly Custody lifetime workflow. Historical lifetime receipts remain
source-pinned evidence, not a grade for a composed successor.

## Native service custody guards

### Unsupported admission

[Native service custody](/docs/embedding-service-custody/) describes reservation, bootstrap, and cancellation guards. [Service endpoint hosting](/docs/embedding-service-host/), [service access](/docs/embedding-service-access/), and [caller policy](/docs/embedding-service-callers/) describe the opt-in production composition. Terminal retirement and restore remain unsupported.

## Related contracts

### Client transport

Client transports bind their request and response to the service registration witness. See [the detailed contract](/docs/embedding-service-authority/#service-authority-contracts).

### Internal active-root reader

The custody reference describes the internal active-root reader and its limits. See [the detailed contract](/docs/embedding-service-custody/#internal-active-root-reader).

### Native custody writer

The formerly dormant writer now participates in the host service path. Its original fragment remains here for existing links. See [the detailed contract](/docs/embedding-service-custody/#dormant-custody-writer).

### Writer deadlines

Custody write deadlines bound waiting without cancelling broker operations already issued. See [the detailed contract](/docs/embedding-service-custody/#dormant-custody-writer).
