Skip to main content
Version: Development

Capability audit and inspection

Capability auditing connects the sealed broker to the durable audit owner. It adds typed capability evidence, required audit admission and scoped CapabilityService inspection. The provider reference distinguishes installed standalone providers from the additional trusted embedding integrations.

Required recording and optional observations​

An allow rule can specify "requireAudit": true. Matching allows and independent policies intersect their ceilings and combine this requirement with logical OR; any matching deny still wins. Omission preserves earlier canonical policy bytes and means false. Present null and nonboolean values are rejected.

A configured embedding calls ActivationCapabilityBroker::with_audit(handle, observations) before registering providers or compiling plans. Standalone composition requires the same audit owner as management. Configure supported standalone providers through the node provider settings.

prepare_owned_dispatch retains the exact handle and provisional budget owners. CapabilityDispatch::dispatch preflights applicable terminal records, reserves both records and awaits a durable attempt. It then rechecks policy, publication, provider, route, cancellation and the original monotonic deadline before budget commitment and dispatch. No audit wait holds an authority fence or Wasmtime Store borrow. A full, unavailable or undersized sink denies the new operation and releases provisional cumulative reservations.

dispatch_audited and call offer the same barrier for existing handles. The synchronous dispatch API rejects required-audit calls. Frozen synchronous guest imports therefore fail closed when policy requires that asynchronous barrier; their WIT signatures are unchanged. The canonical async local-service adapter uses the barrier directly.

The journal retains its single outstanding critical-operation limit. Concurrent required calls, including a required child call while its parent owns that slot, can receive capacity rejection. There is no unbounded audit queue, implicit retry or mandatory journal event for every Invoke. Optional observations may be dropped under saturation without preventing a nonrequired provider call.

Captured identity and evidence​

The broker captures trusted tenant/principal and activation/parent/root lineage; exact publication, component, deployment, revision, route and lifecycle generations; binding-definition digest; provider-binding and policy revisions; and provider profile, configuration digest and epoch. Required calls fail if this sealed-session provenance is incomplete.

Grant observations fingerprint resource selection. Call records fingerprint the actual provider request. Typed providers use CapabilityRequestDigest::from_parts over bounded input fields absent from the byte input. Missing fingerprints deny required typed calls and suppress optional incomplete observations. Local service calls include target, payload, media type, metadata and call options. Records and metric names never contain raw payloads, credentials, resource selectors or secret references. Digests are correlation fingerprints, not encryption or secrecy guarantees for guessable inputs.

CapabilityCall attempts and outcomes retain matching identities. Closed decoding, terminal preflight and recovery reject contradictory associations and provider outcome classes. Optional kinds are CapabilityGrantAllowed, CapabilityGrantDenied and CapabilityProviderOutcome.

EvidenceProvider boundary
LocalDispatchAcceptedThe node accepted the child lifecycle; its guest may subsequently fail.
HttpResponseReceivedThe HTTP provider received a response, without application transaction guarantees.
BrokerAcknowledgedThe event broker acknowledged publication, not consumer processing.
BlobSealedThe blob provider completed sealing.
SecretResolvedThe provider resolved a secret; the value is never recorded.
HostCompletedA built-in host operation completed, such as sampling a clock or accepting a bounded log entry.
NotStarted, Rejected, UnknownNo dispatch, a known rejection, or insufficient provider-result evidence.

Providers call record_provider_outcome only after observing that boundary. Cancellation and unclassified terminal paths stay unknown. Retained context lowering can finish without proof of guest delivery. An idempotency key, Allow DTO or audit sequence never establishes exactly-once execution, rollback or consumer processing.

OwnedCapabilityResponse exposes provider_outcome separately from audit_durability. finish_audit returns a durable sequence when acknowledged. A failed terminal write preserves the provider result with OutcomeUnknown recording status. Closing the journal waits for accepted owners; dropping a waiter does not cancel its prepaid terminal append. Restart reconciliation marks interrupted capability attempts unknown and never invokes the provider again.

Bounded management inspection​

CapabilityService.ListCapabilities requires an explicit deployment_id and a tenant administrator. It returns compiled operations, definition/binding/policy/ provider revisions, sampled state and tenant usage. Contract-prefix and provider filters are bounded. Pages contain at most 128 bindings; cursors pin route generation, catalog transaction, tenant, authenticated subject and filters. Changing either catalog version invalidates a cursor.

States distinguish current configuration, changed/revoked policy, unavailable provider/publication/route and indeterminate reads. A deployment without a compiled plan reports binding-plan-unavailable, without inventing its cause. Foreign and nonexistent deployments are rejected without revealing their metadata.

ExplainCapabilityGrant evaluates a bounded typed resource_document against compiled restrictions. An optional hypothetical_subject selects a principal kind/subject/service within the authenticated tenant. Legacy principal and attribute fields are rejected; no claims or alternate tenant are accepted. The response never echoes resource selectors. Allow is descriptive and subject to live admission: it reserves no activation budget and returns no sealed grant.

Both RPCs use the existing bounded policy control runtime and read-owner quota. A response lease lasts through protobuf encoding, transport body and frame ownership. Oversized responses, expired deadlines and full owners fail without extra queues. Audit queries retain their independent authorization, frozen cursor horizon, loss accounting and response leases.

Tenant counters cover live session owners, retired sessions with retained work, handles, calls, waiting owners, results and reserved input/output bytes. They sum immediate child reservations and delegated memory for session-held ledgers, with an explicit count of ledgers without delegation. Ancestor reservations can overlap: delegated memory is a logical sum, not uniquely allocated bytes or RSS. Cancellation does not refund actual retained work. Counters are sampled rather than atomic.

include_node_usage additionally requires the trusted node-operator claim. Fixed broker_*, pool_*, io_* and audit_* counters come from actual shared owners, including retained connections, failed cleanup and outstanding I/O. audit_capture_dropped counts pre-sink capture failures; audit_dropped_observations counts sink rejection. Missing owners are explicitly unavailable. No credential, foreign identity or resource-specific metric label is exported.

The weak diagnostic registry owns no provider task, guest Store or execution permission. Compact accounting can remain until the final resource or observer is released. Pools register a weak observation reference once; inspection cannot replace their owner or expand capacity.