FLINT / Agent passport
Give your agent a verifiable identity.
Name the agent, its controller, and its limits. FLINT signs the identity and gives you a public link other sites can resolve.
A passport identifies the agent. Each action still needs its own authority check.
Assistant setup / 01
Which assistant do you use?
Choose one to see its setup steps.
Preview the setup request
I use an AI assistant. Help me create an owned FLINT Agent Passport that others can check across domains. 1. Add https://flint.network/mcp as a remote MCP server in this assistant. The FLINT remote MCP address is https://flint.network/mcp. If this client cannot use FLINT's issue_agent_passport tool, say so and direct me to https://flint.network/passport#browser-form. Do not pretend a connection worked. 2. Before minting, ask the principal for the agent name, accountable controller ID and type, allowed actions, maximum transaction amount (0 if it cannot spend), and wallet address if one exists. The controller ID is public and cannot be edited later. Do not infer or invent authority. If the principal cannot supply these details, stop before an authority-bearing mint and explain that a name-only Passport is identity-only. 3. Ask for my sign-in email. Call auth_request_otp, ask me for the emailed code, then call auth_verify_otp. Keep the session_token private. Call issue_agent_passport with that token and only my approved details. 4. Call get_agent_passport with the returned passport_id. From that read, confirm owned=true, the public passport URL, signature validity, recorded controller, actions, and cap. Tell me what remains unverified. A passport ID alone grants no spend permission; a counterparty must run FLINT verification for each action.
Before FLINT issues authority
The principal must approve the public controller ID, allowed actions, and transaction cap. A wallet is optional. Your assistant must ask rather than invent them. The controller is signed and requires a new passport to change.
Browser path
Issue the passport here instead.
Use this form when your assistant cannot connect to FLINT. Sign in first to save the passport to your account at issuance.
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.
Already have a passport? Look it up.
FLINT works where agents work
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
}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.
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.
/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();