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. 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.
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 is their only writer. The effective resolver and native issuance are described under service endpoint 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.
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.
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 describes reservation, bootstrap, and cancellation guards. Service endpoint hosting, service access, and caller policy 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.
Internal active-root reader
The custody reference describes the internal active-root reader and its limits. See the detailed contract.
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.
Writer deadlines
Custody write deadlines bound waiting without cancelling broker operations already issued. See the detailed contract.