Give AI agents only the authority they need. Prove it when they act.
OAAF is an open interoperability framework for carrying, enforcing, and verifying delegated authority across AI agents and tools.
Agent requests:
github.merge_pull_request
Credentials:
valid GitHub access β
Delegated authority:
github.read
github.write
github.create_pull_request
Decision:
DENY
Reason:
tool_not_authorized
The credential could merge. The authority could not. That is the simple problem OAAF solves β and OAAF does not introduce another competing authorization protocol to do it.
No account. No hosted service. No API key.
git clone https://github.com/espradley/oaaf.git
cd oaaf
npm install
npm run demo:crossdemo:cross enforces the same delegated authority across both an MCP tool call and an A2A
agent handoff β allowing what was delegated and denying what was not:
SAME AUTHORITY
Alice β Bob
narrowed to repo.read
β
ββββββββ΄βββββββ
βΌ βΌ
MCP A2A
Agent β Tool Agent β Agent
read ALLOW read ALLOW
merge DENY merge DENY
The authority does not belong to MCP. It does not belong to A2A. It does not belong to a particular agent framework. It travels with the agent's authority, and OAAF verifies it the same way regardless of the transport it arrives on.
The clone above is for trying OAAF. To use it, install the published package:
# TypeScript / JavaScript
npm install @oaaf/sdk
# Python
pip install oaafIf you maintain an MCP server or gateway, start with examples/mcp-tool-guard β it answers "where does OAAF sit in my request path?" in about five minutes.
Agent systems today express what an agent may do with an API key, an OAuth token, a service account, a tool allow-list, or application config. Those describe what the credential or process can access. They do not answer the question that matters for an autonomous agent:
What is this agent authorized to do for this delegated task?
Credentials are issued to the process, not to the intent β so an agent almost always holds broader access than the task in front of it requires. Delegation makes it concrete:
Agent Alice
authority:
repo.read
repo.write
repo.merge
β delegates review
βΌ
Agent Bob
authority:
repo.read
repo.comment
repo.read β ALLOW
repo.comment β ALLOW
repo.merge β DENY (Bob was never delegated it)
OAAF verifies that Bob's presented authority genuinely narrows from Alice's, cryptographically, before anything consequential happens. It says nothing about why Bob was chosen, what happens next, or how the work is coordinated β those are not authority questions.
The model may decide what it wants to do. The authority layer decides what it is permitted to do.
OAAF assumes the agent may be prompt-injected, compromised, buggy, confused, or simply operating with credentials broader than its delegated authority. The enforcement point never relies on the agent restraining itself, and it fails closed: authority that is unverifiable, expired, revoked, or malformed denies the action.
Agent requests action
β
βΌ
OAAF Enforcement Point
β
βββ verify delegated authority
βββ verify proof of possession
βββ verify identity binding
βββ enforce narrowing / attenuation
βββ evaluate constraints
βββ check status / revocation
βββ produce verified authority facts
β
VALID / DENY
β
βΌ
Existing authorization / PDP
β
ALLOW / DENY
β
βΌ
Consequential action
An enforcement point is whatever sits immediately before a consequential action β MCP middleware, a tool gateway, an A2A agent, an agent runtime, an API gateway, a Git proxy. It is an architectural role, not a hosted OAAF service you have to buy or run.
OAAF sits in front of your policy engine, not instead of it. Two questions, two owners:
OAAF asks: Your organization asks:
"Is the delegated authority "Does our policy permit
valid?" this action?"
OAAF
authorityVerified = true
β
βΌ
Organization PDP
β
βΌ
DENY β legitimate
A valid authority chain can still be denied on policy β that is intentional. OAAF conveys verified authority facts into the request context; the organization's PDP still owns the policy decision. OAAF profiles AuthZEN as the decision model here rather than competing with it, and works alongside OPA, Cedar, and other engines (RFC-0006).
OAAF covers the two boundaries agents actually cross:
Agent β Tool MCP (RFC-0002, COAZ / AuthZEN)
Agent β Agent A2A (RFC-0003, A2A extension)
The underlying authority semantics are transport-independent β the same chain verifies the same way β while each binding is standards-specific. OAAF does not assume MCP and A2A share an authorization model; it maps each into its own binding and preserves the authority decision across both (certified as transport equivalence).
OAAF introduces no wire format of its own. Most of the primitives already exist; OAAF makes them work together across an agent boundary.
EXISTING STANDARDS
ββββββββββββββββββββββββββββββββββββββββββ
Identity SPIFFE / WIMSE / OIDC
Delegation Attenuating Authorization Tokens (AAT)
Decisions AuthZEN
MCP auth COAZ
Evidence Signed receipts
A2A transport A2A extensions
β
βΌ
OAAF
ββββββββββββββββββββββββββββββββββββββββββ
Profiles Β· Bindings Β· Enforcement Β· Verification
Explainability Β· Conformance Β· Developer tooling
Where a standard already solves something, OAAF adopts or profiles it β the reasoning is in ADR-0003, and how OAAF engages with each standard (and how to raise an interoperability discrepancy) is in docs/standards.md.
The OAAF Core 1.0 interoperability contract is frozen, and defined independently of the TypeScript and Python reference implementations β so a Go, Rust, or Java implementation can target it without importing any OAAF code. The frozen artifact set (What is OAAF 1.0?, hash-pinned by a freeze manifest):
- normative Core requirements;
- AAT compatibility profile;
- normative reason codes;
- portable conformance corpus;
- implementation-independent runner protocol;
- optional profile definitions;
- adversarial security evidence;
- compatibility policy;
- the freeze manifest.
The contract is Core 1.0 (frozen). The reference packages are versioned separately (
@oaaf/sdkandoaafare0.x) β see the compatibility policy.
Any implementation β in any language β proves conformance without importing OAAF code, by answering a small adapter protocol over the portable corpus:
node scripts/oaaf-conform.mjs --adapter "<your adapter>" --profile CoreRepresentative output:
OAAF Core + Status + Identity + A2A + MCP + PDP 0.1
Corpus 0.1 (sha256:β¦)
Manifest 1.0 frozen (sha256:β¦)
51 applicable vectors
51 passed
0 failed
CONFORMANT
(self-declared, self-verified against the corpus above)
Conformance is self-declared and self-verifiable. OAAF does not certify implementations and
operates no certification authority β the machine-readable output (--json) is clean evidence a
reader can reproduce. Both the TypeScript and Python reference implementations pass the corpus.
- OAAF has adversarial security certification derived from its normative security invariants β 41 attacks tied back to the 44 security invariants, in every attack family: authority widening, chain manipulation, cryptographic attacks, proof-of-possession failures, identity/recipient substitution, validity/revocation behavior, transport-equivalence attacks, privacy leakage, and malformed inputs (security certification).
- OAAF has not yet undergone an independent professional third-party security audit.
Those are two different claims, and both are stated plainly. To report a vulnerability, see SECURITY.md (private reporting).
OAAF does not conflate four things that agent systems usually merge into one:
WHO IS THE ACTOR? subject (SPIFFE / WIMSE / OIDC)
HOW WAS IT AUTHENTICATED? external credential (an SVID / OIDC token β never in OAAF)
WHO POSSESSES THIS AUTHORITY? proof-of-possession key
WHAT MAY IT DO? authority (the delegated grant)
Identity providers establish who the actor is; OAAF verifies what authority the actor presents and that it is bound to the right key. Workload-identity systems are complementary, not replaced (RFC-0005).
- MCP server maintainers β scope authority around consequential tools; a request that exceeds its delegated authority is denied before the tool runs.
- A2A implementers β make the narrowing across an agent handoff cryptographically verifiable.
- Agent framework / runtime authors β a transport-neutral place to enforce what an agent may do.
- Tool gateway / proxy maintainers β enforce delegated authority at the boundary you already own.
- Security / IAM teams β evaluate what autonomous agents may actually do, with fail-closed defaults.
- Not another authorization wire protocol
- Not an agent framework
- Not a model
- Not an IAM replacement (it sits above workload identity and integrates with it)
- Not an orchestration engine, a workflow engine, or a scheduler
- Not an AI-workforce product
- Not DigitalStack360, and not an open-source edition of it
OAAF deliberately does not decide which agent should do the work, what happens next, how work is prioritized, how much capacity exists, when execution should recover, who should take over, or what organizational context to supply. Those are real problems that belong to products built on top of OAAF. The boundary is written down in CHARTER.md and enforced in CI.
All run from a fresh clone, offline, with no credentials:
npm run demo # a delegated agent refused a path it gave up
npm run demo:mcp # OAAF as a precondition on an MCP tools/call
npm run demo:a2a # OAAF enforcement over an A2A message
npm run demo:cross # the same authority, same result, across transports
npm run demo:pdp # OAAF in front of an existing PDP (valid authority, org still denies)
npm run inspect -- --example allow # exit 0 (ALLOW)
npm run inspect -- --example deny-argument # prints the denial; exit 1 (DENY), by designThe inspector exits 0 for ALLOW and 1 for DENY β a non-zero exit on a deny-* example is the
decision, not an error.
| Area | Current state |
|---|---|
| OAAF Core | 1.0 interoperability contract frozen (what that means) |
| TypeScript SDK | Published as @oaaf/sdk (0.x) |
| Python | Published as oaaf (0.x) |
| MCP / COAZ | Implemented and conformance-tested (RFC-0002) |
| A2A | Implemented and conformance-tested (RFC-0003) |
| PDP interoperability | AuthZEN-compatible authority context; existing-PDP coexistence (RFC-0006) |
| Identity | SPIFFE / WIMSE / OIDC-compatible identity-binding model (RFC-0005) |
| Revocation / status | Implemented with profile-specific semantics (RFC-0004) |
| Conformance | Portable corpus + implementation-independent runner |
| Cross-language | TypeScript + Python reference implementations |
| Security | Normative security-invariant + adversarial suite |
| Independent professional audit | Not yet performed |
| External adopters | Early stage β independent evidence still being built (ADOPTERS.md is empty by design) |
| Governance | Founder-led, public RFC process |
OAAF wants interoperability reports, standards-interpretation feedback, independent conformance adapters, real integration examples, security findings, documentation improvements, and implementations in additional languages.
- CONTRIBUTING.md Β· RFC process Β· docs/standards.md Β· Discussions
- Open
help wantedissues include an independent Go/Rust conformance adapter, AuthZEN interop testing, and a real-world MCP integration.
- β Star the project if it is useful.
- π§© Tell us what you're integrating.
- π Report interoperability problems.
- π€ Contribute an implementation, adapter, test, or standards finding.
- π£ Using OAAF in a real project? Consider the voluntary adopter process.
No telemetry, no phone-home, no install-time promotional hooks β participation is voluntary, and a star is a visibility signal, not adoption certification.
Maintained by Edwin Digital LLC, founder-led today and designed to evolve: GOVERNANCE Β· CONTRIBUTING Β· SECURITY Β· versioning & compatibility Β· standards Β· adoption journey.
Apache License 2.0. Maintained by Edwin Digital LLC as initial steward.