emberlink the grant warden

the grant warden for ai agents

Make agent authority
verifiable.

AI agents now act across code, data, money, and infrastructure. Emberlink gives them scoped, revocable grants instead of unbounded access, then signs a receipt for every action. The receipt is what's left of your authority once the agent is gone, and it verifies offline against the daemon that signed it.

license
Apache-2.0
written in
Rust
speaks
MCP · Socket · SDK

§1 · the problem

Agents are becoming actors. Actors need authority.

Every useful agent eventually asks for a credential. Claude Code, Cursor, Codex, OpenClaw: today that means handing it your raw GitHub token, your AWS key, the whole .env. The agent can scope nothing. The agent can revoke nothing. Your authority escapes into a process you can no longer reach.

Credentials are the first place ambient authority breaks. They are not the only place. Once the agent has the key it can read what it shouldn't, push to branches it shouldn't, spend money you didn't authorize, send messages you didn't write. Each one is the same failure mode: standing access, no boundary, no trace.

  1. no scope The token that lets the agent push to one branch lets it push to main, delete repos, read your private gists. Nothing enforces what the agent actually needs.
  2. no revoke "Revoke" means editing a file and restarting a shell. Manual, post-hoc, only if you noticed. The token lives in .env until you remember to rotate it.
  3. no proof When something breaks, you have a terminal scrollback and a prayer. No signed record of what the agent called, in what order, with what result. No answer to "did the agent touch production?"

after emberlink

The agent gets a grant. The grant specifies scope, TTL, budget, and persona. The raw credential stays in the Warden's vault, never leaves the daemon. Every action appends to a signed audit chain. When the task ends (or you revoke it), the authority disappears and a signed Grant Receipt records what happened, in canonical form, third-party verifiable.

ember daemon start

§2 · the grant

One primitive. Eight resource classes.

A grant generalizes across every authority an agent acts on: credentials, data scope, actions, spend, communication, delegation, memory, liability. Same envelope, same approval moment, same audit chain, same signed receipt at termination. Today the wedge is credentials. The shape carries the rest.

01 the grant carries

  • scopewhere it may act, to what depth
  • ttlwall-clock expiration
  • budgettokens, dollars, requests, seconds
  • personawhich identity delegates
  • resource_typecredential · data · action · spend · communication · delegation · memory · liability
  • attestationruntime, binary, signer, SPIFFE
  • delegationparent · child · attenuation enforced
  • policy_decisionapproved · narrowed · denied (with reason)

02 shipping today

credential bytes github:push:…
session tokens · dollars · requests anthropic:claude-sonnet
payment cents · per-tx · window x402:any
compute workload-hours · cpu-secs local:workload
time wall-clock seconds agent:wall

Adding the next class (data, communication, delegation, memory, liability) is an enum variant, not a new product. The receipt shape is forward-compatible.

§3 · the artifact

Every composite grant leaves one receipt.

A real composite is below. Three statements (credential, session, time) under one envelope, one approval moment, one signature. The bytes are a real ember receipt export, not synthesized for this page. Download them, run ember receipt verify --file -, and the signature checks against the signer pubkey embedded in the receipt. "I gave my agent the deploy bundle" is one decision, one record, one revoke.

~ ember receipt export rct-f5ad8662-160f-4ec6-8513-871ea9fbc953 composite · 3 statements · ed25519
$ ember receipt export rct-f5ad8662-160f-4ec6-8513-871ea9fbc953
{
  "id":        "rct-f5ad8662-160f-4ec6-8513-871ea9fbc953",
  "grant_id":  "grant-63341bdd-8a89-4c83-93e8-ebf4db240ff6",
  "summary": {
    "persona_id":   "persona-a53da576-9e03-4b68-bfb8-5d9ffdb08571",
    "human_owner":  "live-deploy",
    "agent_id":     "github-sandbox-demo",
    "service":      "github"
  },
  "approved_chain": [{
    "block": {
      "statements": [
        { "sid": "s0-credential",
          "resource_type": "credential",
          "actions":  ["credential:read"],
          "resource": { "kind": "exact", "value": "github-sandbox-demo" }
        },
        { "sid": "s1-session",
          "resource_type": "session",
          "actions":  ["llm:generate"],
          "resource": { "kind": "glob", "pattern": "anthropic/*" },
          "budget":   { "tokens": 50000, "cents": 100 }
        },
        { "sid": "s2-time",
          "resource_type": "time",
          "actions":  ["time:wall_clock"],
          "resource": { "kind": "any" },
          "budget":   { "wall_clock_secs": 1800 }
        }
      ],
      "expires_at": 1777787788,
      "issued_by":  "persona-a53da576-9e03-4b68-bfb8-5d9ffdb08571",
      "issued_at":  1777785988
    },
    "signature": "2427d29ddbacdf296d76c233c45632f6c27acd1d1783ccd95e46338ac9e909c5…"
  }],
  "approval_chain": [{
    "at": 1777785988, "actor": "human_dashboard", "outcome": "approved"
  }],
  "lifecycle": {
    "issued_at":      1777785988,
    "terminated_at":  1777787562,
    "terminal_reason": { "kind": "revoked", "by": "operator" }
  },
  "evidence": {
    "hash":              "247912ef28f13fec6cb9e97d8120087b0098962dd19eed9c1a34fdfb2fb302ac",
    "signer_pubkey":     "2f7e9c48d1801b16326eb6d18a665d41ab9286b418e65dc9db10f74ee30b814c",
    "sig":               "8d38108c7889151498ff9d4a578b27cde0c9701b0add931e501c4c0f5324321c…",
    "canonical_version": 1
  }
}
4,922 bytes · 3 statements · canonical JSON · ed25519 download as PNG ↓

