Recipes
import { assertScope, verifyPassport } from 'agent-passport';
const passport = await verifyPassport(passportJwt);
function guarded<T extends (...a: any[]) => any>(scope: string, fn: T): T {
return (async (...args: Parameters<T>) => {
assertScope(passport, scope); // throws if not granted
return fn(...args);
}) as T;
}
const sendEmail = guarded('email:send', rawSendEmail);
Build a tamper-evident audit trail
import { signAction, verifyAction } from 'agent-passport';
async function withAudit(agent, type: string, target: string, run: () => Promise<unknown>) {
const result = await run();
const proof = await signAction(agent, { type, target });
await auditStore.append({ proof, at: new Date().toISOString() });
return result;
}
// later, prove who did it:
const { agent } = await verifyAction(savedProof);
Verify the full trust chain
import { verifyPassport, verifyAction, hasScope } from 'agent-passport';
async function trust(actionJwt: string, passportJwt: string, trustedOperators: Set<string>) {
const action = await verifyAction(actionJwt);
const passport = await verifyPassport(passportJwt);
return (
passport.agent.id === action.agent && // passport is about this agent
trustedOperators.has(passport.operator) && // operator is trusted
hasScope(passport, action.action.type) // scope covers the action
);
}
Short-lived passports (rotation)
// re-issue daily; did:key has no revocation, so keep windows small
await issuePassport({ operator, agentDid: agent.did, name: 'bot', scopes: ['crm:read'], expiresIn: 86400 });