Skip to main content
Use local governed authorization when an embedding application needs different agents and callers to have different tool, source, account, or communication permissions. Start with the authorization concepts. For explicit Rust owner composition, completed-turn SQLite restoration, and the separate fixed-host, single-connection JSONL profile, use Native governed embedding.
Preview integration contract, October 2026. The Rust implementation is under active integration. These steps identify real owner interfaces and deployment responsibilities; they are not a copy-and-paste configuration recipe. No new CLI flag or universal REST/RPC authorization setup is documented here. Existing provider login remains credential setup, not activation of this governed profile.
Each protected operation needs current native permission. Its owner’s policy selects no additional review (R1), bounded model review (R2), or fresh human approval (R3). Review and consent cannot supply missing permission. Refused or action-required operations return local feedback while permitted work continues. The support table below separates recorded evidence from remaining work; the review requirements explain how to integrate each choice.

Check support before rollout

Do not label a deployment fully governed while it has an unguarded path that can perform one of its declared protected operations. An unsupported required capability must be unavailable, not routed through a permissive fallback.

1. Keep the existing identity owners

Authenticate at the real ingress: the user session, service connection, connector, or scheduled-work owner. Establish the requester, ingress actor, executing agent, and optional represented subject independently of the request body. Qualify principal IDs by their identity domain. Native integration uses NativeIngressContext for the authenticated submission and InputAuthorityAssociation for retained work facts. Constructing either is not authentication. NativeWorkAuthorizationHost connects ingress to the input owner. Keep the association on the native input with its replay identity, not in a UI or plugin’s session-ID lookup table. Verify that the actual caller may invoke the delegation. An agent holding a grant for a represented user does not mean every caller may use it. A restore, retry, or fresh login must not rewrite the original requester.

2. Compose grants with resource policy

The current Rust composition uses LocalGrantAuthority and GrantBackedWorkPolicy. Its two application interfaces have different jobs: Both use the grant owner’s local publication ordering. They read current local facts without hidden network requests. A publication stamp invalidates decisions; it is not a second policy database. For an external API, retain the credential in a trusted connector and enforce the narrower operation grant before use. Resolve a calendar ID, tenant, database, or destination through trusted owner data. If an adapter knows only that an opaque server operation is requested, authorize that conservative whole capability or leave it unavailable. Do not pretend a model-supplied label proves a finer rule. For Elephant, keep query and fetch enforcement in Elephant as well as the Meerkat invocation check. Agree on qualified identities and action/resource vocabulary; test allowed reads, denied writes, wrong represented subjects, and cross-domain identity collisions. Do not copy Elephant’s policy database into Meerkat or treat a document citation as permission.

3. Bind the actual operation at its execution owner

The native owner supplies a WorkAuthorizationContext for all input contributors. The adapter retains a PreparedAuthorizationBinding with its immutable request or plan, carrying typed operation facts rather than policy JSON or a permit. For tools, the final check must protect the actual resolved tool call and plan. For a model request, resolve the real backend, endpoint, credential identity, wire model, and hosted capabilities. Preserve the prepared companion through provider delegation and explicit retries. Perform the last current check after relevant credential or consequence-preparation waits and before the send or body. Changed accounts, routes, targets, or arguments require a new binding. Equal-looking arguments do not transfer a decision. Controller inference and hosted actions require their own permissions under the same work context.

4. Preserve local feedback and honest failures

Map typed errors before rendering text:
  • OperationAuthorizationError::Refused represents an ordinary operation refusal. Give the agent audience-safe feedback, preserve permitted siblings, and let it choose a different action within existing budgets.
  • OperationAuthorizationError::Unavailable means the authorization owner could not supply authority. Preserve operation_authorization_unavailable; this is not a policy denial or reviewer verdict. Repair the owner for that affected operation; do not retry unchecked or switch to an ungoverned route.
  • OperationAuthorizationError::ObservationUnavailable means required audit observation failed. Preserve that infrastructure classification through tool, provider, callback, live, and SDK adapters. Do not give the model a misleading policy refusal, mark it retryable, or switch providers to hide the failure.
  • SessionError::RuntimeUnavailable { reason } means a session operation could not acquire its runtime owner. Preserve the typed readiness reason and retained work; do not fall back to direct store mutation or report a policy denial.
  • ToolError::OutcomeUncertain (outcome_uncertain) means the call was sent but its effect is unknown. It proves neither success nor refusal before entry. Resolve it through the operation’s existing reconciliation or idempotency contract before considering a new, freshly authorized attempt.
  • When an effect already returned, preserve its actual result and any separate observation or settlement failure. A settlement_failures companion describes an additional failure; it does not replace the primary result or prove that the physical effect was absent.