§4 · verify it

Verify offline. Tamper anything, the boundary holds.

The receipt verifies without contacting the daemon, against the signer's public key. Change one byte and the recompute fails. This is what makes the receipt a third-party-portable proof object: the property doesn't depend on us being available, online, or friendly.

~ ember receipt verify offline
$ ember receipt verify --file ./receipt.json
Verified: receipt rct-f5ad8662-160f-4ec6-8513-871ea9fbc953
  Signer pubkey:   2f7e9c48d1801b16326eb6d18a665d41…
  Hash:            247912ef28f13fec6cb9e97d8120087b…
  Canonical:       v1
~ ember receipt verify (tampered) the boundary held
$ ember receipt verify --file ./tampered.json
Verification FAILED: hash mismatch
  receipt says:   247912ef28f13fec6cb9e97d8120087b…
  recomputed:     ac4cf46645d26d558972a679b3b74587…

Logs answer "what did the system do?" Receipts answer "whose authority backed it?" That second question is the only one humans care about, because humans remain the trusted counterparty when agents act on their behalf.

§5 · install

One binary. No cloud. No account.

The Grant Warden runs on your machine. Nothing leaves your device unless you send it. One command to install, one to start, one to launch a Claude Code session through it.

you@grant-warden ~
$ curl -sSf https://emberlink.sh | sh
ember  detected target: aarch64-apple-darwin
ember  installing version: v0.2.28
ok     sha256 verified against GitHub Release manifest
ok     installed ember -> ~/.local/bin/ember

$ ember init --for claude-code
$ ember daemon start --background --install-agent
ember daemon v0.2.28 · the grant warden
socket:    ~/.ember/run/daemon.sock
dashboard: http://localhost:3141
keyring:   ember-daemon  (Keychain)

# pipe the secret in. never on the command line, never in shell history.
$ gh auth token | ember vault add --name github-pat --stdin
$ ember claude-code
session    sess-7a3e9c · persona claude-code-localhost
grant      24h, scope template claude-code-default-v1
proxy      $HTTPS_PROXY → http://localhost:3142
launching  claude

# your `git push` now blocks-and-polls until you tap approve.
# every action terminates in a signed receipt.

Rust-native? cargo install emberlink works too. Source: github.com/emberdotlink/emberlink.

§6 · the dashboard

Every grant. Every persona. Every receipt. In one place.

The Warden runs locally and surfaces a live trust dashboard at localhost:3141. Grants, approvals, receipts, audit timeline. One click to revoke. One click to verify a signature. Real screenshots from a real daemon, not mockups.

Ember dashboard at-a-glance: summary cards (active agents, active grants, pending approvals, audit events), active grants table with one grant against github-sandbox-demo, and the audit timeline showing two grant.minted events
01 At-a-glance: agents, grants, approvals, audit
Grant Receipt detail: summary, lifecycle (issued, terminated, revoked by operator), per-statement usage table, and the ed25519 evidence section with signer pubkey, hash, and signature
02 Receipt detail: summary, lifecycle, evidence
ember status CLI output: daemon running, one persona active, one grant active for github:pull_request:create, no sandboxes, no pending approvals, three recent audit events
03 ember status: the same state, in the terminal

§7 · alongside, not against

Your existing stack handles the routine. Emberlink owns the moment authority is delegated.

We don't replace your vault, your IDP, your tool catalog, or your SIEM. They keep doing what they do. Emberlink sits at the credential boundary (the synchronous gate) and emits the receipt that nobody else is positioned to produce.

a vault

stores secrets at rest.

we add

scoped, time-bound, budgeted authority over them, and a signed record of every release.

an idp

names the agent.

we add

the artifact that proves what the named agent was authorized to do.

a gateway

watches outbound traffic.

we add

the upstream decision: did the authority to make this call exist before the call did?

a siem

collects logs after the fact.

we add

a signed receipt at the moment of authority. your SIEM's input, not its replacement.

Author once. Act forever. Audit always.

the AAA framework · ADR 111

An agent applies judgment and authors a Construct. The Construct does the work, deterministic and bounded. A signed receipt records the evidence. Three acts, two roles, one trust substrate. This is how the company operates and how the product compounds. Bounded authority is the wedge primitive. The signed Grant Receipt is the artifact at every instance. Logs answer "what did the system do?" Receipts answer "whose authority backed it?"