Cotal
DocsAPI Reference
Build integrationsEmbedding reference

Service endpoint callers

Caller policy

caller-grant takes an owner granter with an interactive row who holds the approved instance, and a grantee is a current exact owner, actor and lifecycle UID. A managed grantee also needs its actual same-owner parent chain, with each current ancestor holding active covering grants for the same service approval. The operation records those immutable grant ids and lifecycle UIDs in parentRefs and rechecks them before append. An admin scope never substitutes for endpoint caller rights. Every capability must name that instance with instanceOnly: true, carry no journal access and no any or ledger target, and sit within the approval's caller ceiling. The answer is granted with the grant as stored. Ordinary user-auth agent connects now derive their endpoint rows from this policy through core's native grant builder, including reserved Describe for each authorized exact instance. An unpinned invokeService or invokeCommand whose class publish the broker refuses is re-sent once on the rail of the instance that answered its describe, so a granted caller reaches the service without naming the instance. The callout rechecks grantee lifecycle, named ancestor grants, current name, assignment, root, activation, approval and ceiling, then checks the policy evidence again after signing and native-key recording. The original connection expiry is at most 60 seconds from issuance, and capped by root and approval expiry. These are fresh leader reads, not a linearized revoke fence. Existing issued connections keep their original expiry, and caller revocation remains deny-new, not terminal absence proof. One instance indexes at most 256 grants over its life, including attempts refused after indexing, and a full index answers resource-exhausted; a new instance is the remedy. caller-revoke admits the grant's source owner, its grantee owner and an operator. It answers pending with denyNew: "landed" and notBefore, in epoch seconds, 71 s after the broker time of the grant's cutoff marker. It never answers revoked, and the result parser refuses that arm. caller-policy-read gives an owner its own grantees, and another owner's grantee only filtered to a service it holds; caller-policy-list needs a service selector.

Broker payload limits

Caller grants need max_payload >= 2098176 (SERVICE_CALLER_PAYLOAD_FLOOR: 2 MiB plus 1 KiB), max_control_line >= 4096, and an auth stream with max_msg_size: -1. Broker generation accepts an explicit serverConfig(broker, accounts, { ...options, maxPayload: SERVICE_CALLER_PAYLOAD_FLOOR }); omission leaves the native 1 MiB default unchanged. No startup path raises limits automatically. The stock root sets it with cotal up --max-payload <bytes>, which records the value in .cotal/broker-policy.json; a renderer outside up reads it back with readBrokerPolicy(root)?.maxPayload so every render of that broker carries the same limit.

Payload observation

For a standalone broker only, pass serviceEndpoints.callerPayload.observerCreds to startAuthService (or the corresponding authority-plane option). The callback returns fresh host-private credentials from the broker owner's mintServiceCallerPayloadObserverCreds({ pub: broker.sys.pub, signingSeed: broker.sys.signingSeed }). Keep that registered SYS signer with the broker owner, never in the data account, a sandbox or a participant client. The helper returns an in-memory, at-most-60-second VARZ-only credential. The stock root does this itself: cotal up retains the system-account signing seed in the root's secret store at space creation and at --rotate-sys, and the auth service started with --service-endpoints composes callerPayload from it when the record names the trust record's system account and the seed derives it; a root with no retained seed opens the engine and door without caller issuance and logs why. The callback only supplies credentials, owns no authority resource, and may finish after its 10-second observation deadline has refused the operation. It is not a cancellation callback.

Startup authenticates native VARZ, matches the observer and data connection's broker incarnation, checks config/system-account evidence and live stream limits, then writes an exact-key assertion bound to that broker, configuration and genuine plane claim. Configured clusters, gateways and leaf links refuse, regardless of connected peer count. This is not multi-broker proof. A default 1 MiB broker fails startup with the required byte limit and creates no assertion.

Process restart

Positive caller issuance repeats the observation and checks the exact assertion revision, complete plane hold and effective authority again before native JWT release. Withdrawal or claim loss refuse new issuance. A broker RELOAD, which keeps the same incarnation serving and moves its config_digest, does not: when the fresh observation proves the same incarnation, the same auth store, and every limit above again, the record is re-asserted under the held claim by CAS on the exact prior row and issuance continues. A reload that breaks any of those, a max_payload below the floor included, still refuses, and a withdrawn record is never overwritten. A RESTART is a new incarnation and refuses. Reopening needs an explicit bootstrap to reassert for the new claim; a prior-plane broker-bound assertion cannot authorize another append. Legacy assertion syntax still parses for existing trusted storage fixtures but alone never enables production caller issuance. Shutdown drains in-flight observations and closes their owned connections before releasing the claim. Reads and revokes do not need a positive assertion. A revoke whose policy row would not fit holds payload-precondition without writing it, and a failed live-limit check withdraws the assertion.

Unknown outcomes

Give each caller operation a fresh random requestId, record it with the exact body before you send it, and replay that body after a lost reply, a 503 or a held answer. Never switch to a new requestId while an earlier answer is unknown. A settled refused or expired ends the attempt, and a grant replayed after its 10-minute window adopts a grant that landed and otherwise answers expired.

Caller issuance is generic, not tied to Linear: the same provider-independent contract discovery and invoke path works for ordinary and managed user-auth callers. Controlled policy append currently requires the application's approved service-host instance. Native control endpoints retain their existing ledger/scope and typed authority contracts, not fabricated application approvals. Scoped Describe is not available, and complete terminal retirement and restore remain unsupported. A host revoke refuses new activation, renewal, readiness and connections, but a connection already open keeps its original expiry of at most 60 s. Approval runs service bootstrap and revoke runs cancellation, while complete observer evidence and writer exclusion remain unavailable. Do not seed service reservations in an existing space, adopt old service-shaped rows, or use ordinary retirement to make them terminal. A signing-key or raw-store holder can bypass helper guards, so schema rejection alone does not make mixed-version writers safe. Restore must quarantine service work until a separately supported reconciliation protocol is available.

On this page