Render Permission denied or Unable to record audit event from the typed result, not string matching. Keep private grant, account, and source details out of public status text. Before resubmitting an operation, use its typed outcome to choose the next step. These are integration responsibilities; human routing retains the preview limits in Human consent. A current reviewer allow may continue the same in-flight retained operation through its remaining native entry checks. It must not automatically re-dispatch an operation that already settled. After action-required feedback, a later authenticated decision can wake the owner through configured delivery; the agent or host explicitly makes a fresh attempt. A still-current exact decision needs no repeat review, but the attempt still needs current authorization and entry checks. An approval notification alone proves neither a decision nor execution. Resolve any earlier uncertain outcome before another attempt, while preserving permitted sibling work and model continuation. Attach the required audit sink to the actual admitted input row. The production composition exposes audited_work_context for this purpose. A tracing callback or lossy event subscription is not a substitute. Stage observations for the next existing native commit, preserving concurrent suffixes and rollback behavior. Report process-lifetime storage as such; do not add an undisclosed fsync to each operation or promise crash-proof pre-effect evidence.

SDK error compatibility

The corrected SDK error contract in this release exposes outcome_uncertain in ToolDispatchTerminalErrorKind across generated schemas and TypeScript, Web, and Python types. It is a dispatch/settlement classification, separate from the unchanged coarse WireToolErrorClass. Do not infer its meaning from an HTTP status or the generic internal class. Update exhaustive Rust/TypeScript handling and closed response validators, including validators for settlement_failures, when adopting that contract. Keep runtime, schema, and SDK pins aligned. Updated readers retain the existing named encodings, but older closed readers can reject the new value; the literal other is not an unknown-value fallback. Do not convert an unrecognized value into success, denial, or permission to retry. A compatible version handshake alone does not establish that a client can decode every new enum value. The correction preserves released Rust enum ordinals and updates the closed TypeScript and Python validators. Recorded Rust, Python and TypeScript checks pass on that change; see the exact scope in the implementation checkpoint. These checks do not establish full end-to-end SDK support.

Preserve restrictions during respawn (candidate)

For a locally bound predecessor, the respawn candidate carries its inherited launch policy and tool visibility ceiling into its successor. It reads those restrictions from the actual retained session owner before retiring it. If that authority is lost, RespawnPredecessorRestrictionsUnavailable refuses the respawn and retains the member, including a Broken member after partial cold restart. Preserve usable siblings and give the calling agent local feedback. A surviving profile name or session reference cannot reconstruct the lost restrictions. A generation proven never to have had a local session is a different case; its successor still keeps its own inherited policy and ceiling. Explicit retirement and a fresh spawn are separate governed operations under current authorization and inherited restrictions. They do not recover the lost predecessor authority, and an acknowledgement cannot make that authority unrestricted. A pending respawn correction candidate passes the corrected cold-loss scenario: respawn returns the typed refusal, preserves the exact Broken member, and installs no replacement trust. A separate surviving-session scenario passes replacement and reciprocal peer wiring after service reconstruction. These tests retain an in-memory RuntimeStore within one process and use default profiles; separate-process recovery and continuity of nontrivial inherited restrictions remain unproven. See the implementation checkpoint for the exact source and executed scope.

Preserve child ownership during shutdown (candidate)

