Skip to content

Protocol · authority

Give software a limited, signed permission to act for you.

Scoped, revocable, offline. OC Agent lets a Bitcoin address grant software a narrow permission, and lets anyone check every action it took against that permission.

A delegation · test vector v01
oc-agent:delegation:v1
principal: bc1qprincipal000000000000000000000000000000
agent: bc1qagent0000000000000000000000000000000000
scopes: lock:seal(recipient=bc1qalice000000000000000000000000000000000)
bond_sats: 0
bond_attestation: none
issued_at: 2026-04-22T12:00:00Z
expires_at: 2026-04-29T12:00:00Z
nonce: 0123456789abcdef0123456789abcdef
  • Open spec, MIT
  • No orangecheck account
  • Never holds your keys
  • No server needed to verify

The problem

A shared key does not say who stands behind it.

Software acts for people more every year. A bot posts. A script pays an invoice. An AI agent calls tools.

Today that software usually carries a shared API key or an OAuth token. The key does not say who stands behind it, what exactly it may do, or until when. The only record of what it did sits in the provider’s logs. To revoke it you ask the issuer. To check it you trust the issuer.

How it works

Grant. Act. Check.

  1. 01

    You grant

    You sign one message with your Bitcoin wallet. It names the agent’s Bitcoin address, what it may do, and when the grant ends. What it may do is written as short scope lines, such as ln:send(max_sats<=1000) or stamp:sign(mime=text/markdown). That signed message is the delegation.
  2. 02

    The agent acts

    Each time it does something, the agent signs a small record with its own Bitcoin key: a hash of what it did, when, which delegation it relies on, and which scope it used.
  3. 03

    Anyone checks, and you can stop it

    A verifier checks both signatures, that the action fits inside the grant, and that the grant had not expired or been revoked. To stop an agent early, you sign a revocation and publish it to Nostr.
The Bitcoin it depends on
Both parties are Bitcoin addresses proven by BIP-322 signatures, so no issuer stands in the middle. Optionally, a Bitcoin block (through OpenTimestamps) settles whether an action came before a revocation, and a grant can point to an OC Attest attestation showing the granter has kept coins unspent. The spec calls that reference a bond. The coins never move and nothing can take them.
Three additions build on v1
Sub-delegation lets an agent pass a narrower slice of its grant to another agent. Private scope seals the scope list with OC Lock for the agent and the verifiers you name. Federation principal lets an M-of-N group of keys grant together; its verifier is published, its signing helpers are not built yet.

Where it stands

Open, stable, and free to use.

The OC Agent spec is v1 and stable; its latest revision is 1.4.0 (2026-10-19), and no revision since v1.0 has changed the envelope format. Open spec, MIT. The tools at agent.ochk.io work today and are free. You need a Bitcoin wallet that can sign a message, and no orangecheck account. OC Agent never holds your coins or your keys: your wallet signs, and what you create stays in your browser unless you publish it. orangecheck as a whole is pre-launch.

The spec

oc-agent-protocol

Version
1 (rev. 1.4.0)
Licence
MIT
Nostr kind
30083–30086
Test vectors
26

Try it

What you can do today.

  • A delegation, an action or a revocation. No second wallet? The site can make a throwaway test agent key in your browser.

    agent.ochk.io/app/compose
  • Any delegation, action or revocation.

    agent.ochk.io/app/inspect
  • Kept in this browser, with revoke one click away.

    agent.ochk.io/app
  • As the agent it names.

    agent.ochk.io/app/compose/import
  • Parse a scope, test whether one fits inside another, preview the exact message a wallet signs. Nothing leaves your browser.

    agent.ochk.io/playground

The site does not anchor to a Bitcoin block yet. To anchor actions and revocations, use @orangecheck/stamp-ots in code.

For developers

Build on it.

npm install @orangecheck/agent-signer @orangecheck/agent-core @orangecheck/bip322

Core

@orangecheck/agent-core

canonical messages, the scope grammar, verifyDelegation, verifyAction, verifyRevocation; 2.5.0

Signer

@orangecheck/agent-signer

createDelegation, signAsAgent, revoke, with your own BIP-322 signer; 0.4.0

CLI

@orangecheck/agent-cli

oc-agent verify, inspect, canonical, scope, subscope; 0.2.3

MCP

@orangecheck/agent-mcp

