Skip to main content

CLP — Capability Loop Protocol

conformance python node dependencies license

CLP — Capability Loop Protocol

A capability has three stages in its life, and today each one lives in a different ecosystem. It is advertised in agent cards, ANS entries, MCP schemas and ERC-8004 records. It is granted as an OAuth token, a biscuit, a UCAN. It is exercised into a log, an OTel span, a transparency ledger. None of those artifacts reference each other.

The consequence is that a routine audit question has no answer:

Was this action within what was granted, and was the grant within what was advertised?

CLP answers it. One canonical capability, a decidable containment relation over it, and a set of checks that verify the whole chain offline — across formats, with no registry and no trusted third party.

Advertise, grant and exercise, with the containment checks between them

The problem it addresses

In multi-agent systems, instructions injected into a sub-agent propagate upward through the delegation chain and execute with the authority of the most privileged agent in the pipeline. The attack surface grows multiplicatively with pipeline depth.

Prompt injection cannot be reliably eliminated inside current model architectures. CLP does not try. It takes the other half of the problem — an agent's authority — and makes it cryptographically bounded, so that a compromised agent cannot exceed what it holds, and the attempt becomes signed evidence.

$ python examples/demo.py

2. INJECTED: worker tries to send mail
  verdict: REFUSED
    [FAIL] ACTION_WITHIN_GRANT   action exceeds the granted authority
                                 verbs: ['mail.send']

5. ENFORCED: the guard runs the checks BEFORE calling the tool
   refused: verbs not covered
   emails actually sent: 0

The last line is the distinction that matters. A check that runs after the message is sent is an audit record, not a control.

Install

pip install zanii-atn          # Python
npm install @zanii-atn/atn     # Node

The distribution is named for the project; the module is named for the protocol:

import clp                                    # after pip install zanii-atn
import { verifyLoop } from "@zanii-atn/atn";

Neither package has runtime dependencies. Ed25519, RFC 8785 canonicalization and base58btc are implemented in-tree so that verification carries no supply chain of its own.

Running the suite

From a clone, with nothing installed:

python tests/run_interop.py   # cross-language conformance suite, 18 checks
python examples/demo.py       # end-to-end injection scenario

Requires Python 3.10+ and Node 16+.

Scope

CLP is not a capability-token format. Attenuated tokens are a mature and actively standardising area — macaroons, biscuit, UCAN, and draft-niyikiza-oauth-attenuating-agent-tokens at the IETF. Those systems guarantee attenuation syntactically: every delegation hop appends restrictions. None of them decides semantically whether one capability is contained in another, and none does it across formats.

That is the gap CLP fills, which makes each of those formats an input rather than a competitor.

Verification checks

Check Question
GRANT_WITHIN_AD Did the provider grant only what it advertised?
CHAIN_MONOTONIC Does every delegation hop narrow, back to a root authority?
ACTION_WITHIN_GRANT Did the action stay inside its authority?
PROVENANCE_CLEAN Did untrusted input drive an action that forbids it?

Every refusal identifies the dimension that failed and the offending values. A refusal that cannot explain itself is not usable as audit evidence.

Obligations

Controls a grant may carry. Each is opt-in and enforced before the action executes.

Obligation Effect
provenance:trusted-only Every input label must begin trusted:. This is an allowlist, so unlabelled and unrecognised-prefix inputs are refused.
provenance:registered-only Those labels must appear in an owner-signed registry, so mislabelling requires the owner's key rather than a code change.
freshness:<seconds> The verifier must hold a signed checkpoint no older than the window. An unprovable revocation view is refused rather than silently accepted.
review:human Requires an approval signed by a registered approver and bound to that exact action.
jurisdiction:<code> The holder asserts operation within the named jurisdiction.

Repository layout

spec/clp-spec.md        protocol specification
spec/containment.md     the algebra: lattice semantics, completeness proof, decidability
spec/adapters.md        normative mappings from A2A, OAuth 2.1 and Zanii artifacts
spec/threat-model.md    attacker profiles, mitigations, and remaining exposure

impl/python/clp/        reference implementation, standard library only
impl/js/clp.mjs         reference implementation, node:crypto only

