Compatibility: Pactmark 0.1.x.

Every effect runs the same gauntlet

Figure 1. Six gates, each with a stable failure code. This sequence runs per effect, not once per run — a grant that was valid two tool calls ago is re-checked before the next one. The single most important property here is that a cached decision is not authority. A long-running agent must query revocation again before its next high-risk reservation or dispatch, which is what makes a kill switch actually kill something.

Policy is default-deny by type

default accepts the literal "deny" and nothing else. There is no configuration, environment variable or convenience helper that flips it. A risk class with no rule is denied. Figure 2. The tool declares; the policy decides. Pactmark ships the R0–R5 scale but deliberately does not define what each class means for your business — that mapping is a host decision that belongs in your control framework.

CapabilityGrant — permission with an expiry

A grant binds tenant, principal, purpose, tool registration, scope, expiry and constraints. It is issued by host code through a GrantIssuer, stored, and re-resolved on every check.
1

Requested, not granted

WorkOrder.requestedCapabilities is an ask. The host decides whether a matching grant exists.
2

Bound to an exact registration

A grant references the tool’s registration digest. Change the tool’s schema, security metadata or implementation version and the old grant no longer matches.
3

Consumed through a one-use reservation

An AuthorizationReservation closes replay and concurrency gaps: two concurrent commands cannot both spend the same one-use permission.
4

Revocable mid-run

Kill switches operate on exact digests. Revocation takes effect at the next reservation or dispatch, not at the next run.
A grant is not a role. If your identity provider says someone is an “admin”, that fact has to be mapped by host code into a concrete, purpose-bound, expiring grant. Pactmark will not infer it.

Credentials never reach the model

Figure 3. SecretRef and ModelCredentialRef are opaque, short-lived and purpose-bound. The adapter resolves the reference immediately before invocation and never persists the value. Redaction here is enforced before export, not configured in a dashboard. The test suites include secret canaries across events, telemetry, evidence, artifacts, HTTP responses and error surfaces.
This reduces exposure. It does not eliminate the secret. A compromised host process or a compromised provider endpoint can still use an authorised value — see Threat model TM-06.

Admission and budgets

Admission reserves before it spends. Reservations are pessimistic: an uncertain model call retains its maximum charge until the outcome is known, so a crash cannot leak budget. Exceeding an admission limit raises KAF_ADMISSION_DENIED — which is one of the few retryable codes, because a quota may free up. Exceeding a model resource profile raises KAF_MODEL_RESOURCE_LIMIT_EXCEEDED, which is not.

Egress is an allowlist, not a filter

External traffic goes through an injected egress broker with normalized exact origins, blocked address classes, DNS and redirect policy, TLS verification, byte and time limits, and credential-to-origin binding. Model or tool content cannot select an undeclared endpoint.

Policy and grants guide

Issuing, scoping, revoking and testing grants in a real application.

Human decisions

What an approval can bind, and the seven things it can never waive.