> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uselayerup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool Invocation Governance

> Every tool call is mediated by the policy decision point (PDP). The PDP is small, deterministic, and audited. Its rulings are the gating contract between intent and effect.

# 16 — Tool invocation governance.

Every tool call — from a human operator, an integration, or an agent — is mediated by the
policy decision point (PDP). The PDP is small, deterministic, and audited. Its rulings are
the gating contract between intent and effect.

## 16.1  PDP request shape

```json theme={null}
{
  "principal":   { "id": "…", "kind": "agent|human|service", "scopes": [ … ], "clearances": [ … ], "region": "eu-central-1" },
  "tool":        { "id": "tool.<name>", "version": "2.4.1", "effectClass": "stage|commit-low|…", "requiredScopes": [ … ], "purpose": "claims.adjustment" },
  "subject":     { "ref": "claim_…", "marking": [ "pii.medium" ], "regionPin": "eu-central-1" },
  "environment": { "now": "2026-05-28T17:21:00Z", "tenantPolicyVersion": "2026.05" }
}
```

## 16.2  PDP algorithm

The PDP runs a fixed sequence. The first failing step terminates with a typed deny.

```text theme={null}
1. STRUCTURAL
   require: tool registered & enabled
   require: tool version not deprecated
   else → deny(reason=structural)

2. SCOPE INTERSECTION
   require: principal.scopes ⊇ tool.requiredScopes
   require: principal.scopes ⊇ subject.requiredReadScopes
   else → deny(reason=scope)

3. MARKING CLEARANCE
   for each marking in subject.marking:
     require: principal.clearances.allows(marking)
   else → deny(reason=marking)

4. PURPOSE COMPATIBILITY
   require: tool.purpose ∈ marking.allowedPurposes  (∀ marking in subject)
   require: tool.purpose ∉ marking.disallowedPurposes
   else → deny(reason=purpose)

5. REGION
   require: principal.region == subject.regionPin
   require: tool.endpoint.region == subject.regionPin
   else → deny(reason=region)

6. ABAC PREDICATES
   require: every tenant predicate evaluates true
   else → deny(reason=abac)

7. AUTHORITY (effect-bearing tools only)
   require: principal.authority covers (subject, payload)
   else → deny(reason=authority)

8. RATE / BUDGET
   require: principal-and-tool budget not exceeded
   else → deny(reason=budget)

9. ALLOW
```

## 16.3  Rejection taxonomy

| Reason       | Class         | Operator visibility                 |
| ------------ | ------------- | ----------------------------------- |
| `structural` | configuration | operator alert                      |
| `scope`      | permission    | operator alert · principal notified |
| `marking`    | permission    | operator alert · security notified  |
| `purpose`    | permission    | operator alert · security notified  |
| `region`     | compliance    | operator alert · security notified  |
| `abac`       | permission    | operator alert                      |
| `authority`  | policy        | operator alert · authority chain    |
| `budget`     | operations    | operator alert · cost dashboard     |

## 16.4  Dispatch-time audit

Every PDP ruling, allow or deny, is recorded as a typed AuditEvent: `policy.allow` or `policy.deny`. The record includes the request shape, the matched rule path, and the input version of the tenant policy. PDP rulings are immutable; subsequent rulings on the same input are independent records.

## 16.5  Agent scope minimisation

An agent definition declares its required scopes. The platform enforces the minimum: a scope not declared cannot be used at runtime, even if the principal calling the agent holds it. This prevents privilege amplification through agent invocation.

<Warning>
  The effective permission set at any instant equals the minimum of: caller-principal grant, agent declared scopes, subject marking clearance, ABAC predicate satisfaction. Privilege never increases by traversing planes.
</Warning>

## 16.6  Policy as data

Tenant access policies are versioned data, not code. The PDP reads the active version; changes are typed AuditEvents (`policy.update`) on the tenant chain. Rollback is a re-promotion of a prior version.

## 16.7  Latency & caching

The PDP is in-substrate and synchronous. Cache keys are *(principal-version, subject-marking-set, tool-id, tool-version, policy-version)*; cache invalidation is triggered by any of the inputs changing. The PDP target SLO is p99 ≤ 5ms.

## 16.8  Failure-open prohibition

If the PDP cannot reach its policy store or its principal store, it fails closed. Tools cannot dispatch; reasoning runs cannot start; commits cannot complete. This is non-configurable.
