Agent passport

Give your agent a portable identity before it moves money.

Limits it cannot rewrite. A kill switch you control. Free. Agents can own it at mint.

An Agent Passport is how your agent proves who sent it and what it is allowed to do, and how you shut it down if it is hijacked.

Identity versus mandate

The passport has two parts. Who your agent is (signed once, never changes) and what it may do (rules you can change or revoke anytime).

The passport signs identity, not spend. The mandate, what it may do and how much it may spend, is a set of rules you can update anytime without re-issuing or re-signing.

signed twice, with a classical and a post-quantum key, so the record stays provable for decades

The 60-second way

Copy one prompt and your agent does the rest.

Paste this into Claude, ChatGPT, Cursor, or any assistant that can use tools. It will connect to FLINT, authenticate with OTP, and mint a passport your account owns.

Prompt

Connect to the FLINT MCP server at https://flint.network/mcp (free). Authenticate first: call auth_request_otp with my inbox, then auth_verify_otp with the code, and store the session_token. Use issue_agent_passport with that session_token so the passport is owned at mint. Ask me for the agent name, allowed actions, max transaction amount, and wallet if any, then set those as the mandate. When done, confirm ownership is attached and give me the public passport URL.

Two ways to mint

Agent-native (recommended)

auth_request_otp, then auth_verify_otp, then issue_agent_passport with session_token. Ownership attaches at mint. No claim link.

Secondary

Anonymous / human claim

Mint without a session and use the claim link later. This path is for humans and anonymous starts, not the agent happy path.

No assistant handy? Use the form below. Sign in first to own the passport at mint.

Path 2 / Web form

Issue a passport in the browser.

Registering creates an identity record for your agent. Connecting its software and approving tool access are separate steps. Sign in first to save this agent to your Account. Command access currently requires an approved account.

01 / Signed identity

Who is this agent?

Responsible person or company and optional details
Controller ID (email or org id)The stable id of the person or company responsible for this agent, for example org_acme or an email. This id becomes public.
Controller display nameOptional. A public display name for the controller, for example FLINT. Leave blank to show only the controller id.
Controller typeChoose Organization for a company or team; User for a person. Command registration selects a verified organization instead of accepting this free-text value.
AttestationsAdds outside proof such as a GitHub org or issuer signal.

02 / Mutable mandate

What may it do?

Starter mandate: edit anytime, no re-issuing.

Allowed actions
Select only actions you intend to permit. Leave all unchecked to register an identity with no permitted actions yet.
Max transaction amountLeave 0 for registration without spending. Tool access requires a separate approval in Command.

Ready to issue

What happens next

Ready to issue

Submit the form to call FLINT Network and mint a public passport URL for this agent.

See a passport get verified

A public verifiable URL for your agent

A signed identity that never changes

A mandate you can edit or revoke anytime

Sentinel takeover alerts and freeze, free

How the passport works

ISSUE

Mint the passport

Create a reusable agent identity tied to the principal, wallet, scope, and runtime.

VERIFY

Check each action

Ask FLINT whether this agent can take this action, in this context, right now.

PROVE

Return signed evidence

Send merchants a tamper-resistant verification record they can store with the transaction.

FLINT works where agents work

MCP connectorflint.network/mcp
Claude connectorClaude.ai, Claude Code, and Cowork
x402 Bazaar listingVerification endpoint listed
Add FLINT to your assistant
For engineers: API, SPIFFE, and response shapes

POST /api/passport request

This is the exact body the page sends to the issuance endpoint.

{
  "agent": {
    "agent_name": "",
    "controller_id": "",
    "controller_type": "organization",
    "wallet_address": ""
  },
  "mandate": {
    "allowed_actions": [],
    "max_transaction_amount": 0
  },
  "origin": "web",
  "src": "passport"
}

Response shape

Anonymous REST shape. owned is true only with a signed-in session; that path omits claim_url.

{
  "passport_id": "kya_01J...",
  "flint_agent_id": "faid_...",
  "passport": {
    "envelope_version": "hybrid-v0",
    "jws": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImZsaW50LXByb2QtMjAyNi1RMiJ9...",
    "pq_signature": "base64url_ml_dsa_65_signature",
    "pq_kid": "flint-pq-2026-Q2",
    "pq_alg": "ML-DSA-65"
  },
  "identity": {
    "record_type": "agent_passport",
    "record_version": "1.0",
    "status": "stamped",
    "agent_name": "Invoice Bot",
    "controller_id": "org_acme",
    "wallet_address": "0x7f4a..."
  },
  "mandate": {
    "allowed_actions": [
      "commerce_purchase",
      "x402_verification_purchase",
      "invoice.pay"
    ],
    "max_transaction_amount": 900,
    "version": 1
  },
  "verification": {
    "signature_valid": true,
    "es256": true,
    "pq": true,
    "valid": true
  },
  "owned": false,
  "claim_url": "https://flint.network/claim?passport_id=kya_01J...&token=...",
  "graph_seeded": true
}

