Skip to main content

Human Authorization

Human authorization provides cryptographic proof that a real, unique human approved an agent’s action — not just an API key holder, but a verified person. Powered by World ID.

Why Cryptographic Human Authorization?

Traditional “human approval” (API key + checkbox) has a fundamental problem: nothing proves a human was actually involved. Any script with an API key can mark an action as “human approved.” World ID solves this with zero-knowledge proofs of personhood:
  • Proof of personhood — Cryptographic proof a unique human approved, not a bot or script
  • Privacy-preserving — Zero-knowledge proof reveals nothing about the human’s identity
  • Sybil-resistant — Each human can only approve once per action (via nullifier hash)
  • Verifiable on-chain — The ZK proof can be independently verified by anyone

How It Works

The authorization flow puts the human in the loop at the moment of action — not after the fact.
Agent                    Treeship API              Human
  |                          |                       |
  |-- POST /v1/authorize --> |                       |
  |<-- approval_url -------- |                       |
  |                          |                       |
  |   (send URL to human)    |                       |
  |                          |                       |
  |                          | <-- opens URL --------|
  |                          | <-- scans World ID ---|
  |                          | -- proof verified ---> |
  |                          |                       |
  |-- GET /v1/authorize/{id} |                       |
  |<-- human_authorization --|                       |
  |                          |                       |
  |-- POST /v1/attest -----> |                       |
  |   (with proof embedded)  |                       |

Quick Start

1. Agent Requests Authorization

import requests

API = "https://api.treeship.dev/v1"
headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}

# Agent requests human authorization
auth = requests.post(f"{API}/authorize", headers=headers, json={
    "agent_slug": "purchase-agent",
    "action": "Purchase API credits ($500) from OpenAI",
    "context": {
        "amount": "$500",
        "vendor": "OpenAI",
        "purpose": "GPT-4 API credits for production"
    },
    "expires_in_minutes": 30
}).json()

# Send this URL to the human (Slack, email, SMS, etc.)
print(f"Approve here: {auth['approval_url']}")

2. Human Opens URL and Scans World ID

The human sees the agent’s request, the action description, and any context. They approve by scanning with World ID (iris scan for Orb-level, or phone verification for Device-level).

3. Agent Polls for Approval

import time

while True:
    status = requests.get(f"{API}/authorize/{auth['request_id']}").json()
    if status["status"] != "pending":
        break
    time.sleep(5)

if status["status"] == "approved":
    # The human_authorization contains the World ID ZK proof
    human_auth = status["human_authorization"]

4. Create Attestation with Proof

if status["status"] == "approved":
    result = requests.post(f"{API}/attest", headers=headers, json={
        "agent_slug": "purchase-agent",
        "action": "Purchased $500 in API credits from OpenAI",
        "inputs_hash": "sha256_of_purchase_details",
        "human_authorization": status["human_authorization"]
    }).json()

    print(f"Verified: {result['public_url']}")
    # The attestation now contains cryptographic proof of human approval

Verification Levels

LevelMethodStrengthBest For
OrbIris scan via World ID OrbStrongest proof of personhoodHigh-value transactions, regulatory compliance
DevicePhone verificationBasic uniqueness signalLow-risk approvals, internal workflows

Hash-Based Approvals (Basic)

For simpler use cases that don’t require proof-of-personhood, you can still use hash-based approvals:
from treeship_sdk import Treeship

ts = Treeship(api_key='your-key')

result = ts.attest(
    action="Approved refund of $5,000 for order #12345",
    human_approved=True,
    human_approver_hash=ts.hash("finance-manager@company.com")
)
The human_approver_hash is a SHA256 hash — the actual approver identity is never stored. However, this approach cannot prove a human was actually involved.

Threshold-Based Authorization

Require World ID authorization based on risk level:
def process_transaction(agent_slug, amount, recipient):
    requires_world_id = (
        amount > 1000 or
        recipient not in approved_vendors or
        is_international(recipient)
    )

    if requires_world_id:
        # Request World ID authorization
        auth = requests.post(f"{API}/authorize", headers=headers, json={
            "agent_slug": agent_slug,
            "action": f"Transfer ${amount} to {recipient}",
            "context": {"amount": f"${amount}", "recipient": recipient},
            "expires_in_minutes": 15
        }).json()

        # Wait for human approval via World ID
        notify_human(auth["approval_url"])
        human_auth = poll_for_approval(auth["request_id"])

        ts.attest(
            action=f"Transfer ${amount} to {recipient}",
            human_authorization=human_auth
        )
    else:
        # Low-risk: no human authorization needed
        ts.attest(
            action=f"Transfer ${amount} to {recipient}",
            human_approved=False
        )

Authorization Request Lifecycle

StatusDescription
pendingWaiting for human to open URL and scan World ID
approvedHuman approved — human_authorization is available
deniedHuman explicitly denied the request
expiredRequest expired before approval (default: 30 minutes)

API Reference

See the full Authorization API Reference for endpoint details.

Best Practices

Use World ID for High Stakes

Reserve World ID authorization for actions above a dollar or risk threshold.

Set Short Expiries

Use 15-30 minute expiry windows. If a human doesn’t respond, the agent should re-request rather than wait indefinitely.

Include Context

Always pass context (amount, vendor, purpose) so the human knows exactly what they’re approving.

Handle Denial Gracefully

If a human denies a request, the agent should stop and report — never retry the same action automatically.