Durable-child shutdown must settle the state owner’s admitted creation and recovery work as well as its child actors before releasing root ownership. A closed actor channel is not a clean settlement report. Preserve pending cleanup or effect debt across repeat shutdown calls and cancelled callers. Until that contract is implemented, the interim design requires retaining the existing root claim until process exit; same-process reopen then returns AlreadyClaimed. This is a later implementation slice, not released durable-child recovery support. Choose child durability explicitly. ProcessBound remains valid long term. The definition-based .persistent_state() convenience path persists session and runtime data while keeping mob storage in memory; durable-child support through that path remains open. A supplied .mob_spec(spec) can carry a durable composition. Preserve the actual selected custody and its matching provenance instead of inferring child durability from a constructor name.

5. Retain a usable controller for admitted work

Resolve and pin the actual controller client during admission. A model name and credential reference alone are not a runnable client. Retain its selection with the native work, separately from the grant for tools and sources. Before ordinary revocation, route replacement, or credential removal, the real owners must determine whether unfinished work depends on that controller. Keep or atomically replace the route, or refuse the administrative change. Do not maintain a separate usage counter or silently stop the run. Explicit administrative stop remains a separate action. This continuity integration is a rollout gate, not something a host may assume from successful client construction. Retry only a grant revocation known to have stopped on contention without mutation, after the contention clears. Unavailable alone does not identify that condition. Audit failures do not authorize retrying an effect.

Model review requirements