FLINT MCP tool

Pass session_token on issue_agent_passport to mint owned. claim_url is anonymous-only.

{
  "tool": "issue_agent_passport",
  "server": "https://flint.network/mcp",
  "arguments": {
    "session_token": "session_...",
    "agent": {
      "agent_name": "Invoice Bot",
      "controller_id": "org_acme",
      "controller_name": "Acme Finance",
      "controller_type": "organization",
      "wallet_address": "0x7f4a3e8b9d2c5f1a0b4e7d3c6f9e2a8b1d4c7f3c1"
    },
    "mandate": {
      "allowed_actions": [
        "commerce_purchase",
        "x402_verification_purchase",
        "invoice.pay",
        "stablecoin_transfer"
      ],
      "max_transaction_amount": 900,
      "notes": "May pay approved invoices, transfer stablecoin, and complete checkout within mandate."
    }
  }
}

Signed identity

Identity is hybrid-signed once. The mandate is not inside this signature.

{
  "record_type": "agent_passport",
  "record_version": "1.0",
  "status": "stamped",
  "agent_name": "Invoice Bot",
  "controller_id": "org_acme",
  "wallet_address": "0x7f4a..."
}

Mutable mandate

Mutable config read at decision time. Updating it does not re-sign the passport.

{
  "allowed_actions": [
    "commerce_purchase",
    "x402_verification_purchase",
    "invoice.pay"
  ],
  "max_transaction_amount": 900,
  "version": 1
}

Passport envelope

Portable hybrid envelope: ES256 compact JWS plus ML-DSA-65 signature.

{
  "envelope_version": "hybrid-v0",
  "jws": "eyJhbGciOiJFUzI1NiIsImtpZCI6ImZsaW50LXByb2QtMjAyNi1RMiJ9...",
  "pq_signature": "base64url_ml_dsa_65_signature",
  "pq_kid": "flint-pq-2026-Q2",
  "pq_alg": "ML-DSA-65"
}

Verification summary

{
  "signature_valid": true,
  "es256": true,
  "pq": true,
  "valid": true
}
POST-QUANTUM READY

Every record is signed twice.

A classical ES256 signature and a post-quantum ML-DSA-65 signature, the NIST-standard lattice scheme, cover every FLINT passport. The proof you keep today stays verifiable even after quantum computers can break classical signatures.

The ES256 compact JWS remains inside the portable hybrid envelope. The post-quantum ML-DSA-65 signature travels beside it, over the same canonical payload.

ES256 + ML-DSA-65 verified

Attach to your agent

Call FLINT again when the agent tries to spend.

Minting is step one. At spend time, send the passport_id, nonce, timestamp, transaction.amount_display, and an environment signal so FLINT can apply the current mandate before money moves.

POST /api/verify

/api/verify server snippet

Recommended server path. Send the passport_id with the transaction and the signal you trust for this agent.

const response = await fetch("https://flint.network/api/verify", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    nonce: crypto.randomUUID(),
    timestamp: new Date().toISOString(),
    passport_id: "kya_01J...",
    partner_id: "merchant_checkout",
    merchant_reference: "order_847",
    transaction: {
      amount_display: "847.00",
      currency: "USDC",
      merchant_reference: "order_847"
    },
    agent_claim: {
      agent_id: "kya_01J..."
    }
  })
});

const verificationRecord = await response.json();

MCP config

Keep the passport_id available to your agent runtime so tools can verify the current mandate at spend time.

{
  "mcpServers": {
    "flint": {
      "url": "https://flint.network/mcp",
      "metadata": {
        "passport_id": "kya_01J..."
      }
    }
  }
}

SPIFFE claim

Use the agent's workload identity when your runtime already issues SPIFFE SVIDs.

const response = await fetch("https://flint.network/api/verify", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    nonce: crypto.randomUUID(),
    timestamp: new Date().toISOString(),
    passport_id: "kya_01J...",
    partner_id: "merchant_checkout",
    merchant_reference: "order_847",
    transaction: {
      amount_display: "847.00",
      currency: "USDC",
      merchant_reference: "order_847"
    },
    agent_claim: {
      spiffe_svid: "spiffe://acme.example/ns/agents/sa/invoice-bot"
    }
  })
});

const verificationRecord = await response.json();