-
Notifications
You must be signed in to change notification settings - Fork 1
Trusted-agent permit drafting (Claude Code + human co-authoring) #1
Description
Observation
The current flow assumes two parties: an untrusted agent requests a permit, and a human in a browser reviews and approves it. But in practice, the common workflow is three parties:
- Human + trusted agent (e.g., Claude Code) — working together in a trusted context
- Untrusted agent — receives a pre-approved permit and executes against it
Today, the human works alongside Claude Code to draft and test capability specs, then hands the result to a downstream agent. The approval URL / browser flow is overkill here — the human is already in the loop during drafting, not reviewing after the fact.
Proposed flow
Trusted context (Claude Code + human) Enclave Untrusted agent
┌─────────────────────────────────┐
│ Human + Claude Code co-author │
│ a capability spec together │
│ │── POST /permit ──►
│ Human approves inline (no │ (already approved
│ browser redirect needed) │ by construction)
│ │
│ Hand permit_id + agent_token │─────────────────────────► execute
│ to the untrusted agent │
└─────────────────────────────────┘
The trusted agent drafts the permit, the human confirms it right there in the terminal, and the untrusted agent gets a pre-scoped permit_id + token. The untrusted agent only ever calls /execute — it never touches /permit or /approve.
What this means for oauth3-skill
The SDK currently bundles the full lifecycle (signup → permit → poll approval → execute). This flow suggests splitting it:
- Provisioning mode (for trusted agents / CLI):
signup+permit+approve+store secret— outputs a permit_id and token - Execution mode (for untrusted agents): takes a permit_id + token, only does
execute+poll
This is closer to how OAuth actually works — token issuance involves the user, the bearer token is handed to the client afterward.
Could also be a CLI
# Trusted agent or human runs:
oauth3 provision --enclave http://localhost:3737 \
--cap '{"type":"scoped-fetch","name":"github","base_url":"https://api.github.com","scope":["/repos/*/issues"]}' \
--secret GITHUB_TOKEN=ghp_...
# → prints permit_id and agent_token
# Untrusted agent uses:
oauth3 execute --permit <id> --token <tok> --code 'await github("GET","/repos/o/r/issues")'Context
This reflects how integration testing actually happens today — human + Claude Code co-authoring specs and testing against a local enclave, then handing results to agents. The current browser-redirect flow adds friction that doesn't match the trust model when a trusted agent is already involved.