FLINT Design Partner Program: now accepting a founding cohort.Apply

FLINT

Agent passport

Issue a real passport for an AI agent.

Issue a real, signed agent passport in seconds. Free, no account, and issued in seconds.

Identity versus mandate

The passport signs identity, not spend. Your agent's identity is hybrid-signed once and never changes. The mandate, what it may do and how much it may spend, is mutable config you can update anytime without re-issuing or re-signing.

01 / Signed identity

Who is this agent?

Controller nameMapped to controller_id in the API request.
Controller type
AttestationsOptional comma-separated attestations.

02 / Mutable mandate

What may it do?

Allowed actions
Max transaction amount

Request preview

What we'll send

Ready to issue

Submit the form to call the real endpoint. Staging may return the expected signing-key message because it intentionally has no signer configured.

What we'll send

This is the exact body the page will POST to /api/passport.

{
  "agent": {
    "agent_name": "Invoice Bot",
    "controller_id": "org_acme",
    "controller_type": "organization",
    "wallet_address": "0x7f4a3e8b9d2c5f1a0b4e7d3c6f9e2a8b1d4c7f3c1"
  },
  "mandate": {
    "allowed_actions": [
      "checkout.purchase",
      "invoice.pay"
    ],
    "max_transaction_amount": 900,
    "notes": "May pay approved invoices and complete checkout within mandate."
  }
}
See a passport get verified

Issue programmatically

Builders can mint passports directly

Response shape

Production returns a real signed envelope. Staging is expected to report no signer.

{
  "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": [
      "checkout.purchase",
      "invoice.pay"
    ],
    "max_transaction_amount": 900,
    "version": 1
  },
  "verification": {
    "signature_valid": true,
    "es256": true,
    "pq": true,
    "valid": true
  },
  "graph_seeded": true
}

FLINT MCP tool

Use issue_agent_passport from flint.network/mcp.

{
  "tool": "issue_agent_passport",
  "server": "https://flint.network/mcp",
  "arguments": {
    "agent": {
      "agent_name": "Invoice Bot",
      "controller_id": "org_acme",
      "controller_type": "organization",
      "wallet_address": "0x7f4a3e8b9d2c5f1a0b4e7d3c6f9e2a8b1d4c7f3c1"
    },
    "mandate": {
      "allowed_actions": [
        "checkout.purchase",
        "invoice.pay"
      ],
      "max_transaction_amount": 900,
      "notes": "May pay approved invoices and complete checkout within mandate."
    }
  }
}

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

Server or autonomous agent

Recommended self-serve path. Use the agent's workload identity with agent_claim.spiffe_svid. No account, shared key, or FLINT-issued credential required.

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();

Browser or client-context agent

Browser and device-context verification runs on a FLINT-provisioned Fingerprint key, scoped to your domain. Contact us to enable it; the snippet below shows the shape.

import Fingerprint from "@fingerprint/agent";

const fpPublicKey = import.meta.env.VITE_FINGERPRINT_KEY;
if (!fpPublicKey) {
  throw new Error("VITE_FINGERPRINT_KEY is not set.");
}

const fp = await Fingerprint.start({ apiKey: fpPublicKey, region: "us" });
const { requestId } = await fp.get();

const response = await fetch("/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: {
      fp_request_id: requestId
    }
  })
});

const verificationRecord = await response.json();

MCP note: the current issue_authorization_record tool takes declared_scope explicitly. Passport-linked mandates over MCP are coming, so no passport_id argument is shown for that tool yet.