Passport Issuer Path
You run AI agents that need credentials to access external systems. Start here to issue cryptographic passports, apply guardrails, and manage your agents' identity.
Your path: Issue passports for agents
You may not need a gate at all. A passport alone is enough to enforce spend caps, rate limits, and domain restrictions via the enforcement layer.
What you'll accomplish
Create an Issuer
Your signing identity, the root of trust for all passports you issue.
Issue a Passport
Cryptographic credential for your agent with permissions and constraints.
Apply Guardrails
Spend caps, rate limits, domain allowlists, enforced by the enforcement layer.
Monitor & Audit
Full cryptographic audit trail of every enforcement decision.
Step 1: Create an Issuer
An Issuer is your signing identity, an Ed25519 (an industry-standard elliptic curve signing algorithm) keypair that stamps all passports you create. Think of it as your organizational CA (Certificate Authority). You only need one per team or project.
curl -X POST https://modei.ai/api/v1/issuers \
-H "Authorization: Bearer mod_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "My AI Lab",
"domain": "myailab.com"
}'Or from the dashboard: Dashboard → Issuers → Create Issuer
Step 2: Issue a Passport
A passport is your agent's cryptographic identity. It includes permissions (what the agent can do) and constraints (spend caps, rate limits, domain restrictions).
import httpx
client = httpx.Client(
base_url="https://modei.ai/api/v1",
headers={"Authorization": "Bearer mod_your_key_here"}
)
response = client.post("/passports", json={
"issuer_id": "iss_...",
"agent_id": "research-bot-001",
"agent_name": "Research Bot",
"permissions": ["web:search", "web:fetch", "documents:read"],
"trust_tier": "L1",
"expires_in_days": 30,
"constraints": {
"core:cost:max_cumulative": 10000, # $100/day max spend
"core:cost:cumulative_window": "daily",
"core:rate:max_per_hour": 500,
}
})
response.raise_for_status()
passport = response.json()
# CRITICAL: Save the private key immediately, never shown again
print(f"Passport ID: {passport['id']}")
print(f"Private Key: {passport['private_key']}") # Save to secrets manager!const response = await fetch("https://modei.ai/api/v1/passports", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MODEI_API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
issuer_id: 'iss_your_issuer_id',
agent_id: 'research-bot-001',
agent_name: 'Research Bot',
permissions: ['web:search', 'web:fetch', 'documents:read'],
trust_tier: 'L1',
expires_in_days: 30,
constraints: {
'core:cost:max_cumulative': 10000, // $100 max spend, in cents
'core:cost:cumulative_window': 'daily',
'core:rate:max_per_hour': 500,
},
})
});
const passport = await response.json();
// CRITICAL: save the private key immediately, never shown again
await storeSecret('agents/research-bot-001/key', passport.private_key);
console.log('Passport ID:', passport.id);Critical: Save your Private Key RIGHT NOW
The private key is returned exactly once and is never stored on Modei servers. Copy it immediately and save it to a secrets manager (1Password, Bitwarden, AWS Secrets Manager). It cannot be recovered.
Step 3: Enforce Constraints (No Gate Needed)
The enforcement layer evaluates passport constraints independently. Call POST /api/enforce before each action to enforce spend caps, rate limits, and scope restrictions, no gate infrastructure required.
curl -X POST https://modei.ai/api/v1/enforce \
-H "Authorization: Bearer mod_your_key" \
-H "Content-Type: application/json" \
-d '{
"passport_id": "pass_01HABC...",
"action": "web:fetch",
"cost_cents": 5
}'
# Response: { "decision": "allow" }
# or: { "decision": "block", "reason": "core:cost:max_cumulative exceeded" }
# or: { "decision": "request_hold", "reason": "core:approval:required" }See Passport-Only Enforcement for the full zero-infrastructure pattern.
Step 4: Monitor Your Agents
Spawn Sub-Agents
Orchestrator agents can issue passports for sub-agents with a subset of their own permissions. Sub-agents cannot have more permissions than their parent.
# Orchestrator issues a short-lived passport for a sub-agent
sub_passport = issuer.create_passport(
agent_id="researcher-20260224-001",
agent_name="Research Sub-Agent",
permissions=["web:search", "web:fetch"], # Subset of orchestrator's permissions
expires_in=timedelta(hours=24), # Task-scoped
metadata={
"spawned_by": "orchestrator-agent",
"task": "market_research",
"project": "q1-2026"
}
)
# ... run task ...
# Revoke when done
await issuer.revoke_passport(sub_passport.passport_id, reason="Task complete")See Agent Autonomy Guide for full agent-to-agent trust chain patterns.
Next steps
- Passport-Only Enforcement, Enforce guardrails without a gate.
- Agent Autonomy Guide, Bootstrap credentials, spawn sub-agents, verify peers.
- Enforcement Layer, All 40 constraint evaluators in detail.
- Passport Structure, JWT format, Ed25519 keys, private key handling.
- Gate Operator Path, Also need to protect resources? Add a gate.
- Commerce Overview, Ready to let your agents transact with other services? Discover, meter, and settle.