The model-review and consent amendment defines the accepted integration direction. The responsibilities below do not establish end-to-end implementation or qualification. Have the existing native policy owner select the requirement for each operation. Check policy coverage at activation and when adding dynamic operations; unknown coverage never implies R1. Enforce the requirement at the shared native boundary, including direct SDK entry. Reject an invalid configuration update without terminating already admitted work. Retain the candidate and its authenticated original-work association through the existing owners. Carry requester, executor, represented subject, ingress, selected account, and applicable mandates or policy edits from those owners, not model text. A copied reference or matching JSON cannot recreate a lost binding. Independent calls do not implicitly become an approved batch. Have each owner distinguish required material, genuine inapplicability, and unavailable context. Missing or unsupported facts are not inapplicability; required facts that cannot be supplied or disclosed produce typed unavailable review before reviewer transport. The action account comes from the action’s actual owner, not the reviewer’s credential route. Concrete host/account derivations still need integration. Keep this optional review-context work off the R1 path. The reviewer itself needs authorization for its actual model, processor, credential route, investigation tools, and information sources under that work context. Give the review a finite owner-selected deadline and retire expired attempts before fallback; a late result cannot authorize entry. Neither model allow nor human approval grants missing permissions or weakens confinement. Keep deny, escalate, and reviewer unavailable distinct. Missing necessary reviewer access or a failed review supplies no verdict. Route escalation or unavailable review to eligible human review only when that alternative is configured; autonomous profiles can return audience-safe local feedback instead. Pending human action also settles the affected operation locally while permitted siblings and queued work continue. Required audit-observation failure remains an infrastructure error, not a denial or ordinary reviewer-unavailable result. Human approval cannot repair that failure. The existing ApprovalService exposes request, get, list, and decide for approval audit records. These methods do not authenticate supplied actor identities or execute effects. The native consent candidate adds a separate authenticated decision and retained-action path; the workflow is not qualified end to end. Its store outcomes and restored history, described below, remain subject to the current integration status. For that integration, the host authenticates the decision event, checks current approver eligibility, and binds the presented facts to the exact retained candidate. An audit actor string is not an approval credential. Present the action, target, recipient, account, arguments, requester, agent, and expiry to an eligible audience. Return Approval required while other permitted work continues. Use the existing delivery and session owners to admit later authenticated decisions and wake the owning session. Delivery does not execute the retained action, replay it, or change its requester. On a later explicit attempt, resolve the retained candidate and complete host validation, preparation, and cancellation checks before consumption. Recheck current authorization and conditionally consume consent at the physical-entry boundary. Changed or lost bindings need fresh consent. A failure known to precede the consumption commit leaves otherwise-valid consent spendable; an ambiguous commit result must be resolved through the same owner before reuse. After a committed use, cancellation or failure does not refund it. Reconciliation or applicable operation idempotency is required before repeating an uncertain effect; fresh consent alone does not establish non-delivery. An audit record cannot recreate executable consent. Test presentation, delivery, and sink integration before advertising this workflow. The candidate restores consent records as history only. An old Pending or Approved row does not restore the original retained action, even when it has no consumed_at. A real human denial remains Denied; closing the original run or withdrawing its authority is a separate withdrawal. A new service refusing an old reference and completing fresh work is a safety control, not proof of interrupted-run resumption or automatic decision delivery. Several services may open the same approval store. A service that opens it reads consent rows as history: an empty set of retained candidates proves only that this service holds none, not that the issuing owner lost custody. Such a reader withdraws nothing. A decision through it is refused before any commit, and an attempt through it reports the owner as unavailable rather than consent as missing. Decide and attempt through the live issuing owner. An attempt through a service that did not issue the consent, including one that names consent approved before a process restart, reports the owner as unavailable (OwnerUnavailable) only when the approval is Pending or Approved, its consent is neither spent nor withdrawn, and the service holds no candidate for it. A spent, withdrawn or denied row keeps its usual outcome. That says only that this service holds no custody for the approval. It does not report that another owner is live or that the issuing process stopped, and it does not mean a remote decision path exists. It is not transient in that service, so a host should request fresh consent rather than retry. A consent approval issued in a run that the runtime staged on a store with cross-process hosting claims records a passive owner scope: the store’s hosting domain and the run’s session. It is identity data for later recovery, never authority or custody: the owner’s own transitions keep it, but the stored row is not tamper-proof, and later recovery checks the actual hosting claim rather than trusting it. Approvals issued without it, such as those of a sessionless host, behave as described above. Decisions reach the owner through ApprovalService::decide_consent on the same service the host passed to its operation review composition. The stock REST server, and rkat-rpc serving an ordinary realm, install no operation review and no human route, so they create no native consent approvals and offer no consent decision method. rkat-rpc serves a governed realm only as governed JSONL over stdio. When the realm configures review rules, rkat-rpc composes the realm owner’s operation review for that pipe, with the pipe’s operator as its R3 human route. The pipe then delivers consent notices and decides through approval/consent_decide; see R3 human consent on a stock governed pipe. An embedding host that installs a human route calls decide_consent directly. An embedding host whose own transport authenticates the actual human decision event can route it through the RPC router instead. Its trusted adapter builds an AuthenticatedConsentEvent: the AuthenticatedApprover, carrying the event’s HostAuthenticationScope (the exact login or session), together with the approval and the decision. The adapter passes it with an approval/consent_decide request to MethodRouter::dispatch_with_consent_event.
  • Plain dispatch has no route to that method.
  • The request may only name the approval and the decision, and both must equal the event’s. An approver, actor, assurance, login or reason in the body is an invalid parameter.
  • The host route’s eligibility receives the approver with its authentication scope. The host must refuse an event from a revoked login even while another login of the same person is live. Revoking a login must advance the publication that the returned evidence checks, so a decision already in flight from that login is refused at commit.
  • The constructors of the approver and the event authenticate nobody. They record what the host adapter established, and the adapter supplies the current login scope and eligibility, including logout and revocation.
  • The router’s runtime must use the approval service the host gave its review composition, because only the issuing owner holds the candidate.
Revoking allowances that were published earlier, for example on logout, stays with the host’s existing publication and withdrawal path. The stock servers build no such event. Waking the owning session on a decision, durable delivery with a visible failure, and handing approved consent across a new turn are later work. Reusable consent applies only to a requirement that owner policy explicitly makes reusable, with a defined scope, use limits where bounded, expiry or an explicit until-revoked lifetime, and revocation. It cannot waive R3 or an unresolved R2 escalation. Temporarily changing a review tier is a separate, scoped policy edit through the existing policy owner, with its own administrator authorization and expiry. Present the action approval and policy change separately; eligibility to approve does not confer policy-edit authority.

Mandatory hook migration (candidate)