tests/                  conformance suite, property tests, golden and adversarial vectors
examples/demo.py        end-to-end injection scenario
docs/                   rendered specification and plan, project assets
tools/                  documentation pipeline and pre-publish secret scanner
archive/                the retired ATN draft; see archive/README.md

Design of the constraint language

Biscuit expresses caveats in Datalog, where deciding whether one policy implies another is intractable. Macaroons provide no comparison operation at all. CLP restricts its constraint language to finite prefix globs, integer ceilings, a single interval and a finite label set, because a restricted language admits a total and inexpensive containment decision — and containment is the only operation the protocol requires.

spec/containment.md contains the completeness proof for pattern-set containment, together with an account of what the restriction cannot express (data-dependent conditions, disjunctive obligations, relative bounds) and why each belongs at a different layer.

Conformance

Given identical seeds, the Python and JavaScript implementations emit byte-identical vector files: the same signatures, hashes, containment decisions, verdicts and enforcement outcomes. Ed25519 is deterministic and RFC 8785 is total, so any divergence is a test failure.

This is a security requirement rather than a stylistic one. If two implementations disagreed about containment, or enforced differently, an attacker would route through the permissive one.

The suite also verifies that adversarial cases are refused at the correct check, that the containment relation is reflexive, antisymmetric and transitive in both languages, that no adapter widens authority during translation, and that a fixed enforcement sequence produces identical artifacts in both implementations.

Relationship to the Zanii platform

CLP composes with the Zanii ledger rather than duplicating it. It uses the same did:key identities, the same RFC 8785 canonicalization and the same sha256:<hex> encoding, so a Zanii delegation certificate maps onto a CLP grant and a Zanii receipt onto a CLP exercise.

The ledger records what happened. CLP constrains what may happen, at the point of delegation. Anchoring a refusal turns an attempted escalation into permanent, timestamped evidence.

Known limitations

Documented in full in spec/threat-model.md §4a.

  • An owner who signs a trust registry naming an unsafe origin, or who grants broadly without review:human, defeats the corresponding control. These decisions are attributable to a key and a date, but they are not preventable.
  • Freshness enforcement requires a revocation feed to exist. CLP makes its absence fail closed; it cannot make it unnecessary.
  • Refusal telemetry identifies the behavioural signature of an agent acting outside its authority. It does not inspect prompts.
  • The pure-Python Ed25519 implementation is reference-grade: correct, not constant-time, and roughly 30 ms per operation. Production signers should use a libsodium-backed library. The JavaScript implementation uses OpenSSL through node:crypto and has neither limitation.

Security

Report vulnerabilities to info@zanii.agency. See SECURITY.md.

Before committing, pushing or sharing an archive of this directory:

python tools/scan_secrets.py

Project history

This repository began as ATN, a broader agent-trust protocol. A review against the existing Zanii ledger showed that ATN reimplemented approximately 85% of functionality already shipped across 60 packages, and did several parts less well. That work is retained under archive/ with the analysis, because the decision to narrow the scope to the capability loop came directly from identifying the one gap the ledger does not fill.

License

Apache-2.0. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zanii_atn-0.1.0.tar.gz (89.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zanii_atn-0.1.0-py3-none-any.whl (50.1 kB view details)

Uploaded Python 3

File details

Details for the file zanii_atn-0.1.0.tar.gz.

File metadata

  • Download URL: zanii_atn-0.1.0.tar.gz
  • Upload date:
  • Size: 89.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.10

File hashes

Hashes for zanii_atn-0.1.0.tar.gz
Algorithm Hash digest
SHA256 34597e739c9d965fa5752af96c3e0c2f1a1dcc056b90e59c93241cac223ab530
MD5 0d462d6f8f783faa3927461e6acf42d5
BLAKE2b-256 33411a3ddff92851aa588028ec948a76834c156785fd92b1bff7635acb05ffa1

See more details on using hashes here.

File details

Details for the file zanii_atn-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: zanii_atn-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 50.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.10

File hashes

Hashes for zanii_atn-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f8e235b8f2c4e765c055cc2d68b512f3a68600c1040e63bf7cb72e0b40388a68
MD5 adecc8952f306122686ed6c9c0975f0f
BLAKE2b-256 26d58dc892b676c633e10b8d4a5e558625366d9fb960edea5932d94da75d678b

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page