agents need authority at runtime.
scoped grants in · signed receipts out.
- 01 human approval scoped at one moment
- 02 grant scope · ttl · budget
- 03 agent tree delegates, attenuates
Compose with any orchestrator, sandbox, or protocol. Emberlink is the authority root below all of them.
the permission primitive changes from account access to task authority.
Human IAM was built for people clicking software. Agents need authority that follows the job, not the seat.
- Repo token
- Model API key
- Cloud CLI session
- Long-lived budget
- Vendor-local logs
- Repo + job scope
- Model scope & spend cap
- Tool scope & wall clock
- Bounded spend, revoke
- Signed receipt, evidence stream
The question is no longer "who has repo access?"
It is "what job was this agent authorized to do, by whom?"
developers using AI are exposed today.
They paste raw API keys into files the AI can read. There's no other option.
# keep me out of git
ANTHROPIC_API_KEY=sk-ant-•••••••••••••••
GITHUB_TOKEN=ghp_••••••••••••••••••••
AWS_SECRET_ACCESS_KEY=•••••••••••••••••
- standing keys.
- no receipt.
- no clean revoke.
with emberlink, the agent never holds your raw keys.
- anthropic
- session cap
- github
- write
- aws
- assumeRole
- 01 bounded by scope, spend, and clock
- 02 agent acts under the slip
- 03 receipt signs the result
install in 60 seconds · same workflow · now signed.
install in 60 seconds.
One binary. No cloud. No account. apache-2.0.
what install.sh does
- detects your OS + architecture (macOS / Linux, x86_64 / aarch64)
- fetches the signed
emberbinary fromgithub.com/emberdotlink/emberlink/releases - verifies sha256 against the GitHub-published manifest
- installs to
~/.local/bin/ember— no sudo, no cloud, no account - downloads the cosign signature + cert alongside for offline verification
$ curl -sSf https://emberlink.sh | sh
$ ember init --for claude-code
$ ember claude-code
a receipt is the human's signature on machine action.
One human approved one task. The agent did the work. The daemon signed what happened. Verify it offline — same algorithm ember receipt verify runs locally.
- type
- grant-receipt-v2
- approved_by
- jhud@ember.local
- agent
- claude_code
- service
- github
- authorized
github:pull_request:createonemberdotlink/landing- bounded by
- 30 min wall clock
- observed
pull_request_created→emberdotlink/landing#42- ended
- revoked by operator at +26 min
9a15b3c847f10f28c4ae394e24b297a04bd30ff5d86eee5dae72a34646e93ff5
ed25519 · published out-of-band · the verify below refuses any receipt not signed by this key
$ ember receipt export rct_01JCK4QH8X8WMNK5RDXJ2VT9P0
{
"id": "rct_01JCK4QH8X8WMNK5RDXJ2VT9P0",
"grant_id": "grant_01JCK4QH8X8WMNK5RDXJ2VT9P0",
"summary": {
"human_owner": "jhud@ember.local",
"persona_id": "persona-claude-code",
"agent_id": "claude_code",
"service": "github",
"resource": "emberdotlink/landing"
},
"approved_chain": [
{
"block": {
"statements": [
{
"sid": "github_pr",
"resource_type": "credential",
"actions": [
"github:pull_request:create"
],
"resource": {
"kind": "exact",
"value": "emberdotlink/landing"
},
"budget": {
"wall_clock_secs": 1800
},
"usage": {
"tokens": 0,
"cents": 0,
"requests": 4,
"workload_hours": 0,
"wall_clock_secs": 1574,
"last_updated": 1715296010
}
}
],
"expires_at": 1715296380,
"issued_by": "persona-claude-code",
"issued_at": 1715294580
},
"pubkey_next": "9041016c391b2e86…3035503d",
"signature": "2427d29ddbacdf29…4199c502"
}
],
"per_statement_usage": [
[
"github_pr",
{
"tokens": 0,
"cents": 0,
"requests": 4,
"workload_hours": 0,
"wall_clock_secs": 1574,
"last_updated": 1715296010
}
]
],
"approval_chain": [
{
"at": 1715294580,
"actor": "human_dashboard",
"outcome": "approved",
"reason": null
}
],
"actions_observed": [
{
"at": 1715296010,
"event": "pull_request_created",
"action": "github:pull_request:create",
"resource": "emberdotlink/landing#42",
"outcome": "allowed"
}
],
"lifecycle": {
"issued_at": 1715294580,
"last_used_at": 1715296010,
"terminated_at": 1715296154,
"terminal_reason": {
"kind": "revoked",
"by": "operator",
"reason": ""
}
},
"attestation": {
"status": "unattested_local_dev"
},
"evidence": {
"hash": "5d8428dcddfdd596…a5d66268",
"sig": "43acb6e1797fc920…55728a0f",
"signer_pubkey": "9a15b3c847f10f28…46e93ff5",
"canonical_version": 1
}
}
authority attenuates. it never expands.
A parent grant can spawn child grants, but every child inherits no more than the parent. Same primitive whether one agent acts or fifty coordinate.
revoke the parent the whole tree dies.
same native workflow
Coding agents are the first place this breaks. Developers already let agents touch real tools. Emberlink keeps the workflow native while moving authority out of secrets and into grants.
like apple pay. but for AI.
three separate parties. one signed approval.
same mechanism on tape: bound approval, live action, revoke mid-flight, surviving receipt.
watch the demo