Skip to main content
HUMΛN
Developer
Developer

Delegation Scope Design Guide

HUMΛN Team··10 min·Technical (Builders)

API keys are a god-mode pattern. They mean unlimited access, no attribution, and no expiry — once leaked, the only fix is rotation. That model worked when the only thing holding the key was a server you owned. It does not work when the holder is an AI agent operating on a human's behalf.

HUMΛN replaces API keys with delegation tokens: a signed cryptographic contract that says "this human (or org) grants this agent these specific scopes for this specific window, with these specific constraints." The MCP surface enforces them on every call.

What a delegation actually is

A token has five fields:

Field Meaning
from The principal granting authority (DID — passport or org).
to The principal receiving authority (the agent's DID).
scope The set of capabilities granted, as a list of scope strings.
constraints Optional bounds — rate limits, IP ranges, time windows, value caps.
expires_at A hard expiry; tokens never live forever.

The token is signed with the granter's passport key, so the verifier doesn't need to call HUMΛN to check authenticity — they verify the signature and check the revocation registry.

The MCP scope vocabulary

These are the scopes you'll actually use day-to-day:

Scope Grants Doesn't grant
kb:read:public Read 58 Public-classified docs + Canon Org-internal docs
kb:read:internal Read Internal-classified docs (HUMΛN devs) FoundersOnly
companion:chat Multi-turn human.ask + human.companion.chat, and Companion preferences (/v1/companion/preferences + observe/pending/ack) KB ingest, arbitrary execution without other scopes
human_api:agents:invoke POST /v1/agents/call — the human.call MCP tool (hosted Worker + API use the same scope string) Does not replace per-capability scopes or the risk gate
humanos:read / humanos:write Intent / HumanOS REST routes (what /v1/intent actually checks; MCP human.intent needs humanos:write) Whatever the route policy does not cover
(no call:propose / call:execute scopes) human.call uses a mode field (propose vs execute), not separate delegation strings See below
human_api:passports:read Read passport data Mutate passports
human_api:passports:write Mutate passports Cross-tenant
org:settings:read Read org-level settings Modify
org:settings:write Modify org-level settings Org admin operations
cloud:admin:* Internal HUMΛN team — admin surfaces Anything outside HUMΛN org

There are more (event emit, marketplace, signals) — see the AI corpus article delegation-scope-vocabulary.md for the canonical list.

Principle of least privilege

Start with the smallest grant that lets your agent do something useful:

# A read-only Cursor companion
human delegation mint \
  --to did:agent:my-cursor \
  --scope "kb:read:public companion:chat" \
  --expires-in 30d

Now your agent can answer questions and search the KB. It cannot do anything destructive. If it needs more, expand the scope — don't reach for a wildcard.

human.call is mode-aware (not two scopes)

The most consequential knob is human.call’s mode, not a pair of delegation scopes named call:propose / call:execute (those strings are not minted today).

  • mode: "propose" — surface a plan or dry-run outcome; your UI can still require an explicit approval step before a later execute.
  • mode: "execute" — perform the action; the API risk gate still enforces requires_approval on irreversible work, and plan tier may block cheap tiers from execute paths on the hosted Worker.

For autonomous workflows (cron jobs, daily summaries), execute on reversible operations may be appropriate when policy allows. For interactive tools (Cursor, Claude Code), default to propose first and let the human confirm before execute.

Constraints: the underrated lever

Constraints let you say "yes, but only..." A few useful ones:

{
  "rate_limit": "60/min",
  "value_cap_usd": 100,
  "allowed_capabilities": ["calendar.events.create", "kb:search"],
  "ip_allowlist": ["10.0.0.0/8"]
}

The agent gets the right of way and the speed limit.

Revoking without breaking everything

The Console's Settings → MCP Access page lists every active session. Revoke one and:

  • The KV cache in the MCP Worker drops the session immediately.
  • The API marks the session row revoked.
  • Subsequent calls return 401 with revoked_at in the problem details.
  • Other agents (other rows) keep working.

Revocation is per-session, not per-key. You don't have to rotate one delegation to fix another.

Org-level vs user-level delegation

Most agents act for a specific user. But some — workflows, scheduled jobs, the org's automation runtime — act for the org. Their delegation has from: did:org:... instead of from: did:passport:.... The grant pattern is identical; the audit trail is different (provenance shows which org admin minted it, on whose behalf).

When in doubt: user-level. Org-level should be rare and should always have an admin's name attached in provenance.

Common mistakes

  1. Granting * "just for testing." Never lands as "just for testing." Mint scoped tokens even in dev.
  2. Forgetting expires_at. A token without expiry is an API key with extra steps.
  3. Mixing the same delegation across multiple integrations. Hard to revoke one without breaking the others. One agent → one delegation.
  4. Using cloud:admin:* outside HUMΛN team. This surface is internal-only and gated; if you're not a HUMΛN dev, you'll get 403.

Tooling

  • human delegation mint — create one (CLI).
  • human delegation list — see what you've issued.
  • human delegation revoke <id> — kill it.
  • Console → Settings → Delegations — same surface, click-friendly.
  • Console → Settings → MCP Access — sessions specifically tied to MCP integrations.

Next

  • Doc 4 — KB Access Control Explainer (what each classification means, who sees what).
  • AI corpus: /ai/articles/delegation-scope-vocabulary.md.