signs an action for every MCP tool call; 0.4.1

Adapters

@orangecheck/agent-anthropic, -openai, -vercel, -langgraph

the same for Claude tool use, OpenAI function calls, the Vercel AI SDK and LangGraph; 1.1.1

import { createDelegation, signAsAgent } from '@orangecheck/agent-signer';

const delegation = await createDelegation({
  principal: { address: 'bc1q…you', signMessage: (m) => wallet.signMessage(m) },
  agentAddress: 'bc1q…agent',
  scopes: ['http:request(origin=https://api.example.com,method=GET)'],
  ttlMs: 7 * 24 * 60 * 60 * 1000, // the signer refuses more than 365 days
});
// agent: { address, signMessage } for the agent's own key
const action = await signAsAgent({ agent, delegation, content: requestBytes,
  mime: 'text/plain', scopeExercised: 'http:request(origin=https://api.example.com,method=GET)' });
verifyAction refuses to answer until you either pass the revocations you fetched or set skipRevocationCheck: true, so “not revoked” never means “never checked”.
Copy-forkable templates are in oc-agent-examples (opens in a new tab): an MCP client and a verifying MCP server, plus one per adapter.

Check one

Verify an agent action someone sent you.

Open the inspector at agent.ochk.io. Paste the JSON or drop a .delegation, .action or .revocation file. An action needs the grant it relies on, so paste both as one array: [delegation, action].

The check runs in your browser with the same library a developer would use. It confirms:

  • each envelope’s id matches its contents, so nothing was edited after signing;
  • the granting address signed the delegation, and the agent’s address signed the action;
  • the action cites this delegation, and its signer is the agent the delegation names;
  • the action was signed inside the grant’s window;
  • the scope used fits inside a scope that was granted;
  • no revocation took effect before the action. The page reads five Nostr relays for revocations and shows how many answered. If none answers, it will not call the action unrevoked.

It shows a stake reference as declared and a block anchor as claimed, without checking either; use @orangecheck/sdk and an OpenTimestamps verifier for those.

For a fully offline check, npx @orangecheck/agent-cli verify does the same from a file and says plainly that it did not look for revocations.

What you trust

Every party you rely on, by name.

The two keys
Your wallet, and whoever holds the agent’s key. A leaked agent key can act within its scope until the grant expires or a verifier sees your revocation.
Nostr relays, for revocations
A verifier learns of a revocation only by finding it on a relay. agent.ochk.io reads and publishes to nos.lol, relay.damus.io, relay.primal.net, offchain.pub and relay.ochk.io, which orangecheck runs. A relay can hide a revocation. It cannot forge one. Publish to several.
OpenTimestamps calendars, if you anchor
@orangecheck/stamp-ots uses alice.btc.calendar.opentimestamps.org, bob.btc.calendar.opentimestamps.org and finney.calendar.eternitywall.com. A calendar must not backdate; the finished proof is checked against Bitcoin block headers.
A chain data source, if you check a stake reference
@orangecheck/sdk reads mempool.space by default. Any Esplora-compatible source, or your own node, works.

No orangecheck server is needed to verify anything. agent.ochk.io is a convenience.

What it is not

The limits, plainly.

Not proof the action happened
It proves the agent signed a statement that it did something. Match the action’s content hash to the real request, payment or post.
Not an instant off switch
A revocation reaches verifiers through relays. Short expiry and tight scopes are the controls that always hold. An action that is not anchored cannot prove it came before a revocation.
Not escrow
A stake reference moves no coins and nothing can be taken. It is a public reputation signal.
Not private by default
A published grant shows both addresses and its scopes. Private scope hides the scope list; the addresses stay visible.

Where it is used

Apps that use it.

No showcase app yet
None of the showcase apps (vault, chat, cosign, the demo) or ochk.app uses OC Agent today. To see it work, use agent.ochk.io or run one of the examples (opens in a new tab).
It composes with the other protocols
Every action is a valid OC Stamp with two extra fields, the stake reference is an OC Attest attestation, private scope uses OC Lock, and registered scopes cover sealing with OC Lock, signing with OC Stamp, voting in OC Vote and creating an OC Pledge.

Grant your first agent.

The tools are free and need no orangecheck account. The spec is open to anyone who wants to build their own.

With thanks to Bram Kanstein, whose work on Bitcoin as a sovereignty layer shaped the premise.