Agent Control Protocol: Admission Control for Agent Actions
Organizations: TraslaIA
Abstract
Autonomous agents can produce harmful behavioral patterns from individually valid requests -- a threat class per-request policy evaluation cannot address, because stateless engines evaluate each request in isolation. We present ACP, a temporal admission control protocol enforcing behavioral properties over execution traces via static risk scoring combined with stateful signals (anomaly accumulation, cooldown) through a LedgerQuerier abstraction. ACP blocks execution based on deterministic, history-aware risk scoring -- not anomaly detection. Under a 500-request workload where every request is individually valid (RS=35), a stateless engine approves all 500; ACP limits autonomous execution to 2 out of 500 (0.4%), escalating after 3 actions and denying after 11. We identify a state-mixing vulnerability in ACP-RISK-2.0 (cross-context false denials) and introduce ACP-RISK-3.0, scoping anomaly signals to PatternKey(agentID, capability, resource). Decision evaluation: 739-832 ns (p50); throughput 1,720,000 req/s. Safety and liveness model-checked via TLA+ (11 invariants + 4 temporal properties, 0 violations) across 4,294,930,695 distinct states. We formalize deviation collapse -- enforcement active but never exercised due to upstream constraints -- and introduce Boundary Activation Rate (BAR) as its detection mechanism. An adversary suppressing BAR to 0.00 is detected via DeltaBAR before collapse (BAR_C=1.00). N coordinated agents accumulate risk independently; coordination window CW_appr=2N with zero deviation: activity scales linearly, preventing superlinear amplification. ACP is Paper 1 of a 6-paper Agent Governance Series: P0 -- atomic decision boundaries; P2 -- behavioral drift detection (IML); P3/4 -- governance structure, fair allocation, and irreducibility; P5 -- runtime execution validity (RAM, arXiv:2604.22898); P6 -- operationalization of RAM.
Figures & tables
| Criterion | RBAC | Zero Trust | ACP |
|---|---|---|---|
| Designed for | Human roles | Network access | Autonomous agents |
| Cryptographic identity | No | Partial | Yes (Ed25519, mandatory) |
| Verifiable dynamic delegation | No | No | Yes (chained, auditable) |
| Decision/execution separation | No | No | Yes (Execution Tokens) |
| Real-time risk evaluation | No | Partial | Yes (deterministic) |
| Multi-institutional auditing | Non-standard | Non-standard | Native (signed ledger) |
| Dimension | AgentSpec | ACP (this work) |
|---|---|---|
| Enforcement granularity | Property-based rules over tool calls (LTL-style constraints). | Admission control with risk scoring and stateful signals. |
| Threat model | Compliance with operator-defined safety properties. | Adversarial admission control + governance collapse detection (BAR-Monitor). |
| Deviation collapse detection | No equivalent to BAR-Monitor. If upstream constraints are relaxed, all decisions become compliant silently. | BAR-Monitor detects this regime explicitly; TREND alert fires before collapse. |
| Composability | Operates adjacent to the prompt layer (tool call interception). | Operates at the execution layer; composable with AgentSpec. |
| Formal verification | Policy synthesis proved correct (AgentSpec properties). | Safety and liveness model-checked in TLA+ (11 invariants, 5,684,342 states, 0 violations). |
| Property | RBAC | ABAC | OPA | Cedar | MCP/A2A | ACP (this work) |
| Stateful decisions | ✓ | |||||
| Deterministic evaluation | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Auditability | partial | partial | partial | partial | ✓ | |
| Runtime enforcement | ✓ | ✓ | ✓ | ✓ | partial | ✓ |
| Temporal behavior | ✓ | |||||
| External verifiability | partial ∗ | partial ∗ | partial ∗ | partial ∗ | ✓ |
| Field | Type | Description |
|---|---|---|
| AgentID | String (43–44 chars) | base58(SHA-256(pk)) . Derived from public key. Immutable. |
| capabilities | List of strings | Explicit permissions. Format: acp:cap:<domain>.<action> . Never abstract roles. |
| autonomy_level | Integer 0–4 | Determines risk evaluation thresholds. 0 = no autonomy. 4 = maximum. |
| state | Enum | active | restricted | suspended | revoked . Transition to revoked is unidirectional. |
| limits | Object | Rate limits, maximum amounts, time windows. Not modifiable at runtime. |
| Abstract (Paper 0) | ACP instantiation |
|---|---|
| State | held by the LedgerQuerier |
| Action | Incoming capability request carrying (AgentID, cap[], res, exp, nonce, sig) |
| Decision function | evaluate : verify signature score risk compare thresholds return APPROVED / DENIED / ESCALATED |
| APPROVED : emit Capability Token + append ledger entry; | |
| DENIED : no token emitted; ledger records denial; | |
| ESCALATED : request placed in audit queue pending supervisor resolution; |
| Factor | Description | Example values |
|---|---|---|
| Baseline by capability | *.read = 0 , financial.payment = 35 | |
| Request context | Non-corporate IP ; outside hours | |
| Agent history (24h) | Recent denial ; anomalous frequency | |
| Resource classification | public = 0 ; sensitive = 15 ; restricted = 45 |
| Category | Threat | Mitigation in ACP |
|---|---|---|
| Spoofing | AgentID impersonation | . Without valid signature immediate DENIED. |
| Tampering | Token or event alteration | Ed25519 covers all fields. Chained ledger: altering one event invalidates all subsequent. |
| Repudiation | Agent denies executed action | ActionRequest digitally signed. Non-repudiation by design. |
| Info Disclosure | Capability exposure | Tokens reveal only the necessary subset. Channel confidentiality via TLS. |
| DoS | Request flooding | Rate limits per agent_id . Anomalous frequency control. |
| Elevation | Delegation that expands privileges | . Cryptographically verified at each hop. |
| Level | Required documents | Enabled capability |
|---|---|---|
| L1 — CORE | ACP-SIGN-1.0, ACP-CT-1.0, ACP-HP-1.0 | Token issuance with cryptographic PoP |
| L2 — SECURITY | L1 + ACP-RISK-3.0, ACP-REV-1.0, ACP-ITA-1.0 | Risk eval (context-scoped F_anom + Cooldown), transitive revocation, ITA |
| L3 — FULL | L2 + ACP-API-1.0, ACP-EXEC-1.0, ACP-LEDGER-1.3 | Complete verifiable auditing |
| L4 — EXTENDED | L3 + ACP-PAY-1.0, ACP-NOTIFY-1.0, ACP-DISC-1.0, … | Full governance suite |
| L5 — DECENTRAL. | L4 + ACP-D suite | Federation without central ITA |
| Level | Document | Title |
| L1 | ACP-SIGN-1.0 | Serialization and Signature |
| L1 | ACP-AGENT-1.0 | Agent Identity |
| L1 | ACP-CT-1.0 | Capability Tokens |
| L1 | ACP-CAP-REG-1.0 | Capability Registry |
| L1 | ACP-HP-1.0 | Handshake / Proof-of-Possession |
| L1 | ACP-DCMA-1.1 | Delegated Chain Multi-Agent |
| Package | Spec | Level |
|---|---|---|
| pkg/crypto | ACP-SIGN-1.0 + ACP-AGENT-1.0 | L1 |
| pkg/sign2 | ACP-SIGN-2.0 (Ed25519 + ML-DSA-65) | L1 |
| pkg/tokens | ACP-CT-1.0 | L1 |
| pkg/registry | ACP-CAP-REG-1.0 | L1 |
| pkg/handshake | ACP-HP-1.0 | L1 |
| pkg/delegation | ACP-DCMA-1.1 | L1 |
| Suite | Positive | Negative | Spec |
|---|---|---|---|
| CORE (SIGN, CT, HP) | 4 | 4 | L1 |
| DCMA | 2 | 2 | L1 |
| HP | 2 | 8 | L1 |
| LEDGER | 3 | 8 | L3 |
| EXEC | 2 | 7 | L3 |
| PROV | 2 | 7 | L1 |
| Scenario | ns/op | B/op | allocs/op | Path |
| Evaluate (clean state) | 739 | 280 | 5 | full RS |
| Evaluate (with history) | 803 | 280 | 5 | full RS |
| Evaluate (all 3 F_anom rules) | 832 | 296 | 5 | full RS |
| Evaluate (COOLDOWN short-circuit) | 78 | 112 | 1 | Step 2 exit |
| Throughput under concurrent load (InMemoryQuerier, 10 workers) | ||||
| 10 concurrent agents | 581 | — | — | 1,722,000 req/s |
| Workers | ns/op | req/s | Observation |
|---|---|---|---|
| 10 | 1,087 | 920,161 | Baseline concurrency |
| 100 | 1,282 | 780,250 | Moderate contention |
| 500 | 1,404 | 712,259 | High contention |
| Distinct agents | ns/op | req/s | Bottleneck |
|---|---|---|---|
| 1 | 84,791 | 11,794 | O( ) scan + per-key contention |
| 100 | 12,533 | 79,789 | State distributed, short lists |
| 1,000 | 12,628 | 79,190 | Shared mutex ceiling |
| Vector | Behavior tested | Result |
|---|---|---|
| SEQ-BENIGN-001 | No false positives under repeated reads | PASS |
| SEQ-BOUNDARY-001 | Exact thresholds RS = 0, 25, 35, 40, 70 | PASS |
| SEQ-PRIVJUMP-001 | Low→high privilege jump caught immediately | PASS |
| SEQ-FANOM-RULE3-001 | Pattern count adds at step 4 | PASS |
| SEQ-COOLDOWN-001 | 3 DENIED in 10 min → cooldown active | PASS |
| Total | 5/5 PASS |
| Metric | Value |
|---|---|
| Total requests | 500 |
| Approved before cooldown | 2 |
| Real DENIED before cooldown | 3 |
| Cooldown-blocked | 495 |
| Requests processed before first block | 5 |
| Throughput | 815,927 req/s |
| Agents | Total requests | Real DENIED | Cooldown-blocked | Throughput |
|---|---|---|---|---|
| 100 | 1,000 | 300 | 700 | 478,881 req/s |
| 500 | 5,000 | 1,500 | 3,500 | 154,111 req/s |
| 1,000 | 10,000 | 3,000 | 7,000 | 223,376 req/s |
| Backend | RTTs/req | Throughput (req/s) | Duration | Relative † |
|---|---|---|---|---|
| InMemoryQuerier | 1 | 376,000 171,000 | 31 ms 13 ms | 1.0 |
| RedisQuerier (unpipelined) | 7–8 | 2,300 230 | 4.3 s 0.4 s | 0.006 |
| RedisPipelinedQuerier | 2 | 4,200 470 | 2.4 s 0.3 s | 1.8 |
| Injected latency/call | Total latency/req | Throughput (req/s) | Scenario |
|---|---|---|---|
| 0 µs (InMemoryQuerier) | 0 µs | 920,000 | Process-local baseline |
| 250 µs | 1 ms | 4,100 | Fast datacenter |
| 1 ms | 4 ms | 1,600 | Busy backend |
| 5 ms | 20 ms | 470 | Cross-datacenter |
| Case | Requests | ESCALATED | DENIED | Cooldown-blocked |
|---|---|---|---|---|
| Normal baseline (Case 1) | 10 | 0 | 0 | 0 |
| Sequential replay (Case 2) | 10 | 3 | 3 | 4 |
| Concurrent replay (Case 3) | 20 | 3 | 3 | 14 |
| Near-identical replay (Case 4) | 10 | 10 | 0 | 0 |
| Engine | Auto. Exec. | Non-Approved | Early Signal | Enforcement Latency |
|---|---|---|---|---|
| Stateless | 100% (500/500) | 0% | ||
| ACP (stateful) | 0.4% (2/500) | 99.6% (498/500) | 3 actions | 11 actions |
| Engine | APPROVED | ESCALATED | DENIED | COOLDOWN |
|---|---|---|---|---|
| Stateless | 500 | 0 | 0 | 0 |
| ACP | 2 | 8 | 3 | 487 |
| Condition | Prior requests | RS | F_anom | Rule 1 | Decision |
|---|---|---|---|---|---|
| Control (clean state) | 0 | 50 | 0 | × | ESCALATED |
| Phase 2 (contaminated) | 11 | 70 | 20 | ✓ | DENIED |
| Scenario | Model | RS | Decision |
|---|---|---|---|
| Clean context | RISK-2.0 | 50 | ESCALATED |
| Clean context | RISK-3.0 | 50 | ESCALATED |
| State-mixing attack | RISK-2.0 | 70 | DENIED |
| State-mixing attack | RISK-3.0 | 50 | ESCALATED |
| Repeated single-context (11 req) | RISK-2.0 | 85 | DENIED |
| Repeated single-context (11 req) | RISK-3.0 | 85 | DENIED |
| Step | Context | pattern_count[A1] | BaseRisk | Decision | |
|---|---|---|---|---|---|
| 1 | (read, public) | 1 | 0 | 0 | approved |
| 2 | (read, public) | 2 | 0 | 0 | approved |
| 3 | (read, public) | 3 (= threshold) | 0 | 0 | approved |
| 4 | (write, sensitive) | 3 (inherited) | 50 | +25 | denied |
| Item | Status |
|---|---|
| Core specs (L1–L4), 38 documents | Complete |
| Go reference implementation (23 packages) | Complete |
| Conformance test vectors (73 signed + 65 unsigned RISK-2.0) | Complete |
| OpenAPI 3.1.0 ( openapi/acp-api-1.0.yaml , 18 endpoints) | Complete |
| Python SDK ( impl/python/ ) | Complete (L1 + full API client) |
| Docker image ( ghcr.io/chelof100/acp-server:latest ) | Complete |
| Vector ID | Steps | Behavior Tested | Key Invariant |
|---|---|---|---|
| SEQ-BENIGN-001 | 3 | Benign repeated reads | Baseline: RS=0, no state buildup |
| SEQ-BOUNDARY-001 | 3 | RS boundary conditions | Exact thresholds: 0, 25, 35, 40, 70 |
| SEQ-PRIVJUMP-001 | 2 | Low-risk → high-risk jump | No residual benefit from prior APPROVED |
| SEQ-FANOM-RULE3-001 | 4 | F_anom Rule 3 activation | Pattern count at step 4 adds |
| SEQ-COOLDOWN-001 | 4 | Cooldown trigger and block | 3 DENIED in 10 min → cooldown active |
| TLA+ variable | Runner field | Engine field |
|---|---|---|
| capability , resource | RunnerRequest | EvalRequest |
| risk_score | risk_score | RSFinal |
| decision | decision | Decision |
| ledger | (audit log) | InMemoryQuerier events |
| cooldown | denied_reason | CooldownActive() |
| Phase | APPROVED | ESCALATED | DENIED | BAR |
|---|---|---|---|---|
| A (Baseline) | 0.30 | 0.35 | 0.35 | 0.70 |
| B (Sanitized) | 1.00 | 0.00 | 0.00 | 0.00 collapse |
| C (Counterfactual) | 0.00 | 0.00 | 1.00 | 1.00 restored |
| Batch | Drift | BAR | Alert | |
|---|---|---|---|---|
| 1 | 0 0% | 0.70 | — | |
| 2 | 25% | 0.57 | TREND early warning | |
| 3 | 50% | 0.33 | TREND | |
| 4 | 75% | 0.10 | TREND | |
| 5 | 100% | 0.00 | THRESHOLD |
| (under attack) | Expected windows to detect | |
|---|---|---|
| (full evasion) | 1 | |
| 1.1 | ||
| (= ) | 2 | |
| 4 |
| Batch | Evasion% | BAR | Alert | |
|---|---|---|---|---|
| 1 | 0.70 | — | ||
| 2 | 0.57 | TREND early warning | ||
| 3 | 0.33 | TREND | ||
| 4 | 0.10 | TREND | ||
| 5 | 0.00 | THRESHOLD |
| Config | Label | APPROVED | DENIED |
|---|---|---|---|
| T1 | strict | 29 | 60 |
| T2 | moderate– | 34 | 65 |
| T3 | default | 39 | 70 |
| T4 | moderate+ | 44 | 75 |
| T5 | relaxed | 49 | 80 |
| Config | Label | APPROVED | ESCALATED | DENIED | BAR | False-Denial Rate | Coverage |
|---|---|---|---|---|---|---|---|
| T1 | strict | 5 | 5 | 10 | 0.75 | 0.00 | 0.25 |
| T2 | moderate– | 5 | 7 | 8 | 0.75 | 0.00 | 0.25 |
| T3 | default | 6 | 7 | 7 | 0.70 | 0.00 | 0.30 |
| T4 | moderate+ | 6 | 7 | 7 | 0.70 | 0.00 | 0.30 |
| T5 | relaxed | 8 | 6 | 6 | 0.60 | 0.00 | 0.40 |
| Tool | Capability | Resource Class | Base RS | Decision |
|---|---|---|---|---|
| weather_query | acp:cap:data.read | PUBLIC | 0 | APPROVED |
| user_profile | acp:cap:data.read | SENSITIVE | 15 | APPROVED |
| system_audit | acp:cap:admin.manage | PUBLIC | 60 | ESCALATED |
| fund_transfer | acp:cap:financial.transfer | RESTRICTED | 80 | DENIED |
| Phase | Requests | APPROVED | ESCALATED | DENIED | BAR |
|---|---|---|---|---|---|
| A (Baseline) | 10 | 7 | 2 | 1 | 0.30 |
| B (IPI Chain) | 8 | 0 | 0 | 8 | 1.00 |
| C (Recovery) | 10 | 7 | 0 | 3 | 0.30 |
| Total | 28 | 14 | 2 | 12 | 0.50 |
| Variant | TTB (reqs) | |||
|---|---|---|---|---|
| Sequential | 1 | 2 | 3 | 4 |
| Round-robin | 2 | 4 | 6 | 7 |
| Round-robin | 3 | 6 | 9 | 10 |
| Round-robin | 5 | 10 | 15 | 16 |
| Burst (5 agents) | 5 | 10 | 15 | 4 |
| Scenario | ACP (stateful) | ACP (stateless) | OPA (pure) |
|---|---|---|---|
| A: Single request | ✓ Approved | ✓ Approved | ✓ allow=true |
| B: Frequency limit (10 req) | ✓ Denied | Approved | allow=true |
| C: Cooldown (temporal) | ✓ Cooldown | re-eval each request | no cooldown concept |
| Backend | Throughput | Durability | Recommended use |
|---|---|---|---|
| InMemoryQuerier | 920k req/s | None (process-local) | Dev / conformance testing |
| Redis sorted sets | 4,700 req/s (unpipelined, 7–8 RTTs) | AOF/RDB | Multi-process, low-latency |
| Redis + pipelining | 8,000 req/s (2 RTTs, Exp. 3) | AOF/RDB | High-throughput production |
| Postgres / MySQL | Backend-dependent | Full ACID | Audit-grade persistence |
| Tier | Backend | BAR-Monitor | Ledger integrity | Recommended context |
|---|---|---|---|---|
| 1 | InMemoryQuerier | Optional | Ephemeral (process-local) | Development, conformance, CI |
| 2 | Redis pipelined | Recommended | AOF/RDB persistent | Production, multi-process |
| 3 | Postgres / ACID | Required | Hash-chained audit | High-assurance, regulated industries |
| Profile | CooldownPeriod | CooldownTrigger | AnomalyRule3Y | Expected BAR | Typical context |
|---|---|---|---|---|---|
| Low | 120 s | 5 | 5 † | 0.80–0.95 | Internal dev tools, low-risk automation |
| Medium | 300 s | 3 | 3 | 0.60–0.80 | B2B APIs, typical SaaS agents (default) |
| High | 600 s | 2 | 2 | 0.45–0.65 | Financial systems, regulated industries |
| Critical | 3600 s | 1 | 1 | 0.30–0.50 | Critical infrastructure, high-assurance |
| Aspect | ACP-RISK-2.0 | ACP-RISK-3.0 |
|---|---|---|
| Rule 1 counter key | agentID | PatternKey(agentID, cap, resource) |
| Cross-context isolation | No (state-mixing) | Yes (per-context scoping) |
| EvalRequest fields | unchanged | resource used for PatternKey |
| Ledger key format | per-agent | per-context (SHA-256 hash) |
| Performance overhead | baseline | 50 ns per evaluation (Table 12 ) |
| Conformance vectors | 65 unsigned | 73 signed (superset; both suites pass) |
| Exp | Adversary Class | Outcome | |||
|---|---|---|---|---|---|
| 1 | Cooldown Evasion | black-box | threshold-hugging | 500 | contained |
| 2 | Multi-Agent Flood | black-box | flood+collusion | 1000 | contained |
| 3 | Backend Stress | black-box | flood | 10K | degraded perf |
| 4 | Token Replay | black-box | evasion | 300 | contained |
| 5–8 | State Mixing | formula-aware | evasion | — | fixed in RISK-3.0 |
| 9 | Deviation Collapse | — | upstream drift | — | BAR detects |
Appendix figures & tables3 assets
Supplementary material from the paper’s appendix.
Appendix
| Term | Definition |
|---|---|
| ACR-1.0 | ACP Compliance Runner 1.0. Sequence-based test runner for ACP-RISK-2.0. Distinct from ACP-CR-1.0 (Change Request Process governance document). |
| AgentID | Cryptographic identifier: base58(SHA-256(Ed25519_public_key)) . Immutable and unforgeable. |
| Capability Token (CT) | Signed JSON artifact authorizing an agent to perform specific actions on a defined resource during a limited period. |
| Execution Token (ET) | Single-use artifact issued after an APPROVED decision. Authorizes exactly that action at that moment. |
| ITA | Institutional Trust Anchor. Authoritative registry linking institution_id to institutional Ed25519 public key. |
| RIK | Root Institutional Key. Institution’s Ed25519 key pair held in HSM. |
| Code | Prohibited behavior |
|---|---|
| PROHIB-001 | Approving a request when any evaluation component fails |
| PROHIB-002 | Reusing an already-consumed Execution Token |
| PROHIB-003 | Omitting signature verification on any incoming artifact |
| PROHIB-004 | Treating a not-found token_id as active in a revocation context |
| PROHIB-005 | Allowing state transition from revoked |
| PROHIB-006 | Issuing an ET without a prior APPROVED AuthorizationDecision |
| Component / Signal | TLA+ verified | Empirically tested | Notes |
| Cooldown enforcement | ✓ | ✓ | Temporal property (CooldownExpires) |
| Flood detection (Rule 1) | ✓ | ✓ | Extended model (ACP_Extended.tla) |
| Denial escalation (Rule 2) | ✓ | ✓ | Verified via execution traces |
| Pattern anomaly (Rule 3) | ✓ | ✓ | Context-isolated (patternKey) |
| Context factors ( ) | Abstracted; future formal work | ||
| History factors ( ) | ✓ | Validated via ACR-1.0 traces |
Runtime Enforcement for AI Agents
Runtime enforcement for AI agents checks and constrains actions as they execute, helping prevent unsafe or unauthorized effects.
See all 273 papers