Agent Authentication

Passji supports AI agents as first-class citizens. API keys, delegated tokens, and machine-to-machine auth.

Auth for the AI Era

Passji isn't just for humans. AI agents need identity too - to call APIs, access resources, and act on behalf of users. We support three token types:

Human Token

Interactive login via emoji + passkey (WebAuthn)

auth_method: webauthn

Agent Token

Programmatic auth for AI agents via API keys

auth_method: api_key

Delegated Token

Agents acting on behalf of humans with scoped permissions

auth_method: token_exchange

Token Comparison

Human Token

Standard OIDC flow. User picks emoji, authenticates with passkey, app receives ID token.

Human Token Claims
// Human Token (interactive login)
{
  "iss": "https://passji.com",
  "sub": "usr_abc123",
  "aud": "client_xyz",
  "emoji_id": "🦊🌸🎯",
  "trust_score": 0.85,
  "auth_method": "webauthn"
}

Agent Token

Machine-to-machine auth. Agent uses API key, receives access token with agent: true claim.

Agent Token Claims
// Agent Token (API key auth)
{
  "iss": "https://passji.com",
  "sub": "agt_def456",
  "aud": "client_xyz",
  "emoji_id": "🤖🔧⚡",
  "agent": true,
  "trust_score": 0.72,
  "auth_method": "api_key"
}

Delegated Token

Agent acting on behalf of a human. Includes delegator claim and scoped permissions.

Delegated Token Claims
// Delegated Token (agent acting for human)
{
  "iss": "https://passji.com",
  "sub": "agt_def456",             // Agent's identity
  "aud": "client_xyz",
  "delegator": "usr_abc123",        // Human who delegated
  "delegator_emoji": "🦊🌸🎯",      // Human's emoji
  "delegation_scope": [             // Limited permissions
    "read:profile",
    "write:settings"
  ],
  "delegation_exp": 1709856000,     // Delegation expiry
  "agent": true,
  "auth_method": "token_exchange"
}

API Key Authentication

For agents that need their own identity (not acting on behalf of a human). Uses the OAuth 2.0 Client Credentials grant.

Agent Registration

Register your agent in the Developer Portal. Choose an emoji identity for your agent (e.g., 🤖🔧⚡) and receive an API key.

API Key Auth Flow
// Agent authentication with API key
const client_id = "agt_your_agent_id";
const api_key = "your_api_key";

const response = await fetch("https://passji.com/token", {
  method: "POST",
  headers: {
    "Authorization": `Basic ${btoa(client_id + ":" + api_key)}`,
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: new URLSearchParams({
    grant_type: "client_credentials",
    scope: "openid agent",
  }),
});

const { access_token } = await response.json();

// Use the token to call protected APIs
const apiResponse = await fetch("https://api.example.com/data", {
  headers: {
    Authorization: `Bearer ${access_token}`,
  },
});

Token Exchange (Delegation)
Coming Soon

When an agent needs to act on behalf of a human, use token exchange. The human grants permission, and the agent receives a scoped delegated token.

Scoped Delegation

Delegated tokens have limited scope and expiry. The human can revoke delegation at any time. Apps can distinguish between human and delegated actions.

Token Exchange Flow
// Request delegated token (token exchange)
const response = await fetch("https://passji.com/token", {
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: new URLSearchParams({
    grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
    subject_token: human_access_token,      // Human's token
    subject_token_type: "urn:ietf:params:oauth:token-type:access_token",
    requested_token_type: "urn:ietf:params:oauth:token-type:access_token",
    client_id: "agt_your_agent_id",
    client_secret: "your_api_key",
    scope: "read:profile write:settings",   // Requested scopes
  }),
});

const { access_token } = await response.json();
// This token acts on behalf of the human

Device Flow
Coming Soon

For agents that can't open a browser (CLI tools, IoT devices, headless agents). The user authorizes on a separate device.

How It Works

  1. Agent requests a device code
  2. User visits verification URL on their phone/laptop
  3. User enters the code and approves
  4. Agent polls and receives the token
Device Flow
// Device Flow for agents (user grants access on another device)

// Step 1: Agent requests device code
const deviceResponse = await fetch("https://passji.com/device/code", {
  method: "POST",
  body: new URLSearchParams({
    client_id: "agt_your_agent_id",
    scope: "openid delegate read:profile",
  }),
});

const {
  device_code,
  user_code,        // "ABCD-1234" - shown to user
  verification_uri, // User visits this URL
  expires_in,
} = await deviceResponse.json();

console.log(`Visit ${verification_uri} and enter code: ${user_code}`);

// Step 2: Poll for token (user approves on their device)
while (true) {
  await sleep(5000); // Poll interval

  const tokenResponse = await fetch("https://passji.com/token", {
    method: "POST",
    body: new URLSearchParams({
      grant_type: "urn:ietf:params:oauth:grant-type:device_code",
      device_code,
      client_id: "agt_your_agent_id",
    }),
  });

  const result = await tokenResponse.json();

  if (result.access_token) {
    // User approved! Agent now has delegated access
    return result.access_token;
  }

  if (result.error === "authorization_pending") {
    continue; // Keep polling
  }

  throw new Error(result.error);
}

Best Practices

Detecting Agent vs Human

Check the agent claim in the token:

detection.js
const decoded = jwt.decode(access_token);

if (decoded.agent === true) {
  // This is an agent
  if (decoded.delegator) {
    // Agent acting on behalf of human
    console.log("Acting for:", decoded.delegator_emoji);
  } else {
    // Pure agent identity
    console.log("Agent:", decoded.emoji_id);
  }
} else {
  // Human user
  console.log("Human:", decoded.emoji_id);
}

Rate Limiting

Agents have separate rate limits from humans. High-traffic agents may need to request elevated limits.

Delegation Scopes

Always request the minimum scopes needed. Users are more likely to approve limited delegation.

  • read:* - Read-only access
  • write:* - Write access
  • Time-limited delegation with delegation_exp

Agent Trust Scoring

Agents build their own trust scores, separate from human identities. Trust is based on:

  • Agent age - How long the agent has been registered
  • Success rate - Ratio of successful to failed auth attempts
  • Usage patterns - Consistent usage builds trust
  • Linked human trust - If the agent owner has high trust, the agent inherits some

Apps can use agent trust scores to decide what access to grant. Low-trust agents might have stricter rate limits or require human approval for sensitive actions.