This candidate introduces the hook-locality correction and the model_operations configuration field. Qualification and full lifecycle coverage remain open. This section describes the candidate migration, not released availability. Before activation, reject any mandatory model-request hook configuration that would also gate the feedback request needed to report its own refusal. Apply this check to the effective configuration, including per-run overrides and replacement engines. Report unsupported configuration; a rejected update must preserve the previous valid configuration and already admitted work. The default remains model_operations = "all". An affected configuration stays invalid until the policy owner explicitly selects model_operations = "ordinary_only" or changes that configuration. This choice limits that prerequisite to ordinary model requests and permits a separately authorized controller request to explain the refusal. Never silently skip a mandatory hook or convert Guardrail to Observe. Feedback does not waive the original prerequisite. Give each request its own purpose. A feedback request can explain what was withheld while permitted work continues; later ordinary requests through the same controller must still pass their mandatory hooks. A feedback failure must not start another feedback loop. Unsupported mandatory RunStarted and TurnBoundary configurations must also be rejected before activation or admission in this slice. Per-item boundary withholding and full hook-lifecycle coverage remain open; silently skipping these gates is not a migration. Describe outcomes at the actual boundary. PreLlmRequest can withhold the model request. PostLlmResponse runs after the provider call and possible streamed output or provider-native effects. A refusal there can withhold subsequent local tool dispatch and authoritative assistant commit; it cannot undo those earlier effects. Do not expose rejected raw output in ordinary feedback.

Process confinement

Choose explicitly between host-trusted execution and a required mechanical profile. Required confinement includes the actual filesystem, network/IPC, environment, and inherited descriptor limits. A missing backend or unsupported requirement refuses that launch; it never retries without confinement. Native hosts can select the shell requirement with AgentFactory::with_shell_confinement(ShellConfinement::Required { requirement }) when enabling shell tools. Each automatic agent build inherits that host requirement into its own dispatcher. The compatibility default is ShellConfinement::TrustedHost. A session request or recovered job does not select a weaker requirement. This configuration applies to shell tools. The stock hosts (rkat, rkat-rpc, rkat-rest and rkat-mcp) select the shell, command-hook and MCP stdio requirements from the [confinement] config section or their --confinement flags and install them through these factory settings; see OS process confinement. Source-reviewed factory integration also binds required confinement through the native command-hook owner. That integration remains queued source, with full hook-locality, protected-audit, and platform qualification open; it does not establish coverage for every subprocess owner. See the native embedding guide for the current checkpoint. At host setup, validate the backend’s real capabilities and compile supported policy for the configuration generation. Bind exact command inputs at launch through the existing process owner. Protect the runtime’s credentials, stores, control endpoints, and shared bootstrap installation from every confined writer. A profile protecting only its own helper can leave another profile’s helper replaceable. Do not claim this is solved by a path check alone. Use actual OS probes with successful allowed operations and blocked forbidden operations. Cover foreground commands, background jobs, recovered monitors, MCP and other subprocesses, and differently authorized agents. Existing containers count only for the isolation they really provide. A shared pod, proxy environment variable, or shell working directory is not automatically the required boundary. Untrusted in-process native plugins remain outside that protection.

Migrate an existing application

  1. Inventory actual operations and trust boundaries: model accounts, tools, sources, peers, stored-resource access, schedules, and outbound routes.
  2. Reuse existing identity and resource owners. Add explicit grants and represented subjects where needed; do not infer them from agent ownership or OAuth access.
  3. Wire one complete admitted-work path through the real dispatcher and audit owner. Prove a denied body is never entered and an allowed sibling completes.
  4. Cover every alternate path you expose, including hosted tools, retries, compaction, live/audio, browser/WASM, callbacks, and scheduled or delegated work.
  5. Validate controller continuity, failure propagation, durable recovery where claimed, and the separately selected consent/confinement workflows. Measure the complete added cost before broad rollout.
Existing histories need no semantic relabeling or fabricated provenance. Keep their actual resource ACLs and retention rules. A trusted embedded deployment remains an explicit choice; migrating some paths does not make unguarded paths governed. For an optional gate agent, give the publishing capability only to the intended gate route. Include indirect publication queues, peers, network-capable tools, and hosted capabilities in that route inventory. Keep the original requester on queued work, and keep human consent independent from the gate’s model judgment.