@pidgeon-ai/issuer 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/directory.ts","../src/auth0.ts","../src/keycloak.ts","../src/okta.ts","../src/kms.ts","../../id/src/keys.ts","../../../src/lib/post/wasm/bytes.ts","../../../src/lib/post/wasm/post_core_wasm.js","../../id/src/http.ts","../../id/src/api.ts","../../id/src/sign-in.ts","../../id/src/cli.ts","../src/person.ts","../src/signer.ts","../src/config.ts","../src/issuer.ts","../src/server.ts","../src/cli.ts"],"sourcesContent":["/**\n * Who the agents are. The issuer holds no list of its own: the company's\n * identity provider is the record (`keycloak.ts`, `auth0.ts`, `okta.ts`), read\n * through this interface, and the issuer turns what it says into cards,\n * keys in the policy, and grants. Pidgeon is the format and the check,\n * never the identity provider.\n */\nexport interface DirectoryAgent {\n /** Never reassigned: the card's `sub`. Keycloak's is the service account's id. */\n sub: string;\n /** `name@<the issuer's domain>`, lower-cased. */\n address: string;\n kind: 'agent' | 'service';\n /** The agent's own Ed25519 public key, base64url (`x`). The agent holds the private half. */\n key: string;\n /** Groups or roles, which the config's `grants` map to grants. */\n groups: string[];\n /** When the agent was made, ISO 8601. */\n createdAt: string;\n}\n\nexport interface Directory {\n /** Every live agent: for the policy, the key directory and the cards anyone reads. */\n agents(): Promise<DirectoryAgent[]>;\n /**\n * One agent, read now, never from a copy: the token endpoint asks this\n * before it signs anything, so an agent disabled a second ago fails its\n * next sign-in. Null when it is not a live agent.\n */\n agent(sub: string): Promise<DirectoryAgent | null>;\n}\n\n/**\n * Each address once. Where the identity provider lets two apps name the\n * same address, neither is an agent: a member who claims a colleague's\n * agent's address blocks it (denial, fixed in the identity provider by\n * whoever may edit apps) but can never sign in as it.\n */\nexport function onePerAddress(agents: DirectoryAgent[]): DirectoryAgent[] {\n const count = new Map<string, number>();\n for (const agent of agents) count.set(agent.address, (count.get(agent.address) ?? 0) + 1);\n return agents.filter((agent) => count.get(agent.address) === 1);\n}\n\n/**\n * Agents listed in the config: for a laptop, a test, or a company that\n * keeps its agents in a file under change control. Live until removed.\n */\nexport function staticDirectory(agents: DirectoryAgent[]): Directory {\n const list = agents.map((agent) => ({ ...agent, address: agent.address.toLowerCase() }));\n return {\n agents: async () => list,\n agent: async (sub) => list.find((agent) => agent.sub === sub) ?? null,\n };\n}\n\n/**\n * A directory read through a short-lived copy, for the reads anyone can\n * make (the policy, cards): the identity provider is asked at most once per\n * `seconds`. `agent(sub)` is never cached.\n */\nexport function cachedDirectory(\n inner: Directory,\n seconds = 60,\n now: () => number = () => Date.now(),\n): Directory {\n let held: { at: number; value: Promise<DirectoryAgent[]> } | null = null;\n return {\n agents() {\n if (!held || held.at <= now() - seconds * 1000) {\n const value = inner.agents();\n held = { at: now(), value };\n // A failed read is not kept: the next one asks again.\n value.catch(() => {\n if (held?.value === value) held = null;\n });\n }\n return held.value;\n },\n agent: (sub) => inner.agent(sub),\n };\n}\n","import { onePerAddress, type Directory, type DirectoryAgent } from './directory';\n\n/**\n * Auth0 as the directory: the issuer reads the tenant's Management API and\n * never writes it.\n *\n * **An agent is a machine-to-machine application** (`app_type:\n * non_interactive`) whose `client_metadata` says so. Auth0 metadata keys\n * cannot hold a dot, so the names are Keycloak's with an underscore:\n *\n * | `client_metadata` | Becomes |\n * | ------------------ | ------------------------------------------------------------- |\n * | `pidgeon_key` | the agent's Ed25519 public key (`x`, base64url); required |\n * | `pidgeon_address` | its address, at the issuer's domain; required |\n * | `pidgeon_kind` | `agent` (default) or `service` |\n * | `pidgeon_groups` | comma-separated, what the config's `grants` map |\n * | `pidgeon_disabled` | `true`: not an agent, from its next sign-in |\n *\n * **Disabling.** An Auth0 application has no enabled switch, so an agent\n * is disabled with `pidgeon_disabled` or by deleting the application.\n * Whoever holds `update:clients` can set or clear it, so it is exactly as\n * strong as that permission, the same people who could change its key.\n *\n * **One key, two uses is not possible here.** Auth0's Private Key JWT takes\n * RS256, RS384 and PS256 with RSA keys only, not Ed25519, so the agent\n * authenticates to Auth0 some other way and names its Pidgeon key in\n * `pidgeon_key`.\n *\n * The card's `sub` is the `client_id`, which Auth0 generates and never lets\n * anyone change; its documentation does not say whether a deleted\n * application's id can come back. `created_at` is the application's.\n *\n * **The issuer's own credential** is a machine-to-machine application\n * authorized for the Management API with `read:clients` only: never\n * `read:client_keys` or `read:client_credentials`, which expose secrets.\n * Its secret comes from the environment.\n */\nexport interface Auth0Options {\n /** The tenant's domain: `acme.eu.auth0.com`, or its custom domain. */\n tenant: string;\n /** The issuer's own application. */\n clientId: string;\n clientSecret: string;\n /** The domain agents' addresses are at. */\n domain: string;\n fetch?: typeof fetch;\n /** Milliseconds since the epoch, for tests. */\n now?: () => number;\n}\n\ninterface Auth0Client {\n client_id: string;\n app_type?: string;\n created_at?: string;\n client_metadata?: Record<string, string | undefined>;\n}\n\nconst PER_PAGE = 100;\n\nexport function auth0Directory(options: Auth0Options): Directory {\n const base = `https://${options.tenant.replace(/^https:\\/\\//, '').replace(/\\/$/, '')}`;\n const domain = options.domain.toLowerCase();\n const fetcher = options.fetch ?? fetch;\n const now = options.now ?? (() => Date.now());\n let token: { value: string; until: number } | null = null;\n\n async function accessToken(): Promise<string> {\n if (token && token.until > now()) return token.value;\n const response = await fetcher(`${base}/oauth/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: options.clientId,\n client_secret: options.clientSecret,\n audience: `${base}/api/v2/`,\n }),\n });\n const body = (await response.json().catch(() => ({}))) as {\n access_token?: string;\n expires_in?: number;\n };\n if (!response.ok || !body.access_token) {\n throw new Error(\n `Auth0 refused the issuer's application ${options.clientId} (${response.status}).`,\n );\n }\n // A minute early, so a token is never sent as it expires.\n token = { value: body.access_token, until: now() + ((body.expires_in ?? 120) - 60) * 1000 };\n return token.value;\n }\n\n async function management<T>(path: string): Promise<T | null> {\n const response = await fetcher(`${base}/api/v2${path}`, {\n headers: { authorization: `Bearer ${await accessToken()}`, accept: 'application/json' },\n });\n if (response.status === 404) return null;\n if (!response.ok) throw new Error(`Auth0 answered ${response.status} for ${path}.`);\n return (await response.json()) as T;\n }\n\n function agentOf(client: Auth0Client): DirectoryAgent | null {\n if (client.app_type !== 'non_interactive') return null;\n const metadata = client.client_metadata ?? {};\n if (metadata.pidgeon_disabled?.trim().toLowerCase() === 'true') return null;\n const key = metadata.pidgeon_key?.trim();\n if (!key || Buffer.from(key, 'base64url').length !== 32) return null;\n const address = metadata.pidgeon_address?.trim().toLowerCase();\n if (!address?.endsWith(`@${domain}`)) return null;\n return {\n sub: client.client_id,\n address,\n kind: metadata.pidgeon_kind?.trim() === 'service' ? 'service' : 'agent',\n key,\n groups: (metadata.pidgeon_groups ?? '')\n .split(',')\n .map((group) => group.trim())\n .filter(Boolean),\n // An age Auth0 does not give is treated as new: the card says `new`, never older than it is.\n createdAt: new Date(client.created_at ? Date.parse(client.created_at) : now()).toISOString(),\n };\n }\n\n async function all(): Promise<DirectoryAgent[]> {\n const agents: DirectoryAgent[] = [];\n for (let page = 0; ; page++) {\n const body = await management<{ clients?: Auth0Client[]; total?: number }>(\n `/clients?app_type=non_interactive&per_page=${PER_PAGE}&page=${page}&include_totals=true`,\n );\n const clients = body?.clients ?? [];\n for (const client of clients) {\n const agent = agentOf(client);\n if (agent) agents.push(agent);\n }\n if (clients.length < PER_PAGE || (page + 1) * PER_PAGE >= (body?.total ?? 0)) break;\n }\n return agents;\n }\n\n return {\n agents: async () => onePerAddress(await all()),\n async agent(sub) {\n const client = await management<Auth0Client>(`/clients/${encodeURIComponent(sub)}`);\n const agent = client ? agentOf(client) : null;\n return agent?.sub === sub ? agent : null;\n },\n };\n}\n","import { onePerAddress, type Directory, type DirectoryAgent } from './directory';\n\n/**\n * Keycloak as the directory: the company's identity provider says who its\n * agents are, and the issuer reads it, never writes it.\n *\n * **An agent is a Keycloak client with a service account**, the identity\n * Keycloak already gives software, whose service-account user is in the\n * agents group (`agents` by default). The client's attributes say the rest:\n *\n * | Client attribute | Becomes |\n * | ----------------- | --------------------------------------------------------- |\n * | `pidgeon.key` | the agent's Ed25519 public key (`x`, base64url) |\n * | `pidgeon.address` | its address; default `<clientId>@<domain>` |\n * | `pidgeon.kind` | `agent` (default) or `service` |\n *\n * **One key, two uses.** Keycloak 26 authenticates a client by a signed\n * JWT under an Ed25519 key in its JWKS (`client-jwt`, signing algorithm\n * EdDSA; tried against 26.4.2, 6 November). A client set up that way needs\n * no `pidgeon.key`: its one Ed25519 key in `jwks.string` is read instead,\n * and the key the agent signs in to sites with is the one it signs in to\n * Keycloak with. `pidgeon.key` wins when both are there.\n *\n * The card's `sub` is the service-account user's id, a UUID Keycloak never\n * reuses; its groups are the ones the config's `grants` map; `created_at`\n * is when that user was made. A client that is disabled, has no service\n * account, no key, or has left the group is not an agent.\n *\n * **The issuer's own credential** is a confidential client of its own with\n * a service account holding `realm-management`'s `view-clients` and\n * `view-users`, nothing that writes. Its secret comes from the environment.\n *\n * Calls are Keycloak's Admin REST API (`/admin/realms/{realm}/…`) and its\n * token endpoint, as documented for Keycloak 26.\n */\nexport interface KeycloakOptions {\n /** Where Keycloak answers: `https://sso.acme.internal`. */\n url: string;\n realm: string;\n /** The issuer's own client. */\n clientId: string;\n clientSecret: string;\n /** The domain agents' addresses are at. */\n domain: string;\n /** The group whose members are agents. Default `agents`. */\n group?: string;\n fetch?: typeof fetch;\n /** Milliseconds since the epoch, for tests. */\n now?: () => number;\n}\n\ninterface KeycloakClient {\n id: string;\n clientId: string;\n enabled?: boolean;\n serviceAccountsEnabled?: boolean;\n attributes?: Record<string, string | undefined>;\n}\n\ninterface KeycloakUser {\n id: string;\n /** `service-account-<clientId>`, lower-cased, for a service account. */\n username?: string;\n /** Absent for a user imported without one. */\n createdTimestamp?: number;\n enabled?: boolean;\n}\n\n/** Keycloak names a client's service-account user this, and says so nowhere else on the user. */\nconst SERVICE_ACCOUNT_PREFIX = 'service-account-';\n\nconst ATTRIBUTES = { key: 'pidgeon.key', address: 'pidgeon.address', kind: 'pidgeon.kind' };\n\n/** The agent's key: `pidgeon.key`, else the one Ed25519 key Keycloak authenticates the client with. */\nfunction keyOf(client: KeycloakClient): string | null {\n const own = client.attributes?.[ATTRIBUTES.key]?.trim();\n if (own) return own;\n if (client.attributes?.['use.jwks.string'] !== 'true') return null;\n try {\n const jwks = JSON.parse(client.attributes['jwks.string'] ?? '') as {\n keys?: { kty?: string; crv?: string; x?: string }[];\n };\n const ed25519 = (jwks.keys ?? []).filter((key) => key.kty === 'OKP' && key.crv === 'Ed25519');\n return ed25519.length === 1 && ed25519[0]!.x ? ed25519[0]!.x : null;\n } catch {\n return null;\n }\n}\n\nexport function keycloakDirectory(options: KeycloakOptions): Directory {\n const base = options.url.replace(/\\/$/, '');\n const realm = encodeURIComponent(options.realm);\n const group = options.group ?? 'agents';\n const domain = options.domain.toLowerCase();\n const fetcher = options.fetch ?? fetch;\n const now = options.now ?? (() => Date.now());\n let token: { value: string; until: number } | null = null;\n\n async function accessToken(): Promise<string> {\n if (token && token.until > now()) return token.value;\n const response = await fetcher(`${base}/realms/${realm}/protocol/openid-connect/token`, {\n method: 'POST',\n headers: { 'content-type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: options.clientId,\n client_secret: options.clientSecret,\n }),\n });\n const body = (await response.json().catch(() => ({}))) as {\n access_token?: string;\n expires_in?: number;\n };\n if (!response.ok || !body.access_token) {\n throw new Error(\n `Keycloak refused the issuer's client ${options.clientId} (${response.status}).`,\n );\n }\n // Ten seconds early, so a token is never sent as it expires.\n token = { value: body.access_token, until: now() + ((body.expires_in ?? 60) - 10) * 1000 };\n return token.value;\n }\n\n async function admin<T>(path: string): Promise<T | null> {\n const response = await fetcher(`${base}/admin/realms/${realm}${path}`, {\n headers: { authorization: `Bearer ${await accessToken()}`, accept: 'application/json' },\n });\n if (response.status === 404) return null;\n if (!response.ok) throw new Error(`Keycloak answered ${response.status} for ${path}.`);\n return (await response.json()) as T;\n }\n\n /** The agent a client is, or null when it is not one. */\n async function agentOf(client: KeycloakClient): Promise<DirectoryAgent | null> {\n const key = keyOf(client);\n if (!client.enabled || !client.serviceAccountsEnabled || !key) return null;\n if (Buffer.from(key, 'base64url').length !== 32) return null;\n\n const user = await admin<KeycloakUser>(\n `/clients/${encodeURIComponent(client.id)}/service-account-user`,\n );\n if (!user || user.enabled === false) return null;\n const groups =\n (await admin<{ name: string; path?: string }[]>(\n `/users/${encodeURIComponent(user.id)}/groups`,\n )) ?? [];\n const names = groups.map((one) => one.name);\n if (!names.includes(group)) return null;\n\n const address = (\n client.attributes?.[ATTRIBUTES.address]?.trim() || `${client.clientId}@${domain}`\n ).toLowerCase();\n if (!address.endsWith(`@${domain}`)) return null;\n return {\n sub: user.id,\n address,\n kind: client.attributes?.[ATTRIBUTES.kind] === 'service' ? 'service' : 'agent',\n key,\n groups: names,\n // An age Keycloak does not know is treated as new: the card says `new`, never older than it is.\n createdAt: new Date(user.createdTimestamp ?? now()).toISOString(),\n };\n }\n\n return {\n async agents() {\n const clients = (await admin<KeycloakClient[]>('/clients?first=0&max=1000')) ?? [];\n const candidates = clients.filter((client) => keyOf(client) !== null);\n const agents = await Promise.all(candidates.map(agentOf));\n return onePerAddress(agents.filter((agent): agent is DirectoryAgent => agent !== null));\n },\n\n /**\n * The user's record does not name its client (only a realm export\n * does), so the client is found by the username Keycloak gives every\n * service account, and confirmed: that client's service-account user\n * must be this `sub`, or it is nobody.\n */\n async agent(sub) {\n const user = await admin<KeycloakUser>(`/users/${encodeURIComponent(sub)}`);\n const name = user?.username?.startsWith(SERVICE_ACCOUNT_PREFIX)\n ? user.username.slice(SERVICE_ACCOUNT_PREFIX.length)\n : null;\n if (!name) return null;\n let client =\n (await admin<KeycloakClient[]>(`/clients?clientId=${encodeURIComponent(name)}`))?.[0] ??\n null;\n // Usernames are lower-cased; a clientId need not be.\n client ??=\n (await admin<KeycloakClient[]>('/clients?first=0&max=1000'))?.find(\n (candidate) => candidate.clientId.toLowerCase() === name,\n ) ?? null;\n const agent = client ? await agentOf(client) : null;\n return agent?.sub === sub ? agent : null;\n },\n };\n}\n","import { createPrivateKey, randomUUID, sign, type KeyObject } from 'node:crypto';\n\nimport { onePerAddress, type Directory, type DirectoryAgent } from './directory';\n\n/**\n * Okta as the directory: the issuer reads the org's Apps API and never\n * writes it.\n *\n * **An agent is an active OAuth 2.0 service app** (`application_type:\n * service`, client credentials) whose `profile` names it. An Okta group\n * holds people, never apps, so the agent's groups live in the profile too,\n * as Okta's own `profile.groupallowlist` pattern does:\n *\n * ```json\n * \"profile\": { \"pidgeon\": { \"key\": \"<x>\", \"address\": \"support@acme.com\", \"kind\": \"agent\", \"groups\": [\"refunds\"] } }\n * ```\n *\n * A deactivated app (`status: INACTIVE`) or a deleted one is not an agent\n * from its next sign-in. The card's `sub` is the app's id; `created_at` is\n * the app's `created`.\n *\n * **One key, two uses is not possible here.** An Okta app's JWKS takes RSA\n * and EC keys only, not Ed25519, so the agent authenticates to Okta with\n * another key and names its Pidgeon key in the profile.\n *\n * **The issuer's own credential** is a service app of its own, granted the\n * `okta.apps.read` scope and a read-only admin role (Okta requires both).\n * Okta takes only Private Key JWT for its own scopes, so the issuer signs a\n * client assertion with an RSA or P-256 key whose public half is in that\n * app's JWKS; the private half comes from the environment.\n */\nexport interface OktaOptions {\n /** The org: `https://acme.okta.com`. */\n org: string;\n /** The issuer's own service app. */\n clientId: string;\n /** Its RSA or P-256 private key, PEM, for the client assertion. */\n privateKey: string | KeyObject;\n /** That key's `kid` in the app's JWKS, when the app has more than one. */\n keyId?: string;\n /** The domain agents' addresses are at. */\n domain: string;\n fetch?: typeof fetch;\n /** Milliseconds since the epoch, for tests. */\n now?: () => number;\n}\n\ninterface OktaApp {\n id: string;\n status?: string;\n created?: string;\n settings?: { oauthClient?: { application_type?: string } };\n profile?: {\n pidgeon?: { key?: unknown; address?: unknown; kind?: unknown; groups?: unknown };\n };\n}\n\nexport const OKTA_SCOPE = 'okta.apps.read';\n\nexport function oktaDirectory(options: OktaOptions): Directory {\n const org = options.org.replace(/\\/$/, '');\n const domain = options.domain.toLowerCase();\n const fetcher = options.fetch ?? fetch;\n const now = options.now ?? (() => Date.now());\n const privateKey =\n typeof options.privateKey === 'string'\n ? createPrivateKey(options.privateKey)\n : options.privateKey;\n const alg =\n privateKey.asymmetricKeyType === 'rsa'\n ? 'RS256'\n : privateKey.asymmetricKeyType === 'ec' &&\n privateKey.asymmetricKeyDetails?.namedCurve === 'prime256v1'\n ? 'ES256'\n : null;\n if (!alg) throw new Error(\"Okta's client assertion is signed with an RSA or P-256 key.\");\n let token: { value: string; until: number } | null = null;\n\n /** RFC 7523 client authentication, as Okta's org authorization server takes it. */\n function assertion(audience: string): string {\n const at = Math.floor(now() / 1000);\n const b64 = (value: unknown) => Buffer.from(JSON.stringify(value)).toString('base64url');\n const input = `${b64({ alg, typ: 'JWT', ...(options.keyId ? { kid: options.keyId } : {}) })}.${b64(\n {\n iss: options.clientId,\n sub: options.clientId,\n aud: audience,\n iat: at,\n exp: at + 300,\n jti: randomUUID(),\n },\n )}`;\n const signature = sign(\n 'sha256',\n Buffer.from(input),\n alg === 'ES256' ? { key: privateKey, dsaEncoding: 'ieee-p1363' } : privateKey,\n );\n return `${input}.${signature.toString('base64url')}`;\n }\n\n async function accessToken(): Promise<string> {\n if (token && token.until > now()) return token.value;\n const endpoint = `${org}/oauth2/v1/token`;\n const response = await fetcher(endpoint, {\n method: 'POST',\n headers: {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n scope: OKTA_SCOPE,\n client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',\n client_assertion: assertion(endpoint),\n }),\n });\n const body = (await response.json().catch(() => ({}))) as {\n access_token?: string;\n expires_in?: number;\n error_description?: string;\n };\n if (!response.ok || !body.access_token) {\n throw new Error(\n `Okta refused the issuer's app ${options.clientId} (${response.status}${body.error_description ? `: ${body.error_description}` : ''}).`,\n );\n }\n token = { value: body.access_token, until: now() + ((body.expires_in ?? 120) - 60) * 1000 };\n return token.value;\n }\n\n async function api(url: string): Promise<Response> {\n const response = await fetcher(url, {\n headers: { authorization: `Bearer ${await accessToken()}`, accept: 'application/json' },\n });\n if (!response.ok && response.status !== 404) {\n throw new Error(`Okta answered ${response.status} for ${new URL(url).pathname}.`);\n }\n return response;\n }\n\n function agentOf(app: OktaApp): DirectoryAgent | null {\n if (app.status !== 'ACTIVE') return null;\n if (app.settings?.oauthClient?.application_type !== 'service') return null;\n const pidgeon = app.profile?.pidgeon;\n const key = typeof pidgeon?.key === 'string' ? pidgeon.key.trim() : '';\n if (!key || Buffer.from(key, 'base64url').length !== 32) return null;\n const address =\n typeof pidgeon?.address === 'string' ? pidgeon.address.trim().toLowerCase() : '';\n if (!address.endsWith(`@${domain}`)) return null;\n return {\n sub: app.id,\n address,\n kind: pidgeon?.kind === 'service' ? 'service' : 'agent',\n key,\n groups: Array.isArray(pidgeon?.groups)\n ? pidgeon.groups.filter((group): group is string => typeof group === 'string')\n : [],\n createdAt: new Date(app.created ? Date.parse(app.created) : now()).toISOString(),\n };\n }\n\n /** The `next` link of an Okta page, kept on the org's own origin. */\n function nextPage(response: Response): string | null {\n for (const part of (response.headers.get('link') ?? '').split(',')) {\n const match = /<([^>]+)>\\s*;\\s*rel=\"next\"/.exec(part);\n if (match && new URL(match[1]!).origin === new URL(org).origin) return match[1]!;\n }\n return null;\n }\n\n return {\n async agents() {\n const agents: DirectoryAgent[] = [];\n let url: string | null =\n `${org}/api/v1/apps?filter=${encodeURIComponent('status eq \"ACTIVE\"')}&limit=200`;\n for (let pages = 0; url && pages < 100; pages++) {\n const response = await api(url);\n for (const app of ((await response.json()) as OktaApp[]) ?? []) {\n const agent = agentOf(app);\n if (agent) agents.push(agent);\n }\n url = nextPage(response);\n }\n return onePerAddress(agents);\n },\n async agent(sub) {\n const response = await api(`${org}/api/v1/apps/${encodeURIComponent(sub)}`);\n if (response.status === 404) return null;\n const agent = agentOf((await response.json()) as OktaApp);\n return agent?.sub === sub ? agent : null;\n },\n };\n}\n","import { createPublicKey, verify } from 'node:crypto';\n\nimport { jwkThumbprint } from '@pidgeon-ai/id';\n\nimport type { RetiredKey, Signer } from './signer';\n\n/**\n * The issuer's key in AWS KMS: an `ECC_NIST_EDWARDS25519` key, which signs\n * pure Ed25519 (`ED25519_SHA_512` over the message itself, `MessageType:\n * RAW`, up to 4 KB). Everything the issuer signs is a JWS signing input of a\n * few hundred bytes, so the key never has to leave KMS and nothing else in\n * the issuer changes.\n *\n * **Pinned at start.** The key is read once (`GetPublicKey`): an alias is\n * resolved to the key's ARN, and every `Sign` names that ARN, so re-pointing\n * the alias later changes nothing until the issuer restarts and publishes\n * the new key. **Every signature is checked** against the public key read at\n * start before it leaves, so the issuer never hands out a token its own\n * JWKS does not verify.\n *\n * The issuer's role needs `kms:GetPublicKey` and `kms:Sign` on that key and\n * nothing else. `@aws-sdk/client-kms` is an optional peer dependency,\n * loaded only here; pass `kms` to use a client of your own.\n */\n\nexport const KMS_KEY_SPEC = 'ECC_NIST_EDWARDS25519';\nexport const KMS_SIGNING_ALGORITHM = 'ED25519_SHA_512';\n\n/** The two KMS calls the issuer makes, as `@aws-sdk/client-kms` shapes them. */\nexport interface KmsApi {\n getPublicKey(input: { KeyId: string }): Promise<{\n KeyId?: string;\n KeySpec?: string;\n KeyUsage?: string;\n SigningAlgorithms?: string[];\n PublicKey?: Uint8Array;\n }>;\n sign(input: {\n KeyId: string;\n Message: Uint8Array;\n MessageType: 'RAW';\n SigningAlgorithm: string;\n }): Promise<{ KeyId?: string; Signature?: Uint8Array }>;\n}\n\nexport interface KmsSignerOptions {\n /** The key's ARN, id, or an alias (`alias/pidgeon-issuer`), resolved once at start. */\n keyId: string;\n /** Default the SDK's: `AWS_REGION`, then the profile's. */\n region?: string;\n kms?: KmsApi;\n}\n\n/** `@aws-sdk/client-kms`, loaded only when a KMS key is configured. */\nasync function sdkClient(region?: string): Promise<KmsApi> {\n let sdk: typeof import('@aws-sdk/client-kms');\n try {\n sdk = await import('@aws-sdk/client-kms');\n } catch {\n throw new Error(\n 'A KMS key needs @aws-sdk/client-kms: `npm install @aws-sdk/client-kms` beside the issuer.',\n );\n }\n const client = new sdk.KMSClient(region ? { region } : {});\n return {\n getPublicKey: (input) => client.send(new sdk.GetPublicKeyCommand(input)),\n sign: (input) =>\n client.send(\n new sdk.SignCommand({\n ...input,\n SigningAlgorithm:\n input.SigningAlgorithm as typeof sdk.SigningAlgorithmSpec.ED25519_SHA_512,\n }),\n ),\n };\n}\n\n/** The key's public half, read and checked: Ed25519, for signing, pure. */\nasync function readKey(kms: KmsApi, keyId: string) {\n let key;\n try {\n key = await kms.getPublicKey({ KeyId: keyId });\n } catch (error) {\n throw new Error(\n `KMS would not give the issuer ${keyId}'s public key (${error instanceof Error ? error.message : error}). Its role needs kms:GetPublicKey and kms:Sign on that key.`,\n );\n }\n if (key.KeySpec !== KMS_KEY_SPEC) {\n throw new Error(`${keyId} is a ${key.KeySpec} key. The issuer signs with ${KMS_KEY_SPEC}.`);\n }\n if (key.KeyUsage && key.KeyUsage !== 'SIGN_VERIFY') {\n throw new Error(`${keyId} is not a signing key.`);\n }\n if (!key.SigningAlgorithms?.includes(KMS_SIGNING_ALGORITHM)) {\n throw new Error(`${keyId} does not sign with ${KMS_SIGNING_ALGORITHM}.`);\n }\n if (!key.KeyId || !key.PublicKey) throw new Error(`KMS gave no public key for ${keyId}.`);\n const publicKey = createPublicKey({\n key: Buffer.from(key.PublicKey),\n format: 'der',\n type: 'spki',\n });\n const x = publicKey.export({ format: 'jwk' }).x;\n const raw = new Uint8Array(Buffer.from(x ?? '', 'base64url'));\n if (raw.length !== 32) throw new Error(`${keyId}'s public key is not an Ed25519 key.`);\n return { arn: key.KeyId, publicKey, raw };\n}\n\nexport async function kmsSigner(options: KmsSignerOptions): Promise<Signer & { keyArn: string }> {\n const kms = options.kms ?? (await sdkClient(options.region));\n const { arn, publicKey, raw } = await readKey(kms, options.keyId);\n return {\n kid: jwkThumbprint(raw),\n publicKey: raw,\n keyArn: arn,\n async sign(message) {\n const signed = await kms.sign({\n KeyId: arn,\n Message: message,\n MessageType: 'RAW',\n SigningAlgorithm: KMS_SIGNING_ALGORITHM,\n });\n const signature = signed.Signature ? new Uint8Array(signed.Signature) : null;\n if (!signature || !verify(null, message, publicKey, signature)) {\n throw new Error(\n `KMS answered for ${arn} with a signature its public key does not verify. Nothing was signed.`,\n );\n }\n return signature;\n },\n };\n}\n\n/** A key in KMS the issuer no longer signs with, published until `notAfter`: its public half only. */\nexport async function kmsRetiredKey(\n options: KmsSignerOptions & { notAfter: Date },\n): Promise<RetiredKey> {\n const kms = options.kms ?? (await sdkClient(options.region));\n const { raw } = await readKey(kms, options.keyId);\n return { kid: jwkThumbprint(raw), publicKey: raw, notAfter: options.notAfter };\n}\n","import { createHash } from 'node:crypto';\nimport { chmod, mkdir, readFile, readdir, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// post-core, the protocol's Rust core, through the same WebAssembly the server runs.\nimport { wasmBase64 } from '../../../src/lib/post/wasm/bytes';\nimport * as core from '../../../src/lib/post/wasm/post_core_wasm.js';\n\n/**\n * An operator's signing key for one domain: Ed25519, made on this machine\n * and never sent anywhere. Pidgeon holds only the public half.\n *\n * `kid` is the key's RFC 8037 JWK thumbprint, which is what Web Bot Auth\n * calls a `keyid` and what the domain's `post.json` lists, so one name\n * finds the key from an email, an HTTP request and the policy alike.\n */\n\nlet ready = false;\nfunction wasm(): typeof core {\n if (!ready) {\n core.initSync({ module: Buffer.from(wasmBase64, 'base64') });\n ready = true;\n }\n return core;\n}\n\nexport interface Identity {\n domain: string;\n kid: string;\n /** 32 bytes. */\n publicKey: Uint8Array;\n /** Ed25519 over exactly these bytes. */\n sign(message: Uint8Array): Uint8Array;\n}\n\nexport interface StoredIdentity extends Identity {\n /** The private key. Kept in the identity file, mode 0600, and nowhere else. */\n seed: Uint8Array;\n /** The key this one replaced, while receivers may still hold it. */\n previous?: { kid: string; publicKey: Uint8Array } | null;\n}\n\nexport const b64url = (bytes: Uint8Array) => Buffer.from(bytes).toString('base64url');\nexport const fromB64url = (text: string) => new Uint8Array(Buffer.from(text, 'base64url'));\n\n/** RFC 8037 §A.3. */\nexport function jwkThumbprint(publicKey: Uint8Array): string {\n return createHash('sha256')\n .update(`{\"crv\":\"Ed25519\",\"kty\":\"OKP\",\"x\":\"${b64url(publicKey)}\"}`)\n .digest('base64url');\n}\n\nexport function verifyBytes(publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array) {\n try {\n return wasm().verify(publicKey, message, signature);\n } catch {\n return false;\n }\n}\n\nexport function identityFromSeed(input: { domain: string; seed: Uint8Array }): StoredIdentity {\n const seed = new Uint8Array(input.seed);\n const publicKey = wasm().publicKey(seed);\n return {\n domain: input.domain.toLowerCase(),\n kid: jwkThumbprint(publicKey),\n publicKey,\n seed,\n sign: (message) => wasm().sign(seed, message),\n };\n}\n\nexport function generateIdentity(domain: string): StoredIdentity {\n return identityFromSeed({ domain, seed: wasm().generateSeed() });\n}\n\n// --- On disk ------------------------------------------------------------------\n\n/** `$PIDGEON_ID_DIR`, else `~/.config/pidgeon/id`. One file per domain. */\nexport function identityDir(env: Record<string, string | undefined> = process.env): string {\n return (\n env.PIDGEON_ID_DIR || join(env.XDG_CONFIG_HOME || join(homedir(), '.config'), 'pidgeon', 'id')\n );\n}\n\ninterface IdentityFile {\n v: 1;\n domain: string;\n kid: string;\n seed: string;\n previous?: { kid: string; public_key: string } | null;\n}\n\nexport async function saveIdentity(identity: StoredIdentity, dir = identityDir()): Promise<string> {\n await mkdir(dir, { recursive: true, mode: 0o700 });\n const path = join(dir, `${identity.domain}.json`);\n const file: IdentityFile = {\n v: 1,\n domain: identity.domain,\n kid: identity.kid,\n seed: b64url(identity.seed),\n previous: identity.previous\n ? { kid: identity.previous.kid, public_key: b64url(identity.previous.publicKey) }\n : null,\n };\n await writeFile(path, `${JSON.stringify(file, null, 2)}\\n`, { mode: 0o600 });\n await chmod(path, 0o600);\n return path;\n}\n\n/**\n * The identity for `domain`, from `PIDGEON_ID_KEY` (`<domain>:<seed>`, for a\n * server the operator deploys to) or the identity file.\n */\nexport async function loadIdentity(\n domain: string,\n options: { dir?: string; env?: Record<string, string | undefined> } = {},\n): Promise<StoredIdentity> {\n const env = options.env ?? process.env;\n const name = domain.toLowerCase();\n const fromEnv = env.PIDGEON_ID_KEY?.split(':');\n if (fromEnv?.length === 2 && fromEnv[0]!.toLowerCase() === name) {\n return identityFromSeed({ domain: name, seed: fromB64url(fromEnv[1]!) });\n }\n\n const path = join(options.dir ?? identityDir(env), `${name}.json`);\n let file: IdentityFile;\n try {\n file = JSON.parse(await readFile(path, 'utf8')) as IdentityFile;\n } catch {\n throw new Error(\n `No identity for ${name} on this machine. Run \\`pidgeon id init ${name}\\` first.`,\n );\n }\n const identity = identityFromSeed({ domain: file.domain, seed: fromB64url(file.seed) });\n if (identity.kid !== file.kid)\n throw new Error(`${path} is damaged: its key does not match its kid.`);\n identity.previous = file.previous\n ? { kid: file.previous.kid, publicKey: fromB64url(file.previous.public_key) }\n : null;\n return identity;\n}\n\n/** The domains with an identity file here. */\nexport async function listIdentities(dir = identityDir()): Promise<string[]> {\n try {\n return (await readdir(dir))\n .filter((name) => name.endsWith('.json'))\n .map((name) => name.slice(0, -5));\n } catch {\n return [];\n }\n}\n","// Generated by scripts/post-core-wasm.sh from crates/post-core-wasm. Do not edit.\n// SPDX-License-Identifier: Apache-2.0\nexport const wasmBase64 =\n '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akEYaiAFQZgEaikAADcDACAFQfAFakEIaiAFQdEIaikAADcDACAFQfAFakEQaiAFQdkIaikAADcDACAFQYcGaiAFQcgIakEYaikAADcAACAFIAUpAIAENwPQBSAFIAUpAMkINwPwBSAFLQDICCEDQQAhAgNAIAVBkAZqIAJqQQA6AAAgAkEBaiICQSBHDQALQSAhAgNAIAVBkAZqIAJqQQA6AAAgAkEBaiICQcAARw0ACyAFQbAKakEIaiAFQfAFakEIaikDADcDACAFQbAKakEQaiAFQfAFakEQaikDADcDACAFQbAKakEXaiAFQfAFakEXaikAADcAACAFQdcKaiAFQdAFakEIaikDADcAACAFQd8KaiAFQdAFakEQaikDADcAACAFQecKaiAFQegFaikDADcAACAFIAUpA/AFNwOwCiAFIAUpA9AFNwDPCkHAASECA0AgBUEcaiACakEAOgAAIAJBAWoiAkHgAUcNAAsCQEHAABAEIgINAEEBQcAAEE8ACyACIAM6AAACQEE/RQ0AIAJBAWogBUGwCmpBP/wKAAALQcAAIQMLAkAgBEUNACAHIARBARA6CwJAIAFFDQAgBiABQQEQOgsCQAJAIAhFDQBBASEEQQAhAUEAIQMMAQsgBUHAADYC6AMgBSACNgLkAyAFIAM2AuADIAUgBUHgA2oQOEEAIQIgBSgCACEBIAUoAgQhA0EAIQQLIAAgBDYCDCAAIAI2AgggACADNgIEIAAgATYCACAFQfAKaiQAC84LAgp/JH4jAEEwayIDJAAgAyACKAIAIgStIg0gASgCACIFrSIOfiIPQpv80ZIBfkL/////AYMiEELSscwEfiABKAIEIgatIhEgDX4gAigCBCIHrSISIA5+fCITfCAQQu2n1+cBfiAPfEIdiHwiFEKb/NGSAX5C/////wGDIhVCFIYgASgCFCIIIAVqrSIWIAI1AhAiF358IAIoAhQiBSAEaq0iGCABNQIQIhl+fCACKAIMIgStIhogEX4gASgCCCIJrSIbIAIoAggiCq0iHH58IAEoAgwiC60iHSASfnwgFyAOfnwgGSANfnwiHn0gASgCHCIMIAlqrSIfIAIoAhwiCSAKaq0iIH58IAIoAiAiCiAEaq0iISABKAIYIgQgBmqtIiJ+fCABKAIgIgEgC2qtIiMgAigCGCICIAdqrSIkfnwg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AUEXdnJB/////wFxNgKQAiACIAIoApQBIgFBDHQgA0EUdnJB/////wFxNgKUAiACIAIoApgBIgNBD3QgAUERdnJB/////wFxNgKYAiACIAIoApwBIgFBEnQgA0EOdnJB/////wFxNgKcAiACIAIoAqABIgNBFXQgAUELdnJB/////wFxNgKgAiACIAIoAqQBIgVBGHQgA0EIdnJB/////wFxNgKkAiACIAIoAsABIgNBDXY2AsgCIAIgAigCqAEiAUECdkH/////AXE2AqwCIAIgAUEbdCAFQQV2ckH/////AXE2AqgCIAIgAigCrAEiBUEBdCABQR92ckH/////AXE2ArACIAIgAigCsAEiAUEEdCAFQRx2ckH/////AXE2ArQCIAIgAigCtAEiBUEHdCABQRl2ckH/////AXE2ArgCIAIgAigCuAEiAUEKdCAFQRZ2ckH/////AXE2ArwCIAIgAigCvAEiBUENdCABQRN2ckH/////AXE2AsACIAIgA0EQdCAFQRB2ckH/////AXE2AsQCIAJBzAJqIAJBhAJqQcyIwAAQCAJAQSRFIgENACACQYQCaiACQcwCakEk/AoAAAsgAkHMAmogAkGoAmpBkMXAABAIAkAgAQ0AIAJBqAJqIAJBzAJqQST8CgAACyACQcwCaiACQagCaiACQYQCahAwIAAgAkHMAmoQHSACQfACaiQAC4wKAQV/IwBBsAVrIgIkACACIAE1AAA3A1AgAiABMQAFQg6GIAExAARCBoaEIAExAAZCFoaENwNYIAIgATEACEINhiABMQAHQgWGhCABMQAJQhWGhDcDYCACIAExAAtCC4YgATEACkIDhoQgATEADEIThoQ3A2ggAiABMQAOQgqGIAExAA1CAoaEIAExAA9CEoaENwNwIAIgATUAEDcDeCACIAExABVCD4YgATEAFEIHhoQgATEAFkIXhoQ3A4ABIAIgATEAGEINhiABMQAXQgWGhCABMQAZQhWGhDcDiAEgAiABMQAbQgyGIAExABpCBIaEIAExABxCFIaENwOQASACIAExAB5CCoYgATEAHUIChoQgAS0AHyIDQRJ0rUKAgPAPg4Q3A5gBIAJB9AFqIAJB0ABqECYgAkHQAGogAkH0AWoQEiACQZwCaiACQdAAahAmAkBBKEUNACACQfACaiACQZwCakEo/AoAAAsg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DQALIANByAFqIAFBCGopAAA3AgAgA0HQAWogAUEQaikAADcCACADQdgBaiABQRhqKQAANwIAIAMgASkAADcCwAECQEHgAUUNACAAQQRqIANB4AH8CgAAC0EAIQILIAAgAjoAACADQYAEaiQAC+gEAQR/IwBBgARrIgIkAEEAIQMCQEHAAEUNACACQQhqQQBBwAD8CwALA0AgAkEIaiADaiIEQQFqIAEtAAAiBUEEdjoAACAEIAVBD3E6AAAgAUEBaiEBIANBAmoiA0HAAEcNAAtBACEBA0AgAkEIaiABaiIDIAMtAAAiBCAEQQhqIgRB8AFxazoAACADQQFqIgMgAy0AACAEwEEEdmo6AAAgAUEBaiIBQT9HDQALQQAhAQJAQShFIgMNACACQcgAakEAQSj8CwALAkAgAw0AIAJByABqQShqQcSHwABBKPwKAAALAkAgAw0AIAJBmAFqQcSHwABBKPwKAAALAkAgAw0AIAJBwAFqQQBBKPwLAAsDQAJAAkACQCABQcAARg0AIAFBAXENAQwCCyACQegBaiACQcgAakEEEC4CQEGgAUUNACACQcgAaiACQegBakGgAfwKAAALQQAhAQNAAkACQAJAIAFBwABGDQAgAUEBcQ0CIAFBAXYhAyABQcAATw0BIAJBiANqIANBwAdsQdjFwABqIAJBCGogAWotAAAQIiACQegBaiACQcgAaiACQYgDahAWIAJByABqIAJB6AFqED4MAgsCQEGgAUUNACAAIAJByABqQaAB/AoAAAsgAkGABGokAA8LIANBIEHsh8AAEDsACyABQQFqIQEMAAsLIAFBAXYhAwJAIAFBwABPDQAgAkGIA2ogA0HAB2xB2MXAAGogAkEIaiABai0AABAiIAJB6AFqIAJByABqIAJBiANqEBYgAkHIAGogAkHoAWoQPgwBCyADQSBB7IfAABA7AAsgAUEBaiEBDAALC6wEAQR/IwBB8AJrIgMkACABQShqIQQCQEEoRQ0AIANBqAFqIARBKPwKAAALQQAhBQNAIANBqAFqIAVqIgYgBigCACABIAVqKAIAajYCACAFQQRqIgVBKEcNAAsCQEEoRSIFDQAgA0HQAWogBEEo/AoAAAsgA0HQAWogARAhIANBCGogA0GoAWogAhAMIANBMGogA0HQAWogAkEoahAMIANB2ABqIAFB+ABqIAJB+ABqEAwgA0GAAWogAUHQAGogAkHQAGoQDAJAIAUNACADQfgBaiADQYABakEo/AoAAAtBACEFA0AgA0H4AWogBWoiBiAGKAIAIANBgAFqIAVqKAIAajYCACAFQQRqIgVBKEcNAAsCQEEoRQ0AIANBoAJqIANBCGpBKPwKAAALIANBoAJqIANBMGoQIUEAIQUDQCADQQhqIAVqIgYgBigCACADQTBqIAVqKAIAajYCACAFQQRqIgVBKEcNAAsCQEEoRQ0AIANByAJqIANB+AFqQSj8CgAAC0EAIQUDQCADQcgCaiAFaiIGIAYoAgAgA0HYAGogBWooAgBqNgIAIAVBBGoiBUEoRw0ACyADQfgBaiADQdgAahAhAkBBKEUiBQ0AIAAgA0GgAmpBKPwKAAALAkAgBQ0AIABBKGogA0EIakEo/AoAAAsCQCAFDQAgAEHQAGogA0HIAmpBKPwKAAALAkAgBQ0AIABB+ABqIANB+AFqQSj8CgAACyADQfACaiQAC4wEAQR/IwBBwAJrIgMkACABQShqIQQCQEEoRQ0AIANB+ABqIARBKPwKAAALQQAhBQNAIANB+ABqIAVqIgYgBigCACABIAVqKAIAajYCACAFQQRqIgVBKEcNAAsCQEEoRSIFDQAgA0GgAWogBEEo/AoAAAsgA0GgAWogARAhIAMgA0H4AGogAhAMIANBKGogA0GgAWogAkEoahAMIANB0ABqIAFB+ABqIAJB0ABqEAwgAUHQAGohAQJAIAUNACADQcgBaiABQSj8CgAAC0EAIQUDQCADQcgBaiAFaiIGIAYoAgAgASAFaigCAGo2AgAgBUEEaiIFQShHDQALAkBBKEUNACADQfABaiADQSj8CgAACyADQfABaiADQShqECFBACEFA0AgAyAFaiIGIAYoAgAgA0EoaiAFaigCAGo2AgAgBUEEaiIFQShHDQALAkBBKEUNACADQZgCaiADQcgBakEo/AoAAAtBACEFA0AgA0GYAmogBWoiBiAGKAIAIANB0ABqIAVqKAIAajYCACAFQQRqIgVBKEcNAAsgA0HIAWogA0HQAGoQIQJAQShFIgUNACAAIANB8AFqQSj8CgAACwJAIAUNACAAQShqIANBKPwKAAALAkAgBQ0AIABB0ABqIANBmAJqQSj8CgAACwJAIAUNACAAQfgAaiADQcgBakEo/AoAAAsgA0HAAmokAAv/AwIGfwF+IwBB0ABrIgEkACABQcgAakIANwMAIAFBwABqQgA3AwAgAUE4akIANwMAIAFCADcDMEEgIQIgAUEwaiEDAkACQAJAAkADQCACRQ0BIAMgAkGAgAQgAkGAgARJGyIEEABBACkDoMFCIQdBAEIANwOgwUIgAiAEayECIAMgBGohAyAHp0EBRw0ACwJAIAdCgICAgMCAAVQNACAHQiCIpxABC0EAIQIgAUEANgI4IAFCgICAgBA3AjBBAyABQTBqEDcNAiABKAIwIQQgASgCNCIFIAEoAjgQAiEDIAQgBRA2QQEhBEEAIQUMAQsgAUEYaiIDIAFBMGpBCWopAAA3AwAgAUEgaiIEIAFBMGpBEWopAAA3AwAgAUEnaiIFIAFBMGpBGGopAAA3AAAgASABKQAxNwMQIAEtADAhBkEgEAQiAkUNAiACIAY6AAAgAiABKQMQNwABIAJBCWogAykDADcAACACQRFqIAQpAwA3AAAgAkEYaiAFKQAANwAAIAFBIDYCOCABIAI2AjQgAUEgNgIwIAFBCGogAUEwahA4IAEoAgwhBSABKAIIIQJBACEDQQAhBAsgACAENgIMIAAgAzYCCCAAIAU2AgQgACACNgIAIAFB0ABqJAAPC0HQgMAAQTcgAUEQakHAgMAAQZCFwAAQOQALQQFBIBBPAAuXBAEFfyMAQYAEayIDJAAgAyACNgKkAiADIAE2AqACIAMgAjYCnAIgA0EQaiADQZwCahA4IANBnAJqIAMoAhAiBCADKAIUIgEQEwJAAkACQAJAIAMtAJwCIgUNACADQYACaiADQakCaikAADcDACADQYgCaiADQbECaikAADcDACADQY8CaiADQbgCaikAADcAACADIAMpAKECNwP4ASADLQCgAiEGQcABIQIDQCADQRhqIAJqQQA6AAAgAkEBaiICQeABRw0AC0EgIQdBIBAEIgINAUEBQSAQTwALIAMtAJ0CIQIgA0EANgKkAiADQoCAgIAQNwKcAiACIANBnAJqEDcNAiADKAKcAiEHIAMoAqACIgYgAygCpAIQAiECIAcgBhA2QYCAgIB4IQcMAQsgAiAGOgAAIAIgAykD+AE3AAEgAkEJaiADQYACaikDADcAACACQRFqIANBiAJqKQMANwAAIAJBGGogA0GPAmopAAA3AAALAkAgAUUNACAEIAFBARA6CwJAAkAgBUUNAEEBIQFBACEFQQAhBAwBCyADQSA2AqQCIAMgAjYCoAIgAyAHNgKcAiADQQhqIANBnAJqEDhBACECIAMoAgghBSADKAIMIQRBACEBCyAAIAE2AgwgACACNgIIIAAgBDYCBCAAIAU2AgAgA0GABGokAA8LQdCAwABBNyADQRhqQcCAwABBkIXAABA5AAuFBAECfyAAIAFqIQICQAJAIAAoAgQiA0EBcQ0AIANBAnFFDQEgACgCACIDIAFqIQECQCAAIANrIgBBACgC8MBCRw0AIAIoAgRBA3FBA0cNAUEAIAE2AujAQiACIAIoAgRBfnE2AgQgACABQQFyNgIEIAIgATYCAAwCCyAAIAMQHwsCQAJAAkACQCACKAIEIgNBAnENACACQQAoAvTAQkYNAiACQQAoAvDAQkYNAyACIANBeHEiAxAfIAAgAyABaiIBQQFyNgIEIAAgAWogATYCACAAQQAoAvDAQkcNAUEAIAE2AujAQg8LIAIgA0F+cTYCBCAAIAFBAXI2AgQgACABaiABNgIACwJAIAFBgAJJDQAgACABECMPCwJAAkBBACgC4MBCIgJBASABQQN2dCIDcQ0AQQAgAiADcjYC4MBCIAFB+AFxQdi+wgBqIgEhAgwBCyABQfgBcSIBQdi+wgBqIQIgAUHgvsIAaigCACEBCyACIAA2AgggASAANgIMIAAgAjYCDCAAIAE2AggPC0EAIAA2AvTAQkEAQQAoAuzAQiABaiIBNgLswEIgACABQQFyNgIEIABBACgC8MBCRw0BQQBBADYC6MBCQQBBADYC8MBCDwtBACAANgLwwEJBAEEAKALowEIgAWoiATYC6MBCIAAgAUEBcjYCBCAAIAFqIAE2AgAPCwv6AwIEfwJ+IwBBMGsiCiQAQYCAgIB4IQsCQAJAIAUNAEGAgICAeCEFDAELIAogBjYCLCAKIAU2AiggCiAGNgIkIApBGGogCkEkahA4IAooAhwhBSAKKAIYIQwLAkACQCAHDQAMAQsgCiAINgIsIAogBzYCKCAKIAg2AiQgCkEQaiAKQSRqEDggCigCFCELIAooAhAhDQsCQAJAAkAgAg0AIAtBgICAgHhGIQZBACEHDAELIAtBgICAgHhGIQYCQEIAIAH8ByIOIAP8B30iDyAPIA5WGyIOIAT8B1QNAEEBIQcMAQsCQAJAAkACQCALQYCAgIB4Rg0AQQIhB0EAIAwgBUGAgICAeEYbIghFDQQgCyAFRw0EIAkgDSAIIAUQPSIHcg0BDAMLIAlFDQIMAQsgB0UNAEECQQQgBxshBwwCC0GAgMAAIQJBBiEHDAILAkAgDkI7Vg0AQbmAwAAhAkEGIQcMAgtBAyEHCyAHQQJ0IggoAqiFQCEHIAgoAriFQCECCwJAIAcQBCIIRQ0AAkAgB0UNACAIIAIgB/wKAAALAkAgBg0AIAsgDRA2CwJAIAVBgICAgHhGDQAgBSAMEDYLIAogBzYCLCAKIAg2AiggCiAHNgIkIApBCGogCkEkahA4IAAgCikDCDcCACAKQTBqJAAPC0EBIAcQRgALvgMBAX8jAEGgBmsiAiQAIAJB0AVqIAEQEiACIAJB0AVqECYgAkHQBWogAhASIAJBqAVqIAJB0AVqECYgAkHQBWogAkGoBWoQEiACQShqIAJB0AVqECYgAkHQAGogASACQShqEAwgAkH4AGogAiACQdAAahAMIAJB0AVqIAJB+ABqEBIgAkGgAWogAkHQBWoQJiACQcgBaiACQdAAaiACQaABahAMIAJB8AFqIAJByAFqQQUQMiACQZgCaiACQfABaiACQcgBahAMIAJBwAJqIAJBmAJqQQoQMiACQegCaiACQcACaiACQZgCahAMIAJBkANqIAJB6AJqQRQQMiACQbgDaiACQZADaiACQegCahAMIAJB4ANqIAJBuANqQQoQMiACQYgEaiACQeADaiACQZgCahAMIAJBsARqIAJBiARqQTIQMiACQdgEaiACQbAEaiACQYgEahAMIAJBgAVqIAJB2ARqQeQAEDIgAkGoBWogAkGABWogAkHYBGoQDCACQdAFaiACQagFakEyEDIgACACQdAFaiACQYgEahAMAkBBKEUNACAAQShqIAJB+ABqQSj8CgAACyACQaAGaiQAC7oDAQR/IwBBwAJrIgIkACACQfABaiABEBIgAiACQfABahAmIAJB8AFqIAFBKGoiAxASIAJBKGogAkHwAWoQJiACQfABaiABQdAAahASQQAhBANAIAJB8AFqIARqIgUgBSkDAEIBhjcDACAEQQhqIgRB0ABHDQALIAJB0ABqIAJB8AFqECYCQEEoRQ0AIAJBoAFqIAFBKPwKAAALQQAhBANAIAJBoAFqIARqIgUgBSgCACADIARqKAIAajYCACAEQQRqIgRBKEcNAAsgAkHwAWogAkGgAWoQEiACQfgAaiACQfABahAmAkBBKEUNACACQcgBaiACQShqQSj8CgAAC0EAIQQDQCACQcgBaiAEaiIFIAUoAgAgAiAEaigCAGo2AgAgBEEEaiIEQShHDQALIAJBKGogAhAhIAJB+ABqIAJByAFqECEgAkHQAGogAkEoahAhAkBBKEUiBA0AIAAgAkH4AGpBKPwKAAALAkAgBA0AIABBKGogAkHIAWpBKPwKAAALAkAgBA0AIABB0ABqIAJBKGpBKPwKAAALAkAgBA0AIABB+ABqIAJB0ABqQSj8CgAACyACQcACaiQAC5UDAQd/IAAgASgCICICOgAdIAAgASgCACIDOgAAIAAgAkEQdjoAHyAAIAJBCHY6AB4gACABKAIcIgRBFXY6ABwgACAEQQ12OgAbIAAgBEEFdjoAGiAAIAEoAhgiAkESdjoAGCAAIAJBCnY6ABcgACACQQJ2OgAWIAAgASgCFCIFQQ92OgAUIAAgBUEHdjoAEyAAIAEoAhAiBkEUdjoAESAAIAZBDHY6ABAgACAGQQR2OgAPIAAgASgCDCIHQRF2OgANIAAgB0EJdjoADCAAIAdBAXY6AAsgACABKAIIIghBDnY6AAkgACAIQQZ2OgAIIAAgASgCBCIBQRN2OgAGIAAgAUELdjoABSAAIAFBA3Y6AAQgACADQRB2OgACIAAgA0EIdjoAASAAIARBA3QgAkEadnI6ABkgACACQQZ0IAVBF3ZyOgAVIAAgBUEBdCAGQRx2cjoAEiAAIAZBBHQgB0EZdnI6AA4gACAHQQd0IAhBFnZyOgAKIAAgCEECdCABQRt2cjoAByAAIAFBBXQgA0EYdnI6AAML7wIBBX9BACECAkAgAUHN/3sgAEEQIABBEEsbIgBrTw0AIABBECABQQtqQXhxIAFBC0kbIgNqQQxqEAQiAUUNACABQXhqIQICQAJAIABBf2oiBCABcQ0AIAIhAAwBCyABQXxqIgUoAgAiBkF4cSAEIAFqQQAgAGtxQXhqIgFBACAAIAEgAmtBEEsbaiIAIAJrIgFrIQQCQCAGQQNxRQ0AIAAgBCAAKAIEQQFxckECcjYCBCAAIARqIgQgBCgCBEEBcjYCBCAFIAEgBSgCAEEBcXJBAnI2AgAgAiABaiIEIAQoAgRBAXI2AgQgAiABEBkMAQsgAigCACECIAAgBDYCBCAAIAIgAWo2AgALAkAgACgCBCIBQQNxRQ0AIAFBeHEiAiADQRBqTQ0AIAAgAyABQQFxckECcjYCBCAAIANqIgEgAiADayIDQQNyNgIEIAAgAmoiAiACKAIEQQFyNgIEIAEgAxAZCyAAQQhqIQILIAILiQMBBH8gACgCDCECAkACQAJAAkAgAUGAAkkNACAAKAIYIQMCQAJAAkAgAiAARw0AIABBFEEQIAAoAhQiAhtqKAIAIgENAUEAIQIMAgsgACgCCCIBIAI2AgwgAiABNgIIDAELIABBFGogAEEQaiACGyEEA0AgBCEFIAEiAkEUaiACQRBqIAIoAhQiARshBCACQRRBECABG2ooAgAiAQ0ACyAFQQA2AgALIANFDQICQAJAIAAgACgCHEECdEHIvcIAaiIBKAIARg0AIAMoAhAgAEYNASADIAI2AhQgAg0DDAQLIAEgAjYCACACRQ0EDAILIAMgAjYCECACDQEMAgsCQCACIAAoAggiBEYNACAEIAI2AgwgAiAENgIIDwtBAEEAKALgwEJBfiABQQN2d3E2AuDAQg8LIAIgAzYCGAJAIAAoAhAiAUUNACACIAE2AhAgASACNgIYCyAAKAIUIgFFDQAgAiABNgIUIAEgAjYCGA8LDwtBAEEAKALkwEJBfiAAKAIcd3E2AuTAQgvqAgEGfyMAQSBrIgJBGGpCADcDACACQRBqQgA3AwAgAkEIakIANwMAIAJCADcDAEEAIQMDQCACIANBAnRqIgQoAgAhBSABIQZBACEHA0AgBi0AACAHdCAFciEFIAZBAWohBiAHQQhqIgdBIEcNAAsgBCAFNgIAIAFBBGohASADQQFqIgNBCEcNAAsgACACKAIcIgZBCHY2AiAgACACKAIAIgdB/////wFxNgIAIAAgBkEVdCACKAIYIgZBC3ZyQf////8BcTYCHCAAIAZBEnQgAigCFCIGQQ52ckH/////AXE2AhggACAGQQ90IAIoAhAiBkERdnJB/////wFxNgIUIAAgBkEMdCACKAIMIgZBFHZyQf////8BcTYCECAAIAZBCXQgAigCCCIGQRd2ckH/////AXE2AgwgACAGQQZ0IAIoAgQiBkEadnJB/////wFxNgIIIAAgBkEDdCAHQR12ckH/////AXE2AgQL7wIBE38jAEGAAWsiAiQAIAEoAgAhAyAAKAIAIQQgASgCBCEFIAAoAgQhBiABKAIIIQcgACgCCCEIIAEoAgwhCSAAKAIMIQogASgCECELIAAoAhAhDCABKAIUIQ0gACgCFCEOIAEoAhghDyAAKAIYIRAgASgCHCERIAAoAhwhEiABKAIgIRMgACgCICEUIAIgACgCJCABKAIka0Hw////AWqtNwN4IAIgFCATa0Hw////A2qtNwNwIAIgEiARa0Hw////AWqtNwNoIAIgECAPa0Hw////A2qtNwNgIAIgDiANa0Hw////AWqtNwNYIAIgDCALa0Hw////A2qtNwNQIAIgCiAJa0Hw////AWqtNwNIIAIgCCAHa0Hw////A2qtNwNAIAIgBiAFa0Hw////AWqtNwM4IAIgBCADa0HQ/f//A2qtNwMwIAJBCGogAkEwahAmAkBBKEUNACAAIAJBCGpBKPwKAAALIAJBgAFqJAALxwIBBn8jAEGgAmsiAyQAAkBBKEUiBA0AIANBCGpBxIfAAEEo/AoAAAsgA0EIakEoaiEFAkAgBA0AIAVBxIfAAEEo/AoAAAsgA0HYAGohBgJAIAQNACAGQQBBKPwLAAsgAsAiBEEHdSIHIARqIAdzIQhBASEEA0AgA0EIaiABIAQgCHMiAkEAIAJrcsFBf0oQSBBEIAFB+ABqIQEgBEEBaiIEQQlHDQALIAdBAXEQSCEEAkBBKEUiAQ0AIANBgAFqIAVBKPwKAAALAkAgAQ0AIANB+AFqIAZBKPwKAAALIANB+AFqECsCQCABDQAgA0GAAWpBKGogA0EIakEo/AoAAAsCQCABDQAgA0HQAWogA0H4AWpBKPwKAAALIANBCGogA0GAAWogBBBEAkBB+ABFDQAgACADQQhqQfgA/AoAAAsgA0GgAmokAAu8AgEEf0EfIQICQCABQf///wdLDQAgAUEmIAFBCHZnIgJrdkEBcSACQQF0a0E+aiECCyAAQgA3AhAgACACNgIcIAJBAnRByL3CAGohAwJAQQAoAuTAQkEBIAJ0IgRxDQAgAyAANgIAIAAgAzYCGCAAIAA2AgwgACAANgIIQQBBACgC5MBCIARyNgLkwEIPCwJAAkACQCADKAIAIgQoAgRBeHEgAUcNACAEIQIMAQsgAUEAQRkgAkEBdmsgAkEfRht0IQMDQCAEIANBHXZBBHFqIgUoAhAiAkUNAiADQQF0IQMgAiEEIAIoAgRBeHEgAUcNAAsLIAIoAggiAyAANgIMIAIgADYCCCAAQQA2AhggACACNgIMIAAgAzYCCA8LIAVBEGogADYCACAAIAQ2AhggACAANgIMIAAgADYCCAuUAgIFfwR+IwBBMGshA0EAIQQCQEGAAkUNACAAQQBBgAL8CwALAkBBKEUNACADQQhqQQBBKPwLAAsDQCADQQhqIARqIAEgBGopAAA3AwAgBEEIaiIEQSBHDQALQcAAIAJrIQVCASACrYYiCEIBiCEJIAhCf3whCiAIpyEGQgAhC0EAIQQDQCADQQhqIARBA3ZB+P///wFxaiIHKQMAIARBP3EiAa2IIQgCQCABIAVJDQAgBykDCEHAACABa62GIAiEIQgLAkACQCAIIAqDIAt8IginIgFBAXENACAEQQFqIgRBgAJHDQIMAQsgACAEaiABIAZBACAIIAlaIgcbazoAACAHrSELIAQgAmoiBEGAAkkNAQsLC5QCAQN/IwBB0AFrIgIkACACQYABaiABQdAAahAbAkBBKEUiAw0AIAJBMGogAkGAAWpBKPwKAAALIAJBgAFqQShqIQQCQCADDQAgAkHYAGogBEEo/AoAAAsgAkGAAWogAkEwakEFEDIgAkEIaiACQYABaiACQdgAahAMIAJBgAFqIAEgAkEIahAMIAQgAUEoaiACQQhqEAwgAkEwaiAEEBAgAkHYAGogAkGAAWoQECACLQBYQQFxEEghASAAIAIpADA3AAAgAEEIaiACQTBqQQhqKQAANwAAIABBEGogAkEwakEQaikAADcAACACIAItAE8gAUEHdHM6AE8gAEEYaiACQTBqQRhqKQAANwAAIAJB0AFqJAALmwIBBn4gACABKQMwIAEpAyggASkDICICQhqIfCIDQhmIfCIEp0H///8fcTYCGCAAIAEpAxAgASkDCCABKQMAIgVCGoh8IgZCGYh8IgenQf///x9xNgIIIAAgASkDOCAEQhqIfCIEp0H///8PcTYCHCAAIAEpAxggB0IaiHwiB6dB////D3E2AgwgACABKQNAIARCGYh8IgSnQf///x9xNgIgIAAgA0L///8PgyACQv///x+DIAdCGYh8IgJCGoh8PgIUIAAgAqdB////H3E2AhAgACABKQNIIARCGoh8IgKnQf///w9xNgIkIAAgAkIZiEITfiAFQv///x+DfCICQhqIIAZC////D4N8PgIEIAAgAqdB////H3E2AgAL/QEBAX8gACABKAIAIAAoAgAiA3NBACACQf8BcWsiAnEgA3M2AgAgACABKAIEIAAoAgQiA3MgAnEgA3M2AgQgACABKAIIIAAoAggiA3MgAnEgA3M2AgggACABKAIMIAAoAgwiA3MgAnEgA3M2AgwgACABKAIQIAAoAhAiA3MgAnEgA3M2AhAgACABKAIUIAAoAhQiA3MgAnEgA3M2AhQgACABKAIYIAAoAhgiA3MgAnEgA3M2AhggACABKAIcIAAoAhwiA3MgAnEgA3M2AhwgACABKAIgIAAoAiAiA3MgAnEgA3M2AiAgACABKAIkIAAoAiQiAXMgAnEgAXM2AiQLgQICA38BfiMAQRBrIgYkAEEBIQdBBCEIAkACQCAEIAVqQX9qQQAgBGtxrSADrX4iCUIgiKcNACAJpyIDQYCAgIB4IARrSw0AAkACQCABDQBBACEIIAZBDGohBQwBCyAGIAQ2AgwgASAFbCEIIAZBCGohBQsgBSAINgIAAkACQAJAAkACQCAGKAIMRQ0AAkAgBigCCCIIDQAgAw0CIAQhCAwDCyACIAggBCADEA4hCAwCCyADDQAgBCEIDAILIAMQBCEICyAIDQAgACAENgIEDAELIAAgCDYCBEEAIQcLQQghCAwBC0EAIQMLIAAgCGogAzYCACAAIAc2AgAgBkEQaiQAC/MBAQR/IwBB4ANrIgEkACABIABBAxAuAkBBKEUiAA0AIAFBoAFqQQBBKPwLAAsgAUGgAWpBKGohAgJAIAANACACQcSHwABBKPwKAAALIAFBoAFqQdAAaiEDAkAgAA0AIANBxIfAAEEo/AoAAAsCQCAADQAgAUGYAmpBAEEo/AsACyABQcACaiABIAMQDCABQegCaiABQaABaiABQdAAaiIAEAwgAUHAAmogAUHoAmoQMSEEIAFBkANqIAFBKGogAxAMIAFBuANqIAIgABAMIAQgAUGQA2ogAUG4A2oQMXEQSCEAIAFB4ANqJAAgAEH/AXFBAEcL2QEBBH8jAEEwayICJABBACEDAkBBJEUNACACQQxqQQBBJPwLAAtBACEEA0AgAkEMaiADaiABIANqKAIAIARBH3VqIANBtMXAAGooAgBrIgRB/////wFxNgIAIANBBGoiA0EkRw0AC0EAIQNBACAEQR92EEhB/wFxayEFQQAhBANAIAJBDGogA2oiASABKAIAIARBHXZqIANBtMXAAGooAgAgBXFqIgRB/////wFxNgIAIANBBGoiA0EkRw0ACwJAQSRFDQAgACACQQxqQST8CgAACyACQTBqJAAL7QEBAX8jAEGAAWsiASQAIAFB8P///wEgACgCJGutNwNQIAFB8P///wMgACgCIGutNwNIIAFB8P///wEgACgCHGutNwNAIAFB8P///wMgACgCGGutNwM4IAFB8P///wEgACgCFGutNwMwIAFB8P///wMgACgCEGutNwMoIAFB8P///wEgACgCDGutNwMgIAFB8P///wMgACgCCGutNwMYIAFB8P///wEgACgCBGutNwMQIAFB0P3//wMgACgCAGutNwMIIAFB2ABqIAFBCGoQJgJAQShFDQAgACABQdgAakEo/AoAAAsgAUGAAWokAAvOAQEEfyMAQdAAayICJAAgAUEoaiEDAkBBKEUNACACIANBKPwKAAALQQAhBANAIAIgBGoiBSAFKAIAIAEgBGooAgBqNgIAIARBBGoiBEEoRw0ACwJAQShFIgQNACACQShqIANBKPwKAAALIAJBKGogARAhAkAgBA0AIABB0ABqIAFB0ABqQSj8CgAACyAAQfgAaiABQfgAakHYtcIAEAwCQCAEDQAgACACQSj8CgAACwJAIAQNACAAQShqIAJBKGpBKPwKAAALIAJB0ABqJAALsQEBAn8jAEEgayICJAAgAS0AACEDIAJBF2ogAUEXaikAADcAACACQRFqIAFBEWopAAA3AAAgAkEJaiABQQlqKQAANwAAIAIgA0H4AXE6AAAgAiABKQABNwABIAIgAS0AH0E/cUHAAHI6AB8gACACEAkgAEE4aiABQThqKQAANwAAIABBMGogAUEwaikAADcAACAAQShqIAFBKGopAAA3AAAgACABKQAgNwAgIAJBIGokAAurAQECfyMAQcADayIDJAACQEEoRSIEDQAgA0GoAWpBKGogAUEoakEo/AoAAAsCQCAEDQAgA0GoAWpB0ABqIAFB0ABqQSj8CgAACwJAIAQNACADQagBaiABQSj8CgAACyACQX9qIQQDQCADQQhqIANBqAFqEBwgA0GoAWogA0EIahBBIARBf2oiBA0ACyADQaACaiADQagBahAcIAAgA0GgAmoQPiADQcADaiQAC5UBAQF/IwBBEGsiAyQAAkACQAJAIAIgAWoiASACTw0AQQAhAwwBCyADQQRqIAAoAgAiAiAAKAIEIAEgAkEBdCICIAEgAksbIgJBCCACQQhLGyICQQFBARAoIAMoAgRBAUcNASADKAIMIQAgAygCCCEDCyADIAAQRgALIAMoAgghASAAIAI2AgAgACABNgIEIANBEGokAAtzAQN/IwBBMGsiAyQAQQAhBAJAQSRFDQAgA0EMakEAQST8CwALQQAhBQNAIANBDGogBGogASAEaigCACAFQR12aiACIARqKAIAaiIFQf////8BcTYCACAEQQRqIgRBJEcNAAsgACADQQxqECogA0EwaiQAC2sBAn8jAEHAAGsiAiQAIAIgABAQIAJBIGogARAQQQEhAUEAIQADQCACQSBqIABqLQAAIAIgAGotAABzIgNBACADa3LAQX9KEEggAXEhASAAQQFqIgBBIEcNAAsgARBIIQAgAkHAAGokACAAC2sBAX8jAEGAAWsiAyQAIANBMGogARASIAJBf2ohASADQQhqIANBMGoQJgNAIANBMGogA0EIahASIANBCGogA0EwahAmIAFBf2oiAQ0ACwJAQShFDQAgACADQQhqQSj8CgAACyADQYABaiQAC3gBA38jAEEQayIBJAACQCAAKAIAIgIoAgQiA0EBcUUNACACKAIAIQIgASADQQF2NgIEIAEgAjYCACABQQQgACgCCCIALQAIIAAtAAkQNAALIAFBgICAgHg2AgAgASAANgIMIAFBBSAAKAIIIgAtAAggAC0ACRA0AAt3AQJ/IwBBEGsiBCQAQQBBACgCmMFCIgVBAWo2ApjBQgJAIAVBAEgNAAJAAkBBAC0AlMFCDQBBAEEAKAKQwUJBAWo2ApDBQkEAKAKcwUJBf0oNAQwCCyAEQQhqIAAgAREDAAALQQBBADoAlMFCIAJFDQAQVgALAAuLAQICfgF8IAH8ByICQjwgAkI8VhsiAkKA9SQgAkKA9SRUG7oiBCAERAAAAAAAGPVAIAQgAb0iAkIAUxtEAAAAAAAY9UAgAkL///////////8AgyIDQoCAgICAgIB4fEKAgICAgICA8P8AVBsgAkJ/fEL/////////B1QbIANQ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';\n","/* @ts-self-types=\"./post_core_wasm.d.ts\" */\n\n/**\n * A new 32-byte private key seed.\n * @returns {Uint8Array}\n */\nexport function generateSeed() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.generateSeed(retptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);\n if (r3) {\n throw takeObject(r2);\n }\n var v1 = getArrayU8FromWasm0(r0, r1).slice();\n wasm.__wbindgen_export2(r0, r1 * 1, 1);\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n}\n\n/**\n * What a receiver does with a signature before checking it\n * (`post_core::discovery::decide`): `verify`, `refuse`, or\n * `refetch-missing`, `refetch-expired`, `refetch-id`, `refetch-kid`.\n * Times are whole seconds since the epoch; `fetched_at` is absent when\n * nothing is held.\n * @param {number} now\n * @param {number | null | undefined} fetched_at\n * @param {number} max_age\n * @param {string | null | undefined} cached_id\n * @param {string | null | undefined} txt_id\n * @param {boolean} kid_known\n * @returns {string}\n */\nexport function policyDecision(now, fetched_at, max_age, cached_id, txt_id, kid_known) {\n let deferred3_0;\n let deferred3_1;\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n var ptr0 = isLikeNone(cached_id) ? 0 : passStringToWasm0(cached_id, wasm.__wbindgen_export3, wasm.__wbindgen_export4);\n var len0 = WASM_VECTOR_LEN;\n var ptr1 = isLikeNone(txt_id) ? 0 : passStringToWasm0(txt_id, wasm.__wbindgen_export3, wasm.__wbindgen_export4);\n var len1 = WASM_VECTOR_LEN;\n wasm.policyDecision(retptr, now, !isLikeNone(fetched_at), isLikeNone(fetched_at) ? 0 : fetched_at, max_age, ptr0, len0, ptr1, len1, kid_known);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n deferred3_0 = r0;\n deferred3_1 = r1;\n return getStringFromWasm0(r0, r1);\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n wasm.__wbindgen_export2(deferred3_0, deferred3_1, 1);\n }\n}\n\n/**\n * The `max_age` to cache a policy for, from the value it published\n * (`post_core::discovery::max_age`). Seconds.\n * @param {number | null} [published]\n * @returns {number}\n */\nexport function policyMaxAge(published) {\n const ret = wasm.policyMaxAge(!isLikeNone(published), isLikeNone(published) ? 0 : published);\n return ret;\n}\n\n/**\n * The 32-byte public key for a seed.\n * @param {Uint8Array} seed\n * @returns {Uint8Array}\n */\nexport function publicKey(seed) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(seed, wasm.__wbindgen_export3);\n const len0 = WASM_VECTOR_LEN;\n wasm.publicKey(retptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);\n if (r3) {\n throw takeObject(r2);\n }\n var v2 = getArrayU8FromWasm0(r0, r1).slice();\n wasm.__wbindgen_export2(r0, r1 * 1, 1);\n return v2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n}\n\n/**\n * The 64-byte Ed25519 signature over `message` exactly as given.\n * @param {Uint8Array} seed\n * @param {Uint8Array} message\n * @returns {Uint8Array}\n */\nexport function sign(seed, message) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(seed, wasm.__wbindgen_export3);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(message, wasm.__wbindgen_export3);\n const len1 = WASM_VECTOR_LEN;\n wasm.sign(retptr, ptr0, len0, ptr1, len1);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);\n if (r3) {\n throw takeObject(r2);\n }\n var v3 = getArrayU8FromWasm0(r0, r1).slice();\n wasm.__wbindgen_export2(r0, r1 * 1, 1);\n return v3;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n}\n\n/**\n * Whether `signature` is `public_key`'s strict Ed25519 signature over `message`.\n * @param {Uint8Array} public_key\n * @param {Uint8Array} message\n * @param {Uint8Array} signature\n * @returns {boolean}\n */\nexport function verify(public_key, message, signature) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(public_key, wasm.__wbindgen_export3);\n const len0 = WASM_VECTOR_LEN;\n const ptr1 = passArray8ToWasm0(message, wasm.__wbindgen_export3);\n const len1 = WASM_VECTOR_LEN;\n const ptr2 = passArray8ToWasm0(signature, wasm.__wbindgen_export3);\n const len2 = WASM_VECTOR_LEN;\n wasm.verify(retptr, ptr0, len0, ptr1, len1, ptr2, len2);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n if (r2) {\n throw takeObject(r1);\n }\n return r0 !== 0;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n}\nfunction __wbg_get_imports() {\n const import0 = {\n __proto__: null,\n __wbg_Error_30c8987f7c2ed4e2: function(arg0, arg1) {\n const ret = Error(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n },\n __wbg_getRandomValues_436a51d0629d84e1: function() { return handleError(function (arg0, arg1) {\n globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));\n }, arguments); },\n __wbindgen_object_drop_ref: function(arg0) {\n takeObject(arg0);\n },\n };\n return {\n __proto__: null,\n \"./post_core_wasm_bg.js\": import0,\n };\n}\n\nfunction addHeapObject(obj) {\n if (heap_next === heap.length) heap.push(heap.length + 1);\n const idx = heap_next;\n heap_next = heap[idx];\n\n heap[idx] = obj;\n return idx;\n}\n\nfunction dropObject(idx) {\n if (idx < 1028) return;\n heap[idx] = heap_next;\n heap_next = idx;\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nlet cachedDataViewMemory0 = null;\nfunction getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n}\n\nfunction getStringFromWasm0(ptr, len) {\n return decodeText(ptr >>> 0, len);\n}\n\nlet cachedUint8ArrayMemory0 = null;\nfunction getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n}\n\nfunction getObject(idx) { return heap[idx]; }\n\nfunction handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n wasm.__wbindgen_export(addHeapObject(e));\n }\n}\n\nlet heap = new Array(1024).fill(undefined);\nheap.push(undefined, null, true, false);\n\nlet heap_next = heap.length;\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n\nfunction passArray8ToWasm0(arg, malloc) {\n const ptr = malloc(arg.length * 1, 1) >>> 0;\n getUint8ArrayMemory0().set(arg, ptr / 1);\n WASM_VECTOR_LEN = arg.length;\n return ptr;\n}\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n if (realloc === undefined) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n\n const mem = getUint8ArrayMemory0();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7F) break;\n mem[ptr + offset] = code;\n }\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = cachedTextEncoder.encodeInto(arg, view);\n\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n\n WASM_VECTOR_LEN = offset;\n return ptr;\n}\n\nfunction takeObject(idx) {\n const ret = getObject(idx);\n dropObject(idx);\n return ret;\n}\n\nlet cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\ncachedTextDecoder.decode();\nconst MAX_SAFARI_DECODE_BYTES = 2146435072;\nlet numBytesDecoded = 0;\nfunction decodeText(ptr, len) {\n numBytesDecoded += len;\n if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n numBytesDecoded = len;\n }\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n\nconst cachedTextEncoder = new TextEncoder();\n\nif (!('encodeInto' in cachedTextEncoder)) {\n cachedTextEncoder.encodeInto = function (arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n };\n}\n\nlet WASM_VECTOR_LEN = 0;\n\nlet wasmModule, wasmInstance, wasm;\nfunction __wbg_finalize_init(instance, module) {\n wasmInstance = instance;\n wasm = instance.exports;\n wasmModule = module;\n cachedDataViewMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n return wasm;\n}\n\nasync function __wbg_load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (!module.ok) {\n throw new Error(`failed to fetch Wasm: ${module.status} ${module.statusText} fetching '${module.url}'`);\n }\n\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n } catch (e) {\n const validResponse = expectedResponseType(module.type);\n\n if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {\n console.warn(\"`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else { throw e; }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n } else {\n return instance;\n }\n }\n\n function expectedResponseType(type) {\n switch (type) {\n case 'basic': case 'cors': case 'default': return true;\n }\n return false;\n }\n}\n\nfunction initSync(module) {\n if (wasm !== undefined) return wasm;\n\n\n if (module !== undefined) {\n if (Object.getPrototypeOf(module) === Object.prototype) {\n ({module} = module)\n } else {\n console.warn('using deprecated parameters for `initSync()`; pass a single object instead')\n }\n }\n\n const imports = __wbg_get_imports();\n if (!(module instanceof WebAssembly.Module)) {\n module = new WebAssembly.Module(module);\n }\n const instance = new WebAssembly.Instance(module, imports);\n return __wbg_finalize_init(instance, module);\n}\n\nasync function __wbg_init(module_or_path) {\n if (wasm !== undefined) return wasm;\n\n\n if (module_or_path !== undefined) {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({module_or_path} = module_or_path)\n } else {\n console.warn('using deprecated parameters for the initialization function; pass a single object instead')\n }\n }\n\n\n const imports = __wbg_get_imports();\n\n if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {\n module_or_path = fetch(module_or_path);\n }\n\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nexport { initSync, __wbg_init as default };\n","import { createHash, randomBytes } from 'node:crypto';\n\nimport { type Identity, verifyBytes } from './keys';\n\n/**\n * Signing an agent's HTTP requests: RFC 9421 HTTP Message Signatures as\n * Web Bot Auth profiles them (draft-ietf-webbotauth-httpsig-protocol-01),\n * in the form Cloudflare verifies today.\n *\n * - `keyid` is the key's JWK thumbprint; `alg=\"ed25519\"`; `tag=\"web-bot-auth\"`.\n * - `Signature-Agent` names `https://post.<domain>`, which serves the key\n * directory (`/.well-known/http-message-signatures-directory`) and the\n * domain's agent cards. Sent as the bare string Cloudflare reads, not\n * the draft's dictionary, until Cloudflare reads that (both verify at\n * Pidgeon).\n * - Covered: `@method`, `@authority`, `@path`, `@query` when there is one,\n * `signature-agent`, `from` (the agent's address, the header RFC 9110\n * gives a robot's operator), `post-grant` when it carries grants, and\n * `content-digest` when there is a body.\n * So a signature holds for this request only, not for any request to\n * the host.\n * - Valid for five minutes. Cloudflare suggests a minute; an agent behind a\n * queue needs more.\n *\n * An MCP call over Streamable HTTP is an HTTP request, so `signedFetch` is\n * also how an agent signs MCP: give it to the transport as `fetch`.\n */\n\nexport const TAG = 'web-bot-auth';\nexport const SIGNATURE_SECONDS = 300;\n\nexport interface SignRequestInput {\n method: string;\n url: string;\n headers?: Record<string, string>;\n body?: string | Uint8Array | null;\n /** The agent's address, `support-agent@acme.com`: sent and covered as `From`. */\n agent?: string | null;\n /** Override the clock, for tests. Milliseconds. */\n now?: number;\n /** The signature's label. */\n label?: string;\n /** The tag. Pidgeon's issuance API uses its own, so an agent's signature is never an operator's. */\n tag?: string;\n /**\n * Grants the agent was given (compact JWS): sent as `Post-Grant`,\n * comma-separated, and covered like `From`, so the receiver sees what it\n * may do. A grant holds only for the agent it names, whoever forwards it.\n */\n grants?: string[];\n seconds?: number;\n}\n\nconst quote = (value: string) => `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n\nfunction authority(url: URL): string {\n const defaultPort =\n (url.protocol === 'https:' && url.port === '443') ||\n (url.protocol === 'http:' && url.port === '80');\n return `${url.hostname.toLowerCase()}${url.port && !defaultPort ? `:${url.port}` : ''}`;\n}\n\nfunction bytesOf(body: string | Uint8Array): Uint8Array {\n return typeof body === 'string' ? new TextEncoder().encode(body) : body;\n}\n\nexport function contentDigest(body: string | Uint8Array): string {\n return `sha-256=:${createHash('sha256').update(bytesOf(body)).digest('base64')}:`;\n}\n\n/**\n * The headers that sign this request, lower-cased: `signature-agent`,\n * `from`, `content-digest` (with a body), `signature-input`, `signature`.\n * Add them to the request as they are; change nothing they cover after.\n */\nexport async function signRequest(\n identity: Identity,\n input: SignRequestInput,\n): Promise<Record<string, string>> {\n const url = new URL(input.url);\n const label = input.label ?? 'sig1';\n const created = Math.floor((input.now ?? Date.now()) / 1000);\n const expires = created + (input.seconds ?? SIGNATURE_SECONDS);\n const agent = input.agent?.trim().toLowerCase() ?? null;\n if (agent && !agent.endsWith(`@${identity.domain}`)) {\n throw new Error(`${agent} is not an address at ${identity.domain}, whose key this is.`);\n }\n\n const added: Record<string, string> = {\n 'signature-agent': quote(`https://post.${identity.domain}`),\n ...(agent ? { from: agent } : {}),\n ...(input.grants?.length\n ? { 'post-grant': input.grants.map((jws) => jws.replace(/\\s+/g, '')).join(', ') }\n : {}),\n };\n const body = input.body === undefined || input.body === null ? null : bytesOf(input.body);\n if (body && body.length > 0) added['content-digest'] = contentDigest(body);\n\n const values: [string, string][] = [\n ['@method', input.method.toUpperCase()],\n ['@authority', authority(url)],\n ['@path', url.pathname || '/'],\n ...(url.search ? ([['@query', url.search]] as [string, string][]) : []),\n ['signature-agent', added['signature-agent']!],\n ...(added.from ? ([['from', added.from]] as [string, string][]) : []),\n ...(added['post-grant'] ? ([['post-grant', added['post-grant']]] as [string, string][]) : []),\n ...(added['content-digest']\n ? ([['content-digest', added['content-digest']]] as [string, string][])\n : []),\n ];\n\n const params =\n `(${values.map(([name]) => quote(name)).join(' ')})` +\n `;created=${created};expires=${expires};keyid=${quote(identity.kid)};alg=\"ed25519\"` +\n `;nonce=${quote(randomBytes(32).toString('base64'))};tag=${quote(input.tag ?? TAG)}`;\n const base = [\n ...values.map(([name, value]) => `${quote(name)}: ${value}`),\n `\"@signature-params\": ${params}`,\n ].join('\\n');\n\n const signature = identity.sign(new TextEncoder().encode(base));\n return {\n ...added,\n 'signature-input': `${label}=${params}`,\n signature: `${label}=:${Buffer.from(signature).toString('base64')}:`,\n };\n}\n\ntype Fetch = typeof globalThis.fetch;\n\n/**\n * `fetch`, signing every request as `agent`. For MCP:\n *\n * ```ts\n * new StreamableHTTPClientTransport(new URL(server), { fetch: signedFetch(identity, { agent }) })\n * ```\n */\nexport function signedFetch(\n identity: Identity,\n options: { agent: string; fetch?: Fetch; grants?: string[] },\n): Fetch {\n const base = options.fetch ?? globalThis.fetch;\n return async (resource, init) => {\n const request = new Request(resource, init);\n const body = request.body ? new Uint8Array(await request.arrayBuffer()) : null;\n const headers: Record<string, string> = {};\n request.headers.forEach((value, name) => {\n headers[name] = value;\n });\n const signature = await signRequest(identity, {\n method: request.method,\n url: request.url,\n headers,\n body,\n agent: options.agent,\n grants: options.grants,\n });\n const signedHeaders = new Headers(request.headers);\n for (const [name, value] of Object.entries(signature)) signedHeaders.set(name, value);\n return base(request.url, {\n method: request.method,\n headers: signedHeaders,\n body: body && body.length > 0 ? body : undefined,\n redirect: request.redirect,\n signal: request.signal,\n });\n };\n}\n\n// --- Verifying, for a receiver ---------------------------------------------------\n\nexport interface VerifyRequestInput {\n method: string;\n url: string;\n headers: Record<string, string> | Headers;\n body?: string | Uint8Array | null;\n}\n\nexport type RequestCheck =\n | {\n ok: true;\n keyid: string;\n agent: string | null;\n from: string | null;\n created: number;\n /** What the signature covers, by name: a receiver insists on the ones it needs. */\n components: string[];\n nonce: string | null;\n }\n | { ok: false; reason: string };\n\n/**\n * Checks a request signed by `signRequest` or any Web Bot Auth signer that\n * covers what it does: the components it names, inside its window, under\n * the key `key` returns. A receiver that wants who the agent is and whose\n * it is asks Pidgeon instead (`POST /v1/verify` with `request`), which looks\n * the key up and attaches the card.\n */\nexport async function verifyRequest(\n input: VerifyRequestInput,\n options: {\n key: (keyid: string, agent: string | null) => Promise<Uint8Array | null>;\n now?: number;\n tag?: string;\n },\n): Promise<RequestCheck> {\n const headers = new Map<string, string>();\n if (input.headers instanceof Headers)\n input.headers.forEach((value, name) => headers.set(name, value));\n else\n for (const [name, value] of Object.entries(input.headers))\n headers.set(name.toLowerCase(), value);\n\n const signatureInput = headers.get('signature-input') ?? '';\n const tag = options.tag ?? TAG;\n // `label=(components);params`, one per comma outside quotes and parentheses.\n const members = splitTopLevel(signatureInput);\n const member = members.find((entry) => entry.includes(`tag=${quote(tag)}`));\n if (!member) return { ok: false, reason: 'unsigned' };\n\n const eq = member.indexOf('=');\n const label = member.slice(0, eq).trim();\n const params = member.slice(eq + 1).trim();\n const list = /^\\(([^)]*)\\)/.exec(params)?.[1];\n if (list === undefined) return { ok: false, reason: 'malformed' };\n const components = [...list.matchAll(/\"([^\"]+)\"((?:;[a-z]+(?:=\"[^\"]*\")?)*)/g)].map((match) => ({\n name: match[1]!,\n params: match[2] ?? '',\n }));\n const number = (name: string) => Number(new RegExp(`;${name}=(\\\\d+)`).exec(params)?.[1] ?? NaN);\n const keyid = /;keyid=\"([^\"]+)\"/.exec(params)?.[1];\n const created = number('created');\n const expires = number('expires');\n if (!keyid || Number.isNaN(created) || Number.isNaN(expires))\n return { ok: false, reason: 'missing_parameters' };\n\n const now = Math.floor((options.now ?? Date.now()) / 1000);\n if (expires <= now) return { ok: false, reason: 'expired' };\n if (created > now + 60 || expires - created > 86_400) return { ok: false, reason: 'window' };\n\n const signature = new RegExp(`(?:^|,)\\\\s*${label}=:([^:]+):`).exec(\n headers.get('signature') ?? '',\n )?.[1];\n if (!signature) return { ok: false, reason: 'malformed' };\n\n const url = new URL(input.url);\n const value = (name: string, componentParams: string): string | null => {\n switch (name) {\n case '@method':\n return input.method.toUpperCase();\n case '@authority':\n return authority(url);\n case '@path':\n return url.pathname || '/';\n case '@query':\n return url.search || '?';\n case '@target-uri':\n return url.href;\n }\n const raw = headers.get(name)?.trim();\n if (raw === undefined) return null;\n const key = /;key=\"([^\"]+)\"/.exec(componentParams)?.[1];\n if (!key) return raw;\n return new RegExp(`(?:^|,)\\\\s*${key}=(\"[^\"]*\")`).exec(raw)?.[1] ?? null;\n };\n\n const lines: string[] = [];\n for (const component of components) {\n const found = value(component.name, component.params);\n if (found === null) return { ok: false, reason: 'missing_component' };\n lines.push(`${quote(component.name)}${component.params}: ${found}`);\n }\n lines.push(`\"@signature-params\": ${params}`);\n\n const agentRaw = headers.get('signature-agent')?.trim() ?? null;\n const agent = agentRaw ? (/\"([^\"]+)\"/.exec(agentRaw)?.[1] ?? null) : null;\n const publicKey = await options.key(keyid, agent);\n if (!publicKey) return { ok: false, reason: 'unknown_key' };\n if (\n !verifyBytes(\n publicKey,\n new TextEncoder().encode(lines.join('\\n')),\n new Uint8Array(Buffer.from(signature, 'base64')),\n )\n ) {\n return { ok: false, reason: 'bad_signature' };\n }\n\n if (components.some((component) => component.name === 'content-digest') && input.body) {\n if (headers.get('content-digest') !== contentDigest(input.body))\n return { ok: false, reason: 'body_changed' };\n }\n\n const from = components.some((component) => component.name === 'from')\n ? (headers.get('from')?.trim().toLowerCase() ?? null)\n : null;\n const nonce = /;nonce=\"([^\"]+)\"/.exec(params)?.[1] ?? null;\n return {\n ok: true,\n keyid,\n agent,\n from,\n created,\n components: components.map((component) => component.name),\n nonce,\n };\n}\n\nfunction splitTopLevel(value: string): string[] {\n const out: string[] = [];\n let depth = 0;\n let quoted = false;\n let start = 0;\n for (let i = 0; i < value.length; i++) {\n const c = value[i];\n if (c === '\"' && value[i - 1] !== '\\\\') quoted = !quoted;\n else if (!quoted && c === '(') depth++;\n else if (!quoted && c === ')') depth--;\n else if (!quoted && depth === 0 && c === ',') {\n out.push(value.slice(start, i).trim());\n start = i + 1;\n }\n }\n if (value.slice(start).trim()) out.push(value.slice(start).trim());\n return out;\n}\n","import { signRequest } from './http';\nimport { b64url, type Identity } from './keys';\n\n/**\n * Pidgeon's issuance API (`/api/id`), for an operator with no account.\n *\n * **The key is the account.** Every request is signed with the operator's\n * key — HTTP Message Signatures with the tag `pidgeon-id`, never\n * `web-bot-auth`, so a signature an agent made for somebody's API is never\n * one the issuance API accepts — and the server finds the domain from the\n * `keyid`. Nothing to sign up for and no token to leak.\n */\n\nexport const ISSUANCE_TAG = 'pidgeon-id';\nexport const DEFAULT_ID_URL = 'https://pidgeon.ai/api/id';\n\nexport interface DnsRecord {\n purpose: 'proof' | 'host';\n type: 'TXT' | 'CNAME';\n /** Relative to the domain: `_post`, `post`. */\n name: string;\n value: string;\n /** Whether it is in place now. */\n found: boolean;\n}\n\nexport interface IdDomain {\n object: 'id_domain';\n domain: string;\n status: 'pending' | 'verified' | 'lapsed';\n kid: string;\n /** `_post` proves the domain; `post` serves its keys and cards at `post.<domain>`. */\n records: DnsRecord[];\n /** One click at the DNS provider, when it offers Domain Connect. */\n setup_url: string | null;\n}\n\nexport interface AgentCardDocument {\n object: 'agent_card';\n url: string;\n jws: string;\n card: Record<string, unknown> & { address: string; exp: number };\n}\n\nexport interface IdAgent {\n object: 'id_agent';\n address: string;\n kind: 'agent' | 'service';\n on_behalf_of: string | null;\n created_at: string;\n card_url: string;\n}\n\nexport interface IdGrant {\n object: 'grant';\n id: string;\n status: string;\n agent: string;\n grantor: { type: 'organisation'; domain: string } | { type: 'person'; email: string };\n scope: { name: string; label: string; limit?: { amount: number; currency: string } };\n audience: string | null;\n subject: { type: string; id: string };\n expires_at: string;\n revoked_at: string | null;\n /** What the agent carries, while the grant is in force. */\n jws: string | null;\n /** Where the person asked answers, on the answer that asked them. */\n consent_url?: string;\n}\n\nexport class IdApiError extends Error {\n constructor(\n readonly status: number,\n readonly code: string | undefined,\n message: string,\n ) {\n super(message);\n }\n}\n\nexport class IdClient {\n constructor(\n private readonly identity: Identity,\n private readonly baseUrl: string = DEFAULT_ID_URL,\n private readonly fetcher: typeof fetch = fetch,\n ) {}\n\n private async call<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl.replace(/\\/$/, '')}${path}`;\n const text = body === undefined ? null : JSON.stringify(body);\n const headers: Record<string, string> = text ? { 'content-type': 'application/json' } : {};\n Object.assign(\n headers,\n await signRequest(this.identity, { method, url, headers, body: text, tag: ISSUANCE_TAG }),\n );\n\n const response = await this.fetcher(url, { method, headers, body: text ?? undefined });\n const json = (await response.json().catch(() => null)) as {\n data?: T;\n error?: { code?: string; message?: string };\n } | null;\n if (!response.ok || !json || json.data === undefined) {\n throw new IdApiError(\n response.status,\n json?.error?.code,\n json?.error?.message ?? `Pidgeon answered ${response.status}.`,\n );\n }\n return json.data;\n }\n\n /** Claim the domain with this key. Idempotent: a second call returns the same records. */\n claim(): Promise<IdDomain> {\n return this.call('POST', '/domains', {\n domain: this.identity.domain,\n public_key: b64url(this.identity.publicKey),\n });\n }\n\n /** Look at DNS now; `verified` once `_post` says this key's id. */\n check(): Promise<IdDomain> {\n return this.call('POST', '/domains/check', { domain: this.identity.domain });\n }\n\n issue(input: {\n name: string;\n kind?: 'agent' | 'service';\n on_behalf_of?: string;\n }): Promise<AgentCardDocument> {\n return this.call('POST', '/agents', input);\n }\n\n list(): Promise<IdAgent[]> {\n return this.call('GET', '/agents');\n }\n\n revoke(name: string): Promise<{ object: 'id_agent'; address: string; revoked: true }> {\n return this.call('DELETE', `/agents/${encodeURIComponent(name)}`);\n }\n\n /**\n * The domain grants one of its own agents, at once: what it may do, for\n * which customer, account or order, where, until when (at most 90 days).\n */\n grant(input: {\n agent: string;\n scope: { name: string; label: string; limit?: { amount: number; currency: string } };\n subject: { type: 'customer' | 'account' | 'order'; id: string };\n audience?: string;\n expires_at?: string;\n /** Ask a person instead of granting as the domain: the answer has a `consent_url` for them. */\n grantor?: { email: string };\n }): Promise<IdGrant> {\n return this.call('POST', '/grants', input);\n }\n\n /** Every token Sign in with Pidgeon issued `name`, taken back; its card and grants stand. */\n revokeSignIns(name: string): Promise<{ object: 'id_agent'; address: string; revoked: number }> {\n return this.call('DELETE', `/agents/${encodeURIComponent(name)}/sign-ins`);\n }\n\n revokeGrant(id: string): Promise<IdGrant> {\n return this.call('DELETE', `/grants/${encodeURIComponent(id)}`);\n }\n\n /**\n * Publish `next` as the domain's key, signed by the current one. `proof`\n * is `next`'s own signature over the rotation, so nobody can rotate a\n * domain onto a key they do not hold.\n */\n rotate(next: Identity): Promise<IdDomain> {\n const statement = rotationStatement(this.identity.domain, this.identity.kid, next.kid);\n return this.call('POST', '/keys', {\n public_key: b64url(next.publicKey),\n proof: b64url(next.sign(new TextEncoder().encode(statement))),\n });\n }\n}\n\n/** What a new key signs to show it is held by whoever asks for it. The server builds the same. */\nexport function rotationStatement(domain: string, from: string, to: string): string {\n return `pidgeon id rotate\\n${domain}\\n${from}\\n${to}`;\n}\n","import { randomBytes } from 'node:crypto';\n\nimport { signRequest } from './http';\nimport { b64url, generateIdentity, type Identity } from './keys';\n\n/**\n * Sign in with Pidgeon, from the agent's side: no browser, no password, no\n * person present.\n *\n * 1. **At Pidgeon**, an RFC 8693 token exchange signed with the agent's key:\n * its card as the subject token, the site's `client_id` as the audience,\n * and its grant, when it acts under one, in `Post-Grant`. Out comes an ID\n * token for that site, bound to this key.\n * 2. **At the site**, the ID token as an RFC 7523 JWT-bearer grant, signed\n * again with the same key, so a copy of the token is no use to anyone\n * else. The site answers with its own session.\n *\n * The site says where both are: `GET` on its token endpoint answers its\n * issuer, any more issuers it accepts agents from, and its `client_id`\n * (`@pidgeon-ai/sign-in` serves it). The agent goes to the issuer that\n * signed its card when the site lists it (a company's own, self-hosted), and\n * to the site's issuer otherwise.\n *\n * An agent whose address is in a Pidgeon account holds no signing key of its\n * own: we sign its mail. It signs in with `signInWithApiKey` instead, sending\n * an API key that can send as the address. That key goes only to the issuer\n * the agent names, never to one a site names, and the ID token is bound to a\n * key made for this one sign-in, shown to Pidgeon with a DPoP proof\n * (RFC 9449).\n */\n\n/** Pidgeon's issuer, the only one an API key is sent to unless the agent says otherwise. */\nexport const PIDGEON_ISSUER = 'https://post.pidgeon.email';\n\nexport const TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange';\nexport const JWT_BEARER = 'urn:ietf:params:oauth:grant-type:jwt-bearer';\nconst TOKEN_TYPE_JWT = 'urn:ietf:params:oauth:token-type:jwt';\n\ntype Fetch = typeof globalThis.fetch;\n\nexport interface SignInWithPidgeonInput {\n /** The agent's address, `support-agent@acme.com`. */\n agent: string;\n /** The site's token endpoint for agents, as its button or docs give it. */\n site: string;\n /** A grant the agent acts under (its JWS), when it has one for this site. */\n grant?: string;\n /** The card's compact JWS. Fetched from `post.<domain>` when not given. */\n card?: string;\n /** Where a domain's protocol host answers. Default `https://post.<domain>`; a laptop's differs. */\n postHost?: (domain: string) => string;\n /**\n * Ask for the access token as a JWT that says the agent acts for its\n * grantor (RFC 8693 §4.1: `sub` the grantor, `act` the agent), for an API\n * to read. Needs `grant`.\n */\n delegation?: boolean;\n fetch?: Fetch;\n}\n\nexport interface SiteMetadata {\n issuer: string;\n /** Every issuer the site accepts agents from, `issuer` first. */\n issuers: string[];\n client_id: string;\n token_endpoint: string;\n}\n\nexport interface PidgeonSignIn {\n /** What the site answered: its session, and what it learned. */\n site: Record<string, unknown>;\n /** The ID token Pidgeon issued, for reading; the site checked it. */\n idToken: string;\n /** Pidgeon's userinfo token, for as long as the grant lasts and ten minutes at most. */\n accessToken: string;\n}\n\nexport class SignInError extends Error {\n constructor(\n readonly step: 'site' | 'card' | 'pidgeon',\n readonly status: number,\n readonly code: string | undefined,\n message: string,\n ) {\n super(message);\n }\n}\n\nasync function json(response: Response): Promise<Record<string, unknown>> {\n return ((await response.json().catch(() => null)) ?? {}) as Record<string, unknown>;\n}\n\nfunction form(values: Record<string, string>): string {\n return new URLSearchParams(values).toString();\n}\n\n/** The site's issuer and `client_id`, from `GET` on its token endpoint. */\nexport async function siteMetadata(site: string, fetcher: Fetch = fetch): Promise<SiteMetadata> {\n const response = await fetcher(site, { headers: { accept: 'application/json' } });\n const body = await json(response);\n if (!response.ok || typeof body.issuer !== 'string' || typeof body.client_id !== 'string') {\n throw new SignInError(\n 'site',\n response.status,\n undefined,\n `${site} does not offer Sign in with Pidgeon.`,\n );\n }\n const trim = (issuer: string) => issuer.replace(/\\/$/, '');\n const listed = Array.isArray(body.issuers)\n ? body.issuers.filter((issuer): issuer is string => typeof issuer === 'string').map(trim)\n : [];\n return {\n issuer: body.issuer,\n issuers: [...new Set([trim(body.issuer), ...listed])],\n client_id: body.client_id,\n token_endpoint: site,\n };\n}\n\n/** The issuer to sign in at: the one that signed the card, when the site lists it, else the site's. */\nfunction issuerFor(site: SiteMetadata, card: string): string {\n try {\n const payload = JSON.parse(Buffer.from(card.split('.')[1] ?? '', 'base64url').toString('utf8'));\n const iss = typeof payload?.iss === 'string' ? payload.iss.replace(/\\/$/, '') : null;\n if (iss && site.issuers.includes(iss)) return iss;\n } catch {\n // Not a card we can read: the issuer will say so.\n }\n return site.issuer.replace(/\\/$/, '');\n}\n\n/** The agent's card, from its domain's protocol host. */\nexport async function fetchCard(\n agent: string,\n fetcher: Fetch = fetch,\n postHost: (domain: string) => string = (domain) => `https://post.${domain}`,\n): Promise<string> {\n const domain = agent.split('@')[1] ?? '';\n const response = await fetcher(\n `${postHost(domain)}/.well-known/post/card?address=${encodeURIComponent(agent)}`,\n );\n const body = await json(response);\n if (!response.ok || typeof body.jws !== 'string') {\n throw new SignInError(\n 'card',\n response.status,\n undefined,\n `${agent} has no card to sign in with.`,\n );\n }\n return body.jws;\n}\n\n/** Signs in to `site` as `agent`, with its own key, in the two steps above. */\nexport function signInWithPidgeon(\n identity: Identity,\n input: SignInWithPidgeonInput,\n): Promise<PidgeonSignIn> {\n return signIn(identity, input, async ({ tokenEndpoint, exchange, headers, agent }) =>\n signRequest(identity, {\n method: 'POST',\n url: tokenEndpoint,\n headers,\n body: exchange,\n agent,\n grants: input.grant ? [input.grant] : undefined,\n }),\n );\n}\n\nexport interface SignInWithApiKeyInput extends SignInWithPidgeonInput {\n /** A key that can send as `agent`. */\n apiKey: string;\n /** The issuer the key may go to. Default `PIDGEON_ISSUER`; a site naming another is refused. */\n issuer?: string;\n}\n\n/**\n * Signs in to `site` as an address in a Pidgeon account, with an API key\n * that can send as it. The key is sent to `issuer` and nowhere else.\n */\nexport function signInWithApiKey(input: SignInWithApiKeyInput): Promise<PidgeonSignIn> {\n const agent = input.agent.trim().toLowerCase();\n const domain = agent.split('@')[1] ?? '';\n // A key for this sign-in only. It never leaves this process.\n const ephemeral = generateIdentity(domain);\n const issuer = (input.issuer ?? PIDGEON_ISSUER).replace(/\\/$/, '');\n\n // Before anything is fetched from it: an issuer the site names is not\n // contacted at all unless it is ours (found porting this to Python, 6 November).\n const admit = (site: SiteMetadata) => {\n if (site.issuer.replace(/\\/$/, '') !== issuer) {\n throw new SignInError(\n 'site',\n 0,\n 'unknown_issuer',\n `${site.token_endpoint} signs in with ${site.issuer}, not ${issuer}, so your API key is not sent there.`,\n );\n }\n };\n\n return signIn(\n ephemeral,\n input,\n async ({ tokenEndpoint, site }) => {\n if (\n site.issuer.replace(/\\/$/, '') !== issuer ||\n new URL(tokenEndpoint).origin !== new URL(issuer).origin\n ) {\n throw new SignInError(\n 'site',\n 0,\n 'unknown_issuer',\n `${site.token_endpoint} signs in with ${site.issuer}, not ${issuer}, so your API key is not sent there.`,\n );\n }\n return {\n authorization: `Bearer ${input.apiKey}`,\n dpop: dpopProof(ephemeral, 'POST', tokenEndpoint),\n ...(input.grant ? { 'post-grant': input.grant.replace(/\\s+/g, '') } : {}),\n };\n },\n admit,\n );\n}\n\n/** RFC 9449 §4.2: a proof that this request comes from whoever holds `identity`'s key. */\nexport function dpopProof(identity: Identity, method: string, url: string): string {\n const encode = (value: unknown) => Buffer.from(JSON.stringify(value)).toString('base64url');\n const target = new URL(url);\n const header = encode({\n typ: 'dpop+jwt',\n alg: 'EdDSA',\n jwk: { kty: 'OKP', crv: 'Ed25519', x: b64url(identity.publicKey) },\n });\n const payload = encode({\n jti: randomBytes(16).toString('base64url'),\n htm: method.toUpperCase(),\n htu: `${target.origin}${target.pathname}`,\n iat: Math.floor(Date.now() / 1000),\n });\n const signature = identity.sign(new TextEncoder().encode(`${header}.${payload}`));\n return `${header}.${payload}.${b64url(signature)}`;\n}\n\ntype Authenticate = (request: {\n tokenEndpoint: string;\n exchange: string;\n headers: Record<string, string>;\n agent: string;\n site: SiteMetadata;\n}) => Promise<Record<string, string>>;\n\nasync function signIn(\n identity: Identity,\n input: SignInWithPidgeonInput,\n authenticate: Authenticate,\n /** Refuses a site before its issuer is contacted. */\n admit?: (site: SiteMetadata) => void,\n): Promise<PidgeonSignIn> {\n const fetcher = input.fetch ?? fetch;\n const agent = input.agent.trim().toLowerCase();\n const site = await siteMetadata(input.site, fetcher);\n admit?.(site);\n const card = input.card ?? (await fetchCard(agent, fetcher, input.postHost));\n // An API key goes to the site's issuer only, which `admit` already checked.\n const issuer = admit ? site.issuer.replace(/\\/$/, '') : issuerFor(site, card);\n\n // 1. Pidgeon: the card and the grant, for this site, from whoever can show they are the agent.\n const discovery = await json(await fetcher(`${issuer}/.well-known/openid-configuration`));\n const tokenEndpoint = discovery.token_endpoint;\n if (typeof tokenEndpoint !== 'string') {\n throw new SignInError('pidgeon', 0, undefined, `${issuer} has no token endpoint.`);\n }\n const exchange = form({\n grant_type: TOKEN_EXCHANGE,\n subject_token: card,\n subject_token_type: TOKEN_TYPE_JWT,\n audience: site.client_id,\n ...(input.delegation ? { requested_token_type: TOKEN_TYPE_JWT } : {}),\n });\n const headers = { 'content-type': 'application/x-www-form-urlencoded' };\n const issued = await fetcher(tokenEndpoint, {\n method: 'POST',\n headers: {\n ...headers,\n ...(await authenticate({ tokenEndpoint, exchange, headers, agent, site })),\n },\n body: exchange,\n });\n const tokens = await json(issued);\n if (!issued.ok || typeof tokens.id_token !== 'string') {\n throw new SignInError(\n 'pidgeon',\n issued.status,\n tokens.error as string | undefined,\n (tokens.error_description as string | undefined) ?? `Pidgeon answered ${issued.status}.`,\n );\n }\n\n // 2. The site: the ID token as a JWT-bearer grant, signed with the same key.\n const bearer = form({ grant_type: JWT_BEARER, assertion: tokens.id_token });\n const answered = await fetcher(site.token_endpoint, {\n method: 'POST',\n headers: {\n ...headers,\n ...(await signRequest(identity, {\n method: 'POST',\n url: site.token_endpoint,\n headers,\n body: bearer,\n agent,\n })),\n },\n body: bearer,\n });\n const session = await json(answered);\n if (!answered.ok) {\n throw new SignInError(\n 'site',\n answered.status,\n session.error as string | undefined,\n (session.error_description as string | undefined) ?? `The site answered ${answered.status}.`,\n );\n }\n return {\n site: session,\n idToken: tokens.id_token,\n accessToken: tokens.access_token as string,\n };\n}\n","import { DEFAULT_ID_URL, IdApiError, IdClient, type IdDomain } from './api';\nimport { signedFetch } from './http';\nimport { SignInError, signInWithPidgeon } from './sign-in';\nimport {\n generateIdentity,\n identityDir,\n listIdentities,\n loadIdentity,\n saveIdentity,\n type StoredIdentity,\n} from './keys';\n\n/**\n * `pidgeon id`: an agent identity on your own domain, no account.\n *\n * pidgeon id init acme.com key made here, domain proved over DNS\n * pidgeon id issue support-agent card live at post.acme.com\n * pidgeon id list | revoke <name> | rotate | check\n * pidgeon id grant <name> … what an agent may do, for whom, until when\n * pidgeon id sign-in <site> --as <name> Sign in with Pidgeon, as the agent\n * pidgeon id verify < message.eml ask the public verifier about a message\n * pidgeon id curl -I <url> --as <name> a request signed as the agent\n *\n * Also `npx @pidgeon-ai/id <command>`, which is this without the `id`.\n * Cards renew themselves: each is signed for a day when it is read, for as\n * long as the domain's `_post` record stands.\n */\n\nexport class UsageError extends Error {}\n\nexport interface IdRunOptions {\n /** Progress, while `init` waits for DNS. Never the answer. */\n stderr?: (line: string) => void;\n fetch?: typeof fetch;\n sleep?: (ms: number) => Promise<void>;\n /** The message for `verify` when no file is named: standard input. */\n stdin?: () => Promise<string>;\n}\n\nconst HELP = `pidgeon id — a signed identity for your agents, on your own domain. No account.\n\n init <domain> Make a key on this machine and prove the domain over DNS\n check [<domain>] Look at DNS again\n issue <name> Give <name>@<domain> a card --kind agent|service --on-behalf-of <who>\n list Agents on the domain\n revoke <name> Withdraw an agent's card now\n rotate Replace the domain's key; the old one verifies for another day\n grant <name> Grant <name> what it may do, as the domain\n --scope bookings.change --label \"manage bookings\"\n --subject customer:42 --audience delta.com --days 30\n --grantor maria@example.com ask a person instead\n revoke-grant <id> Take a grant back now\n revoke-sign-ins <name> End every token <name> signed in with; its card and grants stand\n sign-in <site> Sign in to a site as an agent --as <name> --grant <jws>\n verify [<file>] Check a message's signatures (a file, or standard input). No key\n curl [-I] <url> Send a request signed as an agent --as <name>\n\n --domain <domain> Which domain, when this machine holds more than one\n --json Print the API's answer as JSON\n --no-wait init: print the records and return\n\nKeys live in ${'$'}PIDGEON_ID_DIR (default ~/.config/pidgeon/id). They never leave this machine.`;\n\ninterface Args {\n positional: string[];\n flags: Map<string, string | true>;\n}\n\nfunction parse(argv: string[]): Args {\n const positional: string[] = [];\n const flags = new Map<string, string | true>();\n for (let i = 0; i < argv.length; i++) {\n const token = argv[i]!;\n if (!token.startsWith('--')) {\n positional.push(token);\n continue;\n }\n const [name, inline] = token.slice(2).split('=', 2) as [string, string | undefined];\n if (['json', 'no-wait', 'help'].includes(name)) flags.set(name, true);\n else {\n const value = inline ?? argv[++i];\n if (value === undefined) throw new UsageError(`--${name} needs a value.`);\n flags.set(name, value);\n }\n }\n return { positional, flags };\n}\n\nconst DOMAIN = /^(?=.{4,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$/;\n\nfunction baseUrl(env: Record<string, string | undefined>): string {\n if (env.PIDGEON_ID_URL) return env.PIDGEON_ID_URL;\n // The main CLI's base, `…/api/v1`, names the same host.\n if (env.PIDGEON_BASE_URL) return env.PIDGEON_BASE_URL.replace(/\\/v1\\/?$/, '/id');\n return DEFAULT_ID_URL;\n}\n\nfunction describeRecords(domain: IdDomain): string[] {\n const lines = domain.records.map(\n (record) =>\n ` ${record.found ? '✓' : '·'} ${record.type.padEnd(5)} ${`${record.name}.${domain.domain}`.padEnd(28)} ${record.value}`,\n );\n return lines;\n}\n\nexport async function runId(\n argv: string[],\n env: Record<string, string | undefined> = process.env,\n options: IdRunOptions = {},\n): Promise<string> {\n const { positional, flags } = parse(argv);\n const [command, ...rest] = positional;\n if (!command || flags.has('help') || command === 'help') return HELP;\n\n const dir = identityDir(env);\n const json = flags.has('json');\n const say = options.stderr ?? (() => {});\n const sleep =\n options.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));\n const client = (identity: StoredIdentity) => new IdClient(identity, baseUrl(env), options.fetch);\n\n async function which(): Promise<StoredIdentity> {\n const named = flags.get('domain');\n if (typeof named === 'string') return loadIdentity(named, { dir, env });\n if (env.PIDGEON_ID_KEY) return loadIdentity(env.PIDGEON_ID_KEY.split(':')[0]!, { dir, env });\n const held = await listIdentities(dir);\n if (held.length === 1) return loadIdentity(held[0]!, { dir, env });\n if (held.length === 0)\n throw new UsageError('No domain here yet. Start with `pidgeon id init <domain>`.');\n throw new UsageError(`This machine holds ${held.join(', ')}. Say which with --domain.`);\n }\n\n try {\n switch (command) {\n case 'init': {\n const domain = rest[0]?.trim().toLowerCase().replace(/\\.$/, '');\n if (!domain || !DOMAIN.test(domain))\n throw new UsageError('Name the domain: `pidgeon id init acme.com`.');\n\n let identity: StoredIdentity;\n let made = false;\n try {\n identity = await loadIdentity(domain, { dir, env });\n } catch {\n identity = generateIdentity(domain);\n await saveIdentity(identity, dir);\n made = true;\n }\n\n let state = await client(identity).claim();\n if (json && (state.status === 'verified' || flags.has('no-wait')))\n return JSON.stringify(state, null, 2);\n\n const lines = [\n made\n ? `Made a signing key for ${domain} on this machine (${identity.kid}).`\n : `Using the key for ${domain} on this machine.`,\n ];\n if (state.status !== 'verified') {\n lines.push(\n '',\n state.setup_url\n ? `Add the records in one click: ${state.setup_url}\\n\\nOr add them by hand:`\n : 'Add these records at your DNS provider:',\n ...describeRecords(state),\n '',\n 'The first proves the domain is yours. The second serves its keys and cards at',\n `post.${domain}; without it Pidgeon still verifies your agents, and nobody else can.`,\n );\n if (flags.has('no-wait')) return [...lines, '', 'Then: pidgeon id check'].join('\\n');\n\n say(lines.join('\\n'));\n say('\\nWaiting for DNS…');\n const deadline = Date.now() + Number(flags.get('timeout') ?? 600) * 1000;\n while (state.status !== 'verified' && Date.now() < deadline) {\n await sleep(5000);\n state = await client(identity).check();\n }\n if (state.status !== 'verified') {\n return 'Not yet. DNS can take a while; run `pidgeon id check` once the record is in.';\n }\n lines.length = 0;\n }\n if (json) return JSON.stringify(state, null, 2);\n return [...lines, `${domain} is proved. Next: pidgeon id issue support-agent`]\n .join('\\n')\n .trim();\n }\n\n case 'check': {\n const identity = rest[0] ? await loadIdentity(rest[0], { dir, env }) : await which();\n const state = await client(identity).check();\n if (json) return JSON.stringify(state, null, 2);\n return [\n `${state.domain}: ${state.status === 'verified' ? 'proved' : state.status}`,\n ...describeRecords(state),\n ].join('\\n');\n }\n\n case 'issue': {\n const name = rest[0]?.trim().toLowerCase();\n if (!name) throw new UsageError('Name the agent: `pidgeon id issue support-agent`.');\n const identity = await which();\n const kind = flags.get('kind');\n if (kind !== undefined && kind !== 'agent' && kind !== 'service') {\n throw new UsageError('--kind is agent or service.');\n }\n const onBehalfOf = flags.get('on-behalf-of');\n const card = await client(identity).issue({\n name,\n ...(kind ? { kind } : {}),\n ...(typeof onBehalfOf === 'string' ? { on_behalf_of: onBehalfOf } : {}),\n });\n if (json) return JSON.stringify(card, null, 2);\n return [\n `${card.card.address} has a card: ${card.url}`,\n `Found from the address at https://post.${identity.domain}/.well-known/post/card?address=${card.card.address}`,\n 'It renews itself. Sign with it: import { loadIdentity, signEmail, signedFetch } from \"@pidgeon-ai/id\".',\n ].join('\\n');\n }\n\n case 'verify': {\n // The public verifier, which needs no key: whoever received the mail asks.\n const file = rest[0];\n const message = file\n ? await (await import('node:fs/promises')).readFile(file, 'utf8')\n : await (options.stdin ?? readStdin)();\n if (!message.trim()) {\n throw new UsageError('Give it a message: `pidgeon id verify < message.eml`.');\n }\n const response = await (options.fetch ?? fetch)(\n `${new URL(baseUrl(env)).origin}/api/v1/verify`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ message }),\n },\n );\n const answer = (await response.json()) as {\n data?: Verification;\n error?: { message?: string };\n };\n if (!response.ok || !answer.data) {\n throw new UsageError(\n answer.error?.message ?? `The verifier answered ${response.status}.`,\n );\n }\n if (json) return JSON.stringify(answer.data, null, 2);\n return describeVerification(answer.data);\n }\n\n case 'curl': {\n // `-I` as curl spells it: a HEAD request, and only the answer's head.\n const head = rest[0] === '-I';\n const target = (head ? rest[1] : rest[0])?.trim();\n if (!target) throw new UsageError('Name a URL: `pidgeon id curl -I shop.example`.');\n const url = /^https?:\\/\\//.test(target) ? target : `https://${target}`;\n const identity = await which();\n const named = flags.get('as');\n let agent: string;\n if (typeof named === 'string') {\n agent = named.includes('@') ? named : `${named}@${identity.domain}`;\n } else {\n const agents = await client(identity).list();\n if (agents.length !== 1) {\n throw new UsageError('Say which agent signs, with --as <name>.');\n }\n agent = agents[0]!.address;\n }\n\n const sent: Record<string, string> = {};\n const signed = signedFetch(identity, {\n agent,\n fetch: async (resource, init) => {\n new Headers(init?.headers).forEach((value, name) => {\n if (/^(signature|signature-input|signature-agent|from|content-digest)$/.test(name)) {\n sent[name] = value;\n }\n });\n return (options.fetch ?? fetch)(resource, init);\n },\n });\n const response = await signed(url, { method: head ? 'HEAD' : 'GET' });\n const lines = Object.entries(sent).map(\n ([name, value]) => `> ${capitalise(name)}: ${value}`,\n );\n lines.push(`< ${response.status} ${response.statusText}`.trimEnd());\n if (head) {\n response.headers.forEach((value, name) => lines.push(`< ${capitalise(name)}: ${value}`));\n return lines.join('\\n');\n }\n return [...lines, '', await response.text()].join('\\n');\n }\n\n case 'list': {\n const agents = await client(await which()).list();\n if (json) return JSON.stringify(agents, null, 2);\n if (agents.length === 0)\n return 'No agents yet. `pidgeon id issue <name>` gives one a card.';\n return agents\n .map((agent) => `${agent.address} ${agent.kind} ${agent.card_url}`)\n .join('\\n');\n }\n\n case 'revoke': {\n const name = rest[0]?.trim().toLowerCase();\n if (!name) throw new UsageError('Name the agent: `pidgeon id revoke support-agent`.');\n const revoked = await client(await which()).revoke(name);\n if (json) return JSON.stringify(revoked, null, 2);\n return `${revoked.address} has no card from now on. Copies already fetched lapse within a day.`;\n }\n\n case 'rotate': {\n const current = await which();\n const next = generateIdentity(current.domain);\n const state = await client(current).rotate(next);\n next.previous = { kid: current.kid, publicKey: current.publicKey };\n await saveIdentity(next, dir);\n if (json) return JSON.stringify(state, null, 2);\n return `${current.domain} signs with ${next.kid} now. ${current.kid} still verifies for a day.`;\n }\n\n case 'grant': {\n const name = rest[0]?.trim().toLowerCase();\n const scope = flags.get('scope');\n const label = flags.get('label');\n const subject = flags.get('subject');\n if (!name || typeof scope !== 'string' || typeof label !== 'string') {\n throw new UsageError(\n 'Name the agent and the scope: `pidgeon id grant support-agent --scope bookings.change --label \"manage bookings\" --subject customer:42`.',\n );\n }\n const [type, ...idParts] = typeof subject === 'string' ? subject.split(':') : [];\n if (!type || idParts.length === 0 || !['customer', 'account', 'order'].includes(type)) {\n throw new UsageError('--subject is customer:<id>, account:<id> or order:<id>.');\n }\n const days = flags.get('days');\n const audience = flags.get('audience');\n const grantor = flags.get('grantor');\n const grant = await client(await which()).grant({\n agent: name,\n scope: { name: scope, label },\n subject: { type: type as 'customer' | 'account' | 'order', id: idParts.join(':') },\n ...(typeof audience === 'string' ? { audience } : {}),\n ...(typeof grantor === 'string' ? { grantor: { email: grantor } } : {}),\n ...(typeof days === 'string'\n ? { expires_at: new Date(Date.now() + Number(days) * 86_400_000).toISOString() }\n : {}),\n });\n if (json) return JSON.stringify(grant, null, 2);\n if (grant.consent_url) {\n return [\n `Asked ${typeof grantor === 'string' ? grantor : 'them'} to let ${grant.agent} ${grant.scope.label} for ${grant.subject.type} ${grant.subject.id}.`,\n `Send them this link; nothing is allowed until they answer it: ${grant.consent_url}`,\n `Grant ${grant.id}. \\`pidgeon id revoke-grant ${grant.id}\\` withdraws the request.`,\n ].join('\\n');\n }\n return [\n `${grant.agent} may ${grant.scope.label} for ${grant.subject.type} ${grant.subject.id}${grant.audience ? ` at ${grant.audience}` : ''}, until ${grant.expires_at}.`,\n `Grant ${grant.id}. The agent carries it as Post-Grant; --json prints the JWS.`,\n ].join('\\n');\n }\n\n case 'revoke-grant': {\n const grantId = rest[0]?.trim();\n if (!grantId) throw new UsageError('Name the grant: `pidgeon id revoke-grant <id>`.');\n const revoked = await client(await which()).revokeGrant(grantId);\n if (json) return JSON.stringify(revoked, null, 2);\n return `Grant ${revoked.id} is revoked. The next check of it fails.`;\n }\n\n case 'revoke-sign-ins': {\n const name = rest[0]?.trim().toLowerCase();\n if (!name)\n throw new UsageError('Name the agent: `pidgeon id revoke-sign-ins support-agent`.');\n const done = await client(await which()).revokeSignIns(name);\n if (json) return JSON.stringify(done, null, 2);\n return `${done.address}: ${done.revoked} token${done.revoked === 1 ? '' : 's'} taken back. Its card and grants stand.`;\n }\n\n case 'sign-in': {\n const site = rest[0];\n const name = flags.get('as');\n if (!site || typeof name !== 'string') {\n throw new UsageError(\n 'Name the site and the agent: `pidgeon id sign-in https://site.example/api/auth/pidgeon/token --as support-agent`.',\n );\n }\n const identity = await which();\n // `issue` answers a live agent's card as it is, so this is also how the agent reads its card.\n const card = await client(identity).issue({ name: name.trim().toLowerCase() });\n const grant = flags.get('grant');\n try {\n const signedIn = await signInWithPidgeon(identity, {\n agent: card.card.address,\n site,\n card: card.jws,\n ...(typeof grant === 'string' ? { grant } : {}),\n ...(options.fetch ? { fetch: options.fetch } : {}),\n });\n if (json) return JSON.stringify(signedIn.site, null, 2);\n return `Signed in to ${new URL(site).host} as ${card.card.address}.\\n${JSON.stringify(signedIn.site, null, 2)}`;\n } catch (error) {\n if (error instanceof SignInError) throw new Error(`${error.step}: ${error.message}`);\n throw error;\n }\n }\n\n default:\n throw new UsageError(`No such command \"${command}\".\\n\\n${HELP}`);\n }\n } catch (error) {\n if (error instanceof IdApiError) {\n throw new Error(error.code ? `${error.code}: ${error.message}` : error.message);\n }\n throw error;\n }\n}\n\n// --- verify and curl ----------------------------------------------------------\n\ninterface Verification {\n verdict: string;\n advice: string;\n sender: { address: string; on_behalf_of: string | null } | null;\n is_agent: boolean | null;\n body: 'intact' | 'changed' | 'not_checked';\n signatures: {\n declaration: { result: string; domain: string | null };\n envelope: { result: string; domain: string | null };\n };\n}\n\n/** The verifier's answer as the homepage shows it: a line a check, ✓ or ✗. */\nfunction describeVerification(v: Verification): string {\n const signer = v.signatures.envelope.domain ?? v.signatures.declaration.domain;\n const signed =\n v.signatures.envelope.result === 'pass' || v.signatures.declaration.result === 'pass';\n const broken =\n v.signatures.envelope.result === 'fail' || v.signatures.declaration.result === 'fail';\n const row = (ok: boolean | null, label: string, value: string) =>\n `${ok === null ? '·' : ok ? '✓' : '✗'} ${label.padEnd(10)} ${value}`;\n return [\n row(\n signed && !broken,\n 'signature',\n signed && !broken\n ? `valid, ${signer}`\n : broken\n ? `broken${signer ? `, ${signer}` : ''}`\n : 'none',\n ),\n row(v.is_agent, 'agent', v.sender?.address ?? 'not declared'),\n row(v.sender?.on_behalf_of ? true : null, 'acts for', v.sender?.on_behalf_of ?? 'not said'),\n row(\n v.body === 'not_checked' ? null : v.body === 'intact',\n 'body',\n v.body === 'intact'\n ? 'as it was sent'\n : v.body === 'changed'\n ? 'changed since'\n : 'not checked',\n ),\n '',\n v.advice,\n ].join('\\n');\n}\n\nfunction capitalise(name: string): string {\n return name.replace(\n /(^|-)([a-z])/g,\n (_, dash: string, letter: string) => dash + letter.toUpperCase(),\n );\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString('utf8');\n}\n","import {\n createCipheriv,\n createDecipheriv,\n createHash,\n createPublicKey,\n randomBytes,\n timingSafeEqual,\n verify,\n type JsonWebKey,\n} from 'node:crypto';\n\n/**\n * A person signs in at the issuer: Pidgeon Cloud's person flow, with the\n * company's own identity provider where Cloud has its consent page.\n *\n * The site speaks to the issuer exactly as it speaks to Cloud (the\n * authorization code flow with PKCE and a nonce, `@pidgeon-ai/sign-in`'s\n * `login` and `callback`). The issuer is a relying party of the company's\n * OpenID Connect provider (Keycloak, Auth0, Okta, Entra): it sends the\n * browser there with its own PKCE, state and nonce, checks the ID token\n * that comes back, and signs the person in to the site as `kind: person`\n * with the provider's `sub` and a verified address at the domain.\n *\n * **No database.** What a store would hold travels sealed (AES-256-GCM\n * under `PIDGEON_ISSUER_SECRET`): the sign-in in progress in an HttpOnly\n * cookie on the issuer's host, bound to the browser that started it; the\n * code, sixty seconds, used once through the issuer's replay store.\n * Rotating the secret ends the sign-ins in flight, and nothing else.\n */\n\n/** The company's identity provider, as its relying party. */\nexport interface PersonOptions {\n /** At least 32 characters. Seals the sign-in in progress and the code. */\n secret: string;\n oidc: {\n /** The provider's issuer, exactly as its ID tokens say: `https://sso.acme.com/realms/acme`. */\n issuer: string;\n /**\n * Where the issuer fetches the provider's configuration, when it reaches\n * the provider by another name than browsers do. Default\n * `<issuer>/.well-known/openid-configuration`.\n */\n discoveryUrl?: string;\n clientId: string;\n clientSecret: string;\n /** How the issuer authenticates at the provider's token endpoint. Default `client_secret_basic`. */\n tokenAuth?: 'client_secret_basic' | 'client_secret_post';\n };\n /** Domains a person's verified address may be at. Default the issuer's domain. */\n emailDomains?: string[];\n}\n\nexport const MIN_SECRET = 32;\nexport const FLOW_COOKIE = 'pidgeon_issuer_flow';\nexport const CODE_SECONDS = 60;\nexport const FLOW_SECONDS = 600;\n/** How far a provider's clock may be from ours. */\nconst SKEW = 60;\nconst UPSTREAM_ALGS = ['RS256', 'ES256', 'EdDSA'];\n\nexport function checkSecret(secret: string | undefined): string {\n if (!secret || secret.length < MIN_SECRET) {\n throw new Error(\n `A person's sign-in needs PIDGEON_ISSUER_SECRET, ${MIN_SECRET} characters or more. It seals the sign-in in progress and the code; there is no default.`,\n );\n }\n return secret;\n}\n\n// --- Sealing --------------------------------------------------------------------------\n\nconst b64url = (bytes: Uint8Array | Buffer | string) => Buffer.from(bytes).toString('base64url');\n\nfunction sealKey(secret: string, purpose: string): Buffer {\n return createHash('sha256').update(`pidgeon issuer seal\\0${purpose}\\0${secret}`).digest();\n}\n\n/** AES-256-GCM, a key per purpose, so a cookie is never accepted as a code. */\nexport function seal(secret: string, purpose: string, value: unknown): string {\n const iv = randomBytes(12);\n const cipher = createCipheriv('aes-256-gcm', sealKey(secret, purpose), iv);\n cipher.setAAD(Buffer.from(purpose));\n const body = Buffer.concat([cipher.update(JSON.stringify(value), 'utf8'), cipher.final()]);\n return b64url(Buffer.concat([iv, body, cipher.getAuthTag()]));\n}\n\nexport function unseal<T>(\n secret: string,\n purpose: string,\n token: string | null | undefined,\n): T | null {\n if (!token) return null;\n try {\n const raw = Buffer.from(token, 'base64url');\n if (raw.length < 29) return null;\n const decipher = createDecipheriv('aes-256-gcm', sealKey(secret, purpose), raw.subarray(0, 12));\n decipher.setAAD(Buffer.from(purpose));\n decipher.setAuthTag(raw.subarray(raw.length - 16));\n const text = Buffer.concat([\n decipher.update(raw.subarray(12, raw.length - 16)),\n decipher.final(),\n ]).toString('utf8');\n return JSON.parse(text) as T;\n } catch {\n return null;\n }\n}\n\nexport function pkceChallenge(verifier: string): string {\n return b64url(createHash('sha256').update(verifier).digest());\n}\n\nexport function pkceHolds(verifier: string, challenge: string): boolean {\n const a = Buffer.from(pkceChallenge(verifier));\n const b = Buffer.from(challenge);\n return a.length === b.length && timingSafeEqual(a, b);\n}\n\nexport function cookieOf(request: Request, name: string): string | null {\n for (const part of (request.headers.get('cookie') ?? '').split(';')) {\n const eq = part.indexOf('=');\n if (eq > 0 && part.slice(0, eq).trim() === name) {\n return decodeURIComponent(part.slice(eq + 1).trim());\n }\n }\n return null;\n}\n\n// --- The provider ---------------------------------------------------------------------\n\ninterface ProviderConfiguration {\n issuer: string;\n authorization_endpoint: string;\n token_endpoint: string;\n jwks_uri: string;\n}\n\n/** What the issuer takes from the provider's ID token. */\nexport interface ProviderPerson {\n sub: string;\n email: string;\n authTime: number;\n}\n\nexport class ProviderRefused extends Error {}\n\n/**\n * The provider, as a relying party sees it: its configuration, its keys,\n * and its ID token checked (OpenID Connect Core §3.1.3.7): from that\n * issuer, for this client, current, with the nonce this sign-in sent,\n * signed by a key in its JWKS, with a verified address.\n */\nexport function provider(options: PersonOptions['oidc'], fetcher: typeof fetch, now: () => number) {\n const issuer = options.issuer.replace(/\\/$/, '');\n let configuration: { at: number; value: Promise<ProviderConfiguration> } | null = null;\n let keys: { at: number; value: JsonWebKey[] } | null = null;\n\n function discover(): Promise<ProviderConfiguration> {\n if (!configuration || configuration.at <= now() - 3_600_000) {\n const url = options.discoveryUrl ?? `${issuer}/.well-known/openid-configuration`;\n const value = (async () => {\n const response = await fetcher(url, { headers: { accept: 'application/json' } });\n if (!response.ok) throw new Error(`${url} answered ${response.status}.`);\n const body = (await response.json()) as ProviderConfiguration;\n if (body.issuer?.replace(/\\/$/, '') !== issuer) {\n throw new Error(`${url} names the issuer ${body.issuer}, not ${issuer}.`);\n }\n return body;\n })();\n configuration = { at: now(), value };\n value.catch(() => {\n if (configuration?.value === value) configuration = null;\n });\n }\n return configuration.value;\n }\n\n async function key(kid: string | undefined): Promise<JsonWebKey | null> {\n const find = () =>\n keys?.value.find((one) => (kid ? one.kid === kid : true) && one.use !== 'enc') ?? null;\n const fresh = keys && keys.at > now() - 300_000;\n if (fresh && find()) return find();\n // Refetched once for a `kid` it has not seen: the provider rotated.\n if (keys && keys.at > now() - 10_000) return null;\n const response = await fetcher((await discover()).jwks_uri);\n const body = (await response.json().catch(() => ({}))) as { keys?: JsonWebKey[] };\n keys = { at: now(), value: Array.isArray(body.keys) ? body.keys : [] };\n return find();\n }\n\n async function authorizeUrl(input: {\n redirectUri: string;\n state: string;\n nonce: string;\n verifier: string;\n }): Promise<string> {\n const url = new URL((await discover()).authorization_endpoint);\n url.search = new URLSearchParams({\n response_type: 'code',\n client_id: options.clientId,\n redirect_uri: input.redirectUri,\n scope: 'openid email',\n state: input.state,\n nonce: input.nonce,\n code_challenge: pkceChallenge(input.verifier),\n code_challenge_method: 'S256',\n }).toString();\n return url.toString();\n }\n\n async function redeem(input: {\n code: string;\n redirectUri: string;\n verifier: string;\n nonce: string;\n }): Promise<ProviderPerson> {\n const form = new URLSearchParams({\n grant_type: 'authorization_code',\n code: input.code,\n redirect_uri: input.redirectUri,\n code_verifier: input.verifier,\n });\n const headers: Record<string, string> = {\n 'content-type': 'application/x-www-form-urlencoded',\n accept: 'application/json',\n };\n if (options.tokenAuth === 'client_secret_post') {\n form.set('client_id', options.clientId);\n form.set('client_secret', options.clientSecret);\n } else {\n // RFC 6749 §2.3.1: each form-encoded, then joined.\n const pair = `${encodeURIComponent(options.clientId)}:${encodeURIComponent(options.clientSecret)}`;\n headers.authorization = `Basic ${Buffer.from(pair).toString('base64')}`;\n }\n const response = await fetcher((await discover()).token_endpoint, {\n method: 'POST',\n headers,\n body: form,\n });\n const body = (await response.json().catch(() => ({}))) as {\n id_token?: string;\n error?: string;\n };\n if (!response.ok || typeof body.id_token !== 'string') {\n throw new ProviderRefused(\n `The identity provider did not sign the person in (${body.error ?? response.status}).`,\n );\n }\n return check(body.id_token, input.nonce);\n }\n\n async function check(token: string, nonce: string): Promise<ProviderPerson> {\n const parts = token.split('.');\n if (parts.length !== 3) throw new ProviderRefused('The provider sent no ID token.');\n let header: { alg?: string; kid?: string };\n let claims: Record<string, unknown>;\n try {\n header = JSON.parse(Buffer.from(parts[0]!, 'base64url').toString('utf8'));\n claims = JSON.parse(Buffer.from(parts[1]!, 'base64url').toString('utf8'));\n } catch {\n throw new ProviderRefused('The provider sent no ID token.');\n }\n if (!header.alg || !UPSTREAM_ALGS.includes(header.alg)) {\n throw new ProviderRefused(`The provider's ID token is signed with ${header.alg}.`);\n }\n const jwk = await key(header.kid);\n if (!jwk || !signatureHolds(header.alg, jwk, `${parts[0]}.${parts[1]}`, parts[2]!)) {\n throw new ProviderRefused(\"The provider's ID token is not signed by its keys.\");\n }\n\n const at = Math.floor(now() / 1000);\n if (typeof claims.iss !== 'string' || claims.iss.replace(/\\/$/, '') !== issuer) {\n throw new ProviderRefused(\"The provider's ID token is from another issuer.\");\n }\n const aud = claims.aud;\n const audiences = Array.isArray(aud) ? aud : [aud];\n if (!audiences.includes(options.clientId)) {\n throw new ProviderRefused(\"The provider's ID token is for another client.\");\n }\n if (audiences.length > 1 && claims.azp !== options.clientId) {\n throw new ProviderRefused(\"The provider's ID token is for another client.\");\n }\n if (typeof claims.exp !== 'number' || claims.exp + SKEW <= at) {\n throw new ProviderRefused(\"The provider's ID token has expired.\");\n }\n if (typeof claims.iat === 'number' && claims.iat > at + SKEW) {\n throw new ProviderRefused(\"The provider's ID token is from the future.\");\n }\n if (claims.nonce !== nonce) {\n throw new ProviderRefused(\"The provider's ID token is for another sign-in.\");\n }\n if (typeof claims.sub !== 'string' || !claims.sub) {\n throw new ProviderRefused(\"The provider's ID token names nobody.\");\n }\n if (claims.email_verified !== true || typeof claims.email !== 'string') {\n throw new ProviderRefused('The identity provider has not verified this person’s address.');\n }\n return {\n sub: claims.sub,\n email: claims.email.trim().toLowerCase(),\n authTime: typeof claims.auth_time === 'number' ? claims.auth_time : at,\n };\n }\n\n return { authorizeUrl, redeem };\n}\n\nfunction signatureHolds(alg: string, jwk: JsonWebKey, input: string, signature: string): boolean {\n try {\n const key = createPublicKey({ key: jwk, format: 'jwk' });\n const data = Buffer.from(input);\n const sig = Buffer.from(signature, 'base64url');\n if (alg === 'EdDSA') return jwk.kty === 'OKP' && verify(null, data, key, sig);\n if (alg === 'ES256') {\n return (\n jwk.kty === 'EC' &&\n jwk.crv === 'P-256' &&\n verify('sha256', data, { key, dsaEncoding: 'ieee-p1363' }, sig)\n );\n }\n return jwk.kty === 'RSA' && verify('sha256', data, key, sig);\n } catch {\n return false;\n }\n}\n","import { readFile } from 'node:fs/promises';\n\nimport { identityFromSeed } from '@pidgeon-ai/id';\n\n/**\n * The issuer's signing key, behind one interface so custody never touches\n * the protocol: a file, AWS KMS (`kms.ts`), or an HSM over PKCS#11\n * implementing the same three members, and nothing else changes.\n *\n * Everything the issuer signs is a JWS signing input (a card, an ID token,\n * a grant), a few hundred bytes, so a KMS that signs pure Ed25519 only up to\n * 4 KB (AWS's limit) is enough here. Agents sign their own mail and requests\n * with their own keys; the issuer never does.\n */\nexport interface Signer {\n /** The key's RFC 8037 JWK thumbprint: its `kid` in the policy, the JWKS and every JWS. */\n readonly kid: string;\n /** 32 bytes. */\n readonly publicKey: Uint8Array;\n /** Ed25519 over exactly these bytes. */\n sign(message: Uint8Array): Promise<Uint8Array>;\n}\n\n/** A key the issuer no longer signs with but still publishes, until `notAfter`. */\nexport interface RetiredKey {\n kid: string;\n publicKey: Uint8Array;\n notAfter: Date;\n}\n\n/**\n * The key file `pidgeon-issuer keygen` writes, which is the same format as\n * `pidgeon id init`'s: `{v: 1, domain, kid, seed}`, the seed base64url.\n * Mount it as a secret, mode 0600; it is read once at start.\n */\nexport async function fileSigner(path: string): Promise<Signer> {\n let file: { v?: number; domain?: string; kid?: string; seed?: string };\n try {\n file = JSON.parse(await readFile(path, 'utf8'));\n } catch {\n throw new Error(`No key at ${path}. Make one with \\`pidgeon-issuer keygen <domain>\\`.`);\n }\n if (file.v !== 1 || typeof file.seed !== 'string') {\n throw new Error(`${path} is not a Pidgeon key file.`);\n }\n return seedSigner(file.seed, { domain: file.domain ?? 'issuer', expectKid: file.kid, path });\n}\n\n/** A key from its seed, base64url: `PIDGEON_ISSUER_KEY` in the environment. */\nexport function seedSigner(\n seed: string,\n options: { domain?: string; expectKid?: string; path?: string } = {},\n): Signer {\n const identity = identityFromSeed({\n domain: options.domain ?? 'issuer',\n seed: new Uint8Array(Buffer.from(seed, 'base64url')),\n });\n if (identity.seed.length !== 32) throw new Error('An Ed25519 seed is 32 bytes.');\n if (options.expectKid && options.expectKid !== identity.kid) {\n throw new Error(`${options.path ?? 'The key'} is damaged: its key does not match its kid.`);\n }\n return {\n kid: identity.kid,\n publicKey: identity.publicKey,\n sign: async (message) => identity.sign(message),\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\n\nimport { cachedDirectory, staticDirectory, type Directory, type DirectoryAgent } from './directory';\nimport { auth0Directory } from './auth0';\nimport { keycloakDirectory } from './keycloak';\nimport { oktaDirectory } from './okta';\nimport type { GrantRule, IssuerOptions, StaticClient } from './issuer';\nimport { kmsRetiredKey, kmsSigner } from './kms';\nimport { checkSecret } from './person';\nimport { fileSigner, seedSigner, type RetiredKey } from './signer';\n\n/**\n * `issuer.json`, the one file a company writes (`issuer.example.json`).\n * Secrets never go in it: the key is a file it names (mounted as a secret)\n * or `PIDGEON_ISSUER_KEY`, and a connector's credential comes from the\n * environment variable the connector names.\n */\nexport interface IssuerFile {\n domain: string;\n issuer?: string;\n organisation?: string;\n /**\n * The key file, relative to this file, or a key in AWS KMS (`{ \"kms\":\n * \"arn:aws:kms:…\" }`, an `ECC_NIST_EDWARDS25519` key). `PIDGEON_ISSUER_KEY`\n * (the seed) wins when set.\n */\n key?: KeyRef;\n /** Keys being withdrawn: published until `not_after`. */\n retired?: { key: KeyRef; not_after: string }[];\n directory:\n | { static: DirectoryAgent[] }\n | {\n keycloak: {\n url: string;\n realm: string;\n /** The issuer's own client in that realm. */\n client_id: string;\n /** The environment variable holding its secret. Default `KEYCLOAK_CLIENT_SECRET`. */\n client_secret_env?: string;\n /** The group whose members are agents. Default `agents`. */\n group?: string;\n };\n }\n | {\n auth0: {\n /** The tenant's domain: `acme.eu.auth0.com`. */\n tenant: string;\n /** The issuer's own machine-to-machine application, with `read:clients` only. */\n client_id: string;\n /** The environment variable holding its secret. Default `AUTH0_CLIENT_SECRET`. */\n client_secret_env?: string;\n };\n }\n | {\n okta: {\n /** The org: `https://acme.okta.com`. */\n org: string;\n /** The issuer's own service app, with `okta.apps.read` and a read-only admin role. */\n client_id: string;\n /** The environment variable holding its RSA or P-256 private key, PEM. Default `OKTA_PRIVATE_KEY`. */\n private_key_env?: string;\n /** That key's `kid` in the app's JWKS. */\n key_id?: string;\n };\n };\n /**\n * A person's sign-in, through the company's OpenID Connect provider, with\n * the issuer as one of its clients. Needs `PIDGEON_ISSUER_SECRET`.\n */\n person?: {\n oidc: {\n /** The provider's issuer, as its ID tokens say. */\n issuer: string;\n /** Where the issuer reaches the provider's configuration, when not at its issuer URL. */\n discovery_url?: string;\n client_id: string;\n /** The environment variable holding its secret. Default `PIDGEON_PERSON_CLIENT_SECRET`. */\n client_secret_env?: string;\n token_auth?: 'client_secret_basic' | 'client_secret_post';\n };\n /** Default the domain. */\n email_domains?: string[];\n };\n grants?: GrantRule[];\n clients?: StaticClient[];\n client_metadata_hosts?: string[];\n /** How long the list of agents is held for the public reads, in seconds. Default 60. */\n directory_cache_seconds?: number;\n}\n\n/** A key file's path, or a KMS key: its ARN, id or alias, and its region when not the default. */\nexport type KeyRef = string | { kms: string; region?: string };\n\nexport async function loadConfig(\n path: string,\n env: Record<string, string | undefined> = process.env,\n): Promise<IssuerOptions> {\n let file: IssuerFile;\n try {\n file = JSON.parse(await readFile(path, 'utf8'));\n } catch (error) {\n throw new Error(`Could not read ${path}: ${error instanceof Error ? error.message : error}`);\n }\n if (typeof file.domain !== 'string' || !file.domain.includes('.')) {\n throw new Error(`${path}: \\`domain\\` is the domain whose agents this issues for.`);\n }\n const here = (relative: string) => resolve(dirname(path), relative);\n\n const signer = env.PIDGEON_ISSUER_KEY\n ? seedSigner(env.PIDGEON_ISSUER_KEY, { domain: file.domain })\n : typeof file.key === 'string'\n ? await fileSigner(here(file.key))\n : file.key?.kms\n ? await kmsSigner({ keyId: file.key.kms, region: file.key.region })\n : null;\n if (!signer) {\n throw new Error(`${path}: name a \\`key\\` file or a KMS key, or set PIDGEON_ISSUER_KEY.`);\n }\n\n const retired: RetiredKey[] = [];\n for (const entry of file.retired ?? []) {\n const notAfter = new Date(entry.not_after);\n if (typeof entry.key === 'string') {\n const old = await fileSigner(here(entry.key));\n retired.push({ kid: old.kid, publicKey: old.publicKey, notAfter });\n } else {\n retired.push(\n await kmsRetiredKey({ keyId: entry.key.kms, region: entry.key.region, notAfter }),\n );\n }\n }\n\n let person: IssuerOptions['person'];\n if (file.person) {\n const { oidc } = file.person;\n const secretName = oidc?.client_secret_env ?? 'PIDGEON_PERSON_CLIENT_SECRET';\n if (!oidc?.issuer || !oidc.client_id) {\n throw new Error(\n `${path}: \\`person.oidc\\` names the provider's \\`issuer\\` and the \\`client_id\\`.`,\n );\n }\n const clientSecret = env[secretName];\n if (!clientSecret) {\n throw new Error(`${path}: set ${secretName}, the issuer's client secret at ${oidc.issuer}.`);\n }\n person = {\n secret: checkSecret(env.PIDGEON_ISSUER_SECRET),\n oidc: {\n issuer: oidc.issuer,\n discoveryUrl: oidc.discovery_url,\n clientId: oidc.client_id,\n clientSecret,\n tokenAuth: oidc.token_auth,\n },\n emailDomains: file.person.email_domains,\n };\n }\n\n return {\n domain: file.domain,\n person,\n issuer: file.issuer,\n organisation: file.organisation,\n signer,\n retired,\n directory: cachedDirectory(directoryFrom(file, path, env), file.directory_cache_seconds ?? 60),\n grants: file.grants,\n clients: file.clients,\n clientMetadataHosts: file.client_metadata_hosts,\n };\n}\n\nfunction directoryFrom(\n file: IssuerFile,\n path: string,\n env: Record<string, string | undefined>,\n): Directory {\n const directory = file.directory ?? {};\n if ('keycloak' in directory) {\n const { keycloak } = directory;\n const secretName = keycloak.client_secret_env ?? 'KEYCLOAK_CLIENT_SECRET';\n const secret = env[secretName];\n if (!secret)\n throw new Error(`${path}: set ${secretName}, the issuer's Keycloak client secret.`);\n return keycloakDirectory({\n url: keycloak.url,\n realm: keycloak.realm,\n clientId: keycloak.client_id,\n clientSecret: secret,\n domain: file.domain,\n group: keycloak.group,\n });\n }\n if ('auth0' in directory) {\n const { auth0 } = directory;\n const secretName = auth0.client_secret_env ?? 'AUTH0_CLIENT_SECRET';\n const secret = env[secretName];\n if (!secret) throw new Error(`${path}: set ${secretName}, the issuer's Auth0 client secret.`);\n return auth0Directory({\n tenant: auth0.tenant,\n clientId: auth0.client_id,\n clientSecret: secret,\n domain: file.domain,\n });\n }\n if ('okta' in directory) {\n const { okta } = directory;\n const keyName = okta.private_key_env ?? 'OKTA_PRIVATE_KEY';\n const privateKey = env[keyName];\n if (!privateKey)\n throw new Error(`${path}: set ${keyName}, the issuer's Okta private key (PEM).`);\n return oktaDirectory({\n org: okta.org,\n clientId: okta.client_id,\n privateKey,\n keyId: okta.key_id,\n domain: file.domain,\n });\n }\n if ('static' in directory && Array.isArray(directory.static)) {\n for (const agent of directory.static) {\n if (!agent.address?.toLowerCase().endsWith(`@${file.domain.toLowerCase()}`)) {\n throw new Error(`${path}: ${agent.address} is not an address at ${file.domain}.`);\n }\n }\n return staticDirectory(directory.static);\n }\n throw new Error(\n `${path}: \\`directory\\` is { \"keycloak\": {...} }, { \"auth0\": {...} }, { \"okta\": {...} } or { \"static\": [...] }.`,\n );\n}\n","import { createHash, createPublicKey, randomBytes, randomUUID, verify } from 'node:crypto';\n\nimport { jwkThumbprint, verifyRequest } from '@pidgeon-ai/id';\n\nimport type { Directory, DirectoryAgent } from './directory';\nimport {\n checkSecret,\n CODE_SECONDS,\n cookieOf,\n FLOW_COOKIE,\n FLOW_SECONDS,\n pkceHolds,\n provider,\n ProviderRefused,\n seal,\n unseal,\n type PersonOptions,\n} from './person';\nimport type { RetiredKey, Signer } from './signer';\n\n/**\n * A Post issuer a company runs itself (#568): its own domain signs its\n * agents' cards, ID tokens and grants, with a key that never leaves its\n * network, for the agents its identity provider says it has.\n *\n * **The same wire protocol as Pidgeon Cloud's issuer**, so the libraries\n * work against it unchanged: the policy and the card at `post.<domain>`\n * (the draft's §discovery and §card), the token exchange an agent signs\n * (RFC 8693, Web Bot Auth's profile) and the ID token a site checks\n * (`@pidgeon-ai/sign-in`), grants (§grants), and a person's sign-in, the\n * authorization code flow with PKCE, through the company's own identity\n * provider (`person.ts`). The formats are the app's own\n * (`src/lib/post/card.ts`, `grant.ts`, `pidgeon-sign-in.ts`), written out\n * here because a package cannot import the app; `tests/unit/issuer.test.ts`\n * holds them equal by reading what this signs with the app's own readers.\n *\n * **No database.** Who the agents are is the directory's; a signature is\n * used once through `replay`, in memory unless a shared store is passed.\n * Run one replica, or pass one.\n *\n * Left out on purpose: userinfo, introspection and\n * revocation (each needs a store; an ID token lives five minutes and\n * revoking an agent is disabling it in the identity provider), dynamic\n * client registration, and the card log.\n */\n\nexport const TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange';\nexport const TOKEN_TYPE_JWT = 'urn:ietf:params:oauth:token-type:jwt';\nexport const TOKEN_TYPE_ID = 'urn:ietf:params:oauth:token-type:id_token';\nexport const TOKEN_TYPE_ACCESS = 'urn:ietf:params:oauth:token-type:access_token';\n\n/** Where each thing answers under the issuer. The token and JWKS paths are Pidgeon Cloud's. */\nexport const PATHS = {\n configuration: '/.well-known/openid-configuration',\n policy: '/.well-known/post.json',\n card: '/.well-known/post/card',\n directory: '/.well-known/http-message-signatures-directory',\n token: '/api/post/oidc/token',\n authorize: '/api/post/oidc/authorize',\n /** The issuer's own: where the company's identity provider sends a person back. Cloud has none. */\n callback: '/api/post/oidc/callback',\n jwks: '/api/post/oidc/jwks',\n grants: '/api/post/grants',\n} as const;\n\nconst POLICY_MAX_AGE = 86_400;\nconst CARD_SECONDS = 86_400;\nconst ID_TOKEN_SECONDS = 300;\nconst NEW_ADDRESS_DAYS = 30;\n/** The longest an exchange's signature may have been made before it arrives. */\nconst EXCHANGE_SIGNATURE_SECONDS = 600;\nconst EXCHANGE_COMPONENTS = ['@method', '@authority', '@path', 'from', 'content-digest'];\nconst GRANT_HEADER = 'post-grant';\n\nexport interface GrantRule {\n /** The directory group or role that carries this grant. */\n group: string;\n scope: { name: string; label: string; limit?: { amount: number; currency: string } };\n /** The domain the agent may act with. Absent: anywhere. */\n audience?: string;\n subject: { type: 'customer' | 'account' | 'order'; id: string };\n /** How long each signed copy lasts. Default 30. */\n days?: number;\n}\n\n/**\n * A site, registered by hand: its `client_id`, the host its grants must be\n * for, and where a person's sign-in may return to, each matched exactly.\n */\nexport interface StaticClient {\n client_id: string;\n host: string;\n redirect_uris?: string[];\n}\n\n/** Remembers a signature's `keyid nonce` until it expires; false when it was used. */\nexport interface ReplayStore {\n use(key: string, expiresAt: number): boolean | Promise<boolean>;\n}\n\nexport interface IssuerOptions {\n /** The domain whose agents this issues for: `acme.com`. */\n domain: string;\n /** Default `https://post.<domain>`. */\n issuer?: string;\n signer: Signer;\n /** Keys being withdrawn: published until their `notAfter`, so copies they signed still check. */\n retired?: RetiredKey[];\n directory: Directory;\n /** The card's `on_behalf_of`: who the agents work for. Default the domain. */\n organisation?: string;\n grants?: GrantRule[];\n clients?: StaticClient[];\n /**\n * Hosts whose Client ID Metadata Documents may be fetched, for a site\n * whose `client_id` is a URL. Default none: the token endpoint runs\n * inside the network, and an `audience` the caller chooses must never\n * make it fetch an arbitrary URL.\n */\n clientMetadataHosts?: string[];\n /** A person's sign-in, through the company's identity provider. Absent: agents only. */\n person?: PersonOptions;\n replay?: ReplayStore;\n fetch?: typeof fetch;\n /** Milliseconds since the epoch, for tests. */\n now?: () => number;\n}\n\nexport interface Issuer {\n readonly issuer: string;\n readonly domain: string;\n /** Answers a request to the issuer, or null when the path is not one of its. */\n handle(request: Request): Promise<Response | null>;\n /** The `_post` TXT record for `_post.<domain>`. */\n record(): string;\n /** Every public document, by path, as `pidgeon-issuer export` writes them. */\n documents(): Promise<Record<string, string>>;\n /** An agent's card, signed now, or null when the directory has no such live agent. */\n card(address: string): Promise<{ jws: string; card: Record<string, unknown> } | null>;\n /** The grants an agent holds now, signed. */\n grantsFor(agent: DirectoryAgent): Promise<{ id: string; jws: string }[]>;\n}\n\nconst b64url = (bytes: Uint8Array | Buffer | string) => Buffer.from(bytes).toString('base64url');\nconst encode = (value: unknown) => b64url(JSON.stringify(value));\nconst iso = (ms: number) => new Date(ms).toISOString().replace(/\\.\\d{3}Z$/, 'Z');\n\n/** An in-memory `ReplayStore`. */\nexport function memoryReplayStore(now: () => number = () => Date.now()): ReplayStore {\n const seen = new Map<string, number>();\n return {\n use(key, expiresAt) {\n const at = Math.floor(now() / 1000);\n for (const [held, until] of seen) if (until < at) seen.delete(held);\n if (seen.has(key)) return false;\n seen.set(key, expiresAt);\n return true;\n },\n };\n}\n\n/** A JWS this issuer signed, read back: only the claims the checks look at. */\ninterface Signed {\n iss?: unknown;\n sub?: unknown;\n jti?: unknown;\n exp?: unknown;\n address?: unknown;\n agent?: unknown;\n keys?: unknown;\n aud?: unknown;\n scope?: unknown;\n subject?: unknown;\n}\n\nclass Refused extends Error {\n constructor(\n readonly code: string,\n message: string,\n readonly status = 400,\n ) {\n super(message);\n }\n}\n\nexport function createIssuer(options: IssuerOptions): Issuer {\n const domain = options.domain.toLowerCase();\n const issuer = (options.issuer ?? `https://post.${domain}`).replace(/\\/$/, '');\n const now = options.now ?? (() => Date.now());\n const fetcher = options.fetch ?? fetch;\n const replay = options.replay ?? memoryReplayStore(now);\n const organisation = options.organisation ?? domain;\n const nowSeconds = () => Math.floor(now() / 1000);\n const person = options.person\n ? { ...options.person, secret: checkSecret(options.person.secret) }\n : null;\n const upstream = person ? provider(person.oidc, fetcher, now) : null;\n\n // --- Signing ----------------------------------------------------------------------\n\n async function jws(header: Record<string, unknown>, payload: unknown): Promise<string> {\n const input = `${encode({ ...header, kid: options.signer.kid })}.${encode(payload)}`;\n const signature = await options.signer.sign(new TextEncoder().encode(input));\n return `${input}.${b64url(signature)}`;\n }\n\n /** Ours: signed by the current key or one still published, and readable. */\n function readOurs(token: string, typ: string): Signed | null {\n const parts = token.replace(/\\s+/g, '').split('.');\n if (parts.length !== 3) return null;\n try {\n const header = JSON.parse(Buffer.from(parts[0]!, 'base64url').toString('utf8'));\n if (header?.alg !== 'EdDSA' || header?.typ !== typ) return null;\n const key = publishedIssuerKeys().find((candidate) => candidate.kid === header.kid);\n if (!key) return null;\n const signed = verify(\n null,\n Buffer.from(`${parts[0]}.${parts[1]}`),\n createPublicKey({\n key: { kty: 'OKP', crv: 'Ed25519', x: b64url(key.publicKey) },\n format: 'jwk',\n }),\n Buffer.from(parts[2]!, 'base64url'),\n );\n return signed ? JSON.parse(Buffer.from(parts[1]!, 'base64url').toString('utf8')) : null;\n } catch {\n return null;\n }\n }\n\n function publishedIssuerKeys(): { kid: string; publicKey: Uint8Array; notAfter: number }[] {\n const current = {\n kid: options.signer.kid,\n publicKey: options.signer.publicKey,\n // The current key is published a year ahead, renewed on every read.\n notAfter: now() + 365 * 86_400_000,\n };\n const retired = (options.retired ?? [])\n .filter((key) => key.notAfter.getTime() > now())\n .map((key) => ({ ...key, notAfter: key.notAfter.getTime() }));\n return [current, ...retired];\n }\n\n // --- The public documents --------------------------------------------------------\n\n async function policy(): Promise<string> {\n const agents = await options.directory.agents();\n // An agent's key stays for two policy lifetimes past the read, so a copy\n // fetched just before the agent was removed still lists it no longer.\n const agentNotAfter = iso(now() + 2 * POLICY_MAX_AGE * 1000);\n const keys = [\n ...publishedIssuerKeys().map((key) => ({\n kid: key.kid,\n alg: 'Ed25519',\n pub: b64url(key.publicKey),\n not_after: iso(key.notAfter),\n })),\n ...unique(agents.map((agent) => agent.key)).map((x) => ({\n kid: jwkThumbprint(new Uint8Array(Buffer.from(x, 'base64url'))),\n alg: 'Ed25519',\n pub: x,\n not_after: agentNotAfter,\n })),\n ];\n return (\n JSON.stringify(\n {\n v: 'post0',\n max_age: POLICY_MAX_AGE,\n keys,\n first_contact: { accept: ['known'] },\n identity: { issuer },\n features: [],\n },\n null,\n 2,\n ) + '\\n'\n );\n }\n\n /** Web Bot Auth's key directory: the agents' keys, which their `Signature-Agent` points at. */\n async function keyDirectory(): Promise<string> {\n const agents = await options.directory.agents();\n return JSON.stringify({\n keys: unique(agents.map((agent) => agent.key)).map((x) => ({\n kty: 'OKP',\n crv: 'Ed25519',\n kid: jwkThumbprint(new Uint8Array(Buffer.from(x, 'base64url'))),\n x,\n use: 'sig',\n })),\n });\n }\n\n function jwks() {\n return {\n keys: publishedIssuerKeys().map((key) => ({\n kty: 'OKP',\n crv: 'Ed25519',\n x: b64url(key.publicKey),\n kid: key.kid,\n alg: 'EdDSA',\n use: 'sig',\n })),\n };\n }\n\n function configuration() {\n return {\n issuer,\n token_endpoint: `${issuer}${PATHS.token}`,\n jwks_uri: `${issuer}${PATHS.jwks}`,\n ...(person\n ? {\n authorization_endpoint: `${issuer}${PATHS.authorize}`,\n grant_types_supported: ['authorization_code', TOKEN_EXCHANGE],\n response_types_supported: ['code'],\n code_challenge_methods_supported: ['S256'],\n scopes_supported: ['openid', 'email'],\n }\n : {\n grant_types_supported: [TOKEN_EXCHANGE],\n // No person signs in here: there is no authorization endpoint.\n response_types_supported: [],\n }),\n subject_types_supported: ['public'],\n id_token_signing_alg_values_supported: ['EdDSA'],\n token_endpoint_auth_methods_supported: ['none'],\n claims_supported: [\n 'iss',\n 'sub',\n 'aud',\n 'exp',\n 'iat',\n 'auth_time',\n 'jti',\n 'email',\n 'email_verified',\n 'on_behalf_of',\n 'kind',\n 'operator',\n 'standing',\n 'card',\n 'grant',\n 'grants',\n 'nonce',\n 'cnf',\n 'act',\n 'sub_type',\n ],\n client_id_metadata_document_supported: (options.clientMetadataHosts ?? []).length > 0,\n };\n }\n\n function record(): string {\n // Written once: a new agent's key is found by the verifier's unknown-`kid` refetch.\n const id = createHash('sha256')\n .update(`post policy id\\0self-hosted\\0${domain}`)\n .digest('hex')\n .slice(0, 16);\n return `v=post0; id=${id}`;\n }\n\n // --- Cards ------------------------------------------------------------------------\n\n const cardUrl = (address: string) =>\n `${issuer}${PATHS.card}?address=${encodeURIComponent(address)}`;\n\n /** `src/lib/post/card.ts`'s claims, in `CARD_CLAIMS`' order. */\n function cardClaims(agent: DirectoryAgent) {\n const iat = nowSeconds();\n const created = Date.parse(agent.createdAt);\n const fresh = now() - created < NEW_ADDRESS_DAYS * 86_400_000;\n return {\n iss: issuer,\n sub: agent.sub,\n iat,\n exp: iat + CARD_SECONDS,\n v: 'post0',\n address: agent.address,\n kind: agent.kind,\n on_behalf_of: organisation,\n operator: { domain, verified: true },\n created_at: iso(created),\n keys: [\n {\n type: 'post',\n domain,\n kid: jwkThumbprint(new Uint8Array(Buffer.from(agent.key, 'base64url'))),\n },\n ],\n reputation: { standing: fresh ? 'new' : 'established', since: iso(created).slice(0, 7) },\n url: cardUrl(agent.address),\n };\n }\n\n async function card(address: string) {\n const wanted = address.trim().toLowerCase();\n const agent = (await options.directory.agents()).find((one) => one.address === wanted);\n if (!agent) return null;\n const claims = cardClaims(agent);\n return { jws: await jws({ alg: 'EdDSA', typ: 'agent-card+jwt' }, claims), card: claims };\n }\n\n // --- Grants -----------------------------------------------------------------------\n\n /** Stable for an agent and a rule, so the status read can find it again. */\n const grantId = (agent: DirectoryAgent, rule: GrantRule) =>\n `grt_${createHash('sha256')\n .update(\n `${agent.sub}\\0${rule.group}\\0${rule.scope.name}\\0${rule.subject.type}:${rule.subject.id}`,\n )\n .digest('base64url')\n .slice(0, 22)}`;\n\n const rulesFor = (agent: DirectoryAgent) =>\n (options.grants ?? []).filter((rule) => agent.groups.includes(rule.group));\n\n /**\n * `src/lib/post/grant.ts`'s grant, from the organisation (the domain).\n * Signed from the start of today, so each day's copy is the same bytes.\n */\n async function grantsFor(agent: DirectoryAgent) {\n const day = Math.floor(nowSeconds() / 86_400) * 86_400;\n return Promise.all(\n rulesFor(agent).map(async (rule) => {\n const id = grantId(agent, rule);\n const grant = {\n iss: issuer,\n jti: id,\n sub: agent.sub,\n agent: agent.address,\n iat: day,\n exp: day + (rule.days ?? 30) * 86_400,\n v: 'post0',\n grantor: { type: 'organisation', domain, confirmed_by: 'domain' },\n scope: rule.scope,\n ...(rule.audience ? { aud: rule.audience } : {}),\n subject: rule.subject,\n status: `${issuer}${PATHS.grants}/${id}/status`,\n };\n return { id, jws: await jws({ alg: 'EdDSA', typ: 'agent-grant+jwt' }, grant) };\n }),\n );\n }\n\n /** Whether a grant still holds: its agent still in the directory, still in the rule's group. */\n async function grantStatus(id: string) {\n for (const agent of await options.directory.agents()) {\n for (const rule of rulesFor(agent)) {\n if (grantId(agent, rule) !== id) continue;\n const day = Math.floor(nowSeconds() / 86_400) * 86_400;\n return {\n object: 'grant_status',\n id,\n status: 'active',\n expires_at: iso((day + (rule.days ?? 30) * 86_400) * 1000),\n revoked_at: null,\n };\n }\n }\n return null;\n }\n\n // --- Sites ------------------------------------------------------------------------\n\n interface Site {\n host: string;\n redirectUris: string[];\n }\n const clientCache = new Map<string, { at: number; site: Site }>();\n\n /** The site's host, from the static list or its metadata document. */\n async function clientHost(clientId: string | null): Promise<string> {\n if (!clientId) throw new Refused('invalid_target', \"audience is the site's client_id.\");\n return (await site(clientId)).host;\n }\n\n /** A site the issuer knows: listed in the config, or by a metadata document on an allowed host. */\n async function site(clientId: string): Promise<Site> {\n const listed = options.clients?.find((client) => client.client_id === clientId);\n if (listed) {\n return { host: listed.host.toLowerCase(), redirectUris: listed.redirect_uris ?? [] };\n }\n\n let url: URL;\n try {\n url = new URL(clientId);\n } catch {\n throw new Refused('invalid_target', `${clientId} is not a site this issuer knows.`);\n }\n const allowed = (options.clientMetadataHosts ?? []).map((host) => host.toLowerCase());\n if (url.protocol !== 'https:' || !allowed.includes(url.hostname.toLowerCase())) {\n throw new Refused('invalid_target', `${clientId} is not a site this issuer knows.`);\n }\n const held = clientCache.get(clientId);\n if (held && held.at > now() - 300_000) return held.site;\n\n const response = await fetcher(clientId, {\n redirect: 'error',\n headers: { accept: 'application/json' },\n signal: AbortSignal.timeout(5000),\n }).catch(() => null);\n const text = response?.ok ? await response.text() : '';\n let document: { client_id?: unknown; redirect_uris?: unknown } = {};\n try {\n if (text.length <= 64 * 1024) document = JSON.parse(text);\n } catch {\n // Refused below.\n }\n const redirects = Array.isArray(document.redirect_uris)\n ? document.redirect_uris.filter((uri): uri is string => typeof uri === 'string')\n : [];\n if (document.client_id !== clientId || redirects.length === 0) {\n throw new Refused('invalid_target', `${clientId} does not describe a site.`);\n }\n let found: Site;\n try {\n found = { host: new URL(redirects[0]!).hostname.toLowerCase(), redirectUris: redirects };\n } catch {\n throw new Refused('invalid_target', `${clientId} does not describe a site.`);\n }\n clientCache.set(clientId, { at: now(), site: found });\n return found;\n }\n\n // --- The token exchange ------------------------------------------------------------\n\n /**\n * `services/pidgeon-sign-in.ts :: exchangeAgentToken` for a `pidgeon id`\n * agent, with the directory in place of the proved domains. In order:\n * the request signed by a key the directory gives an agent, covering what\n * it must, used once; the card ours, current, that agent's and naming that\n * key; the agent live **now** in the identity provider; the grant, when it\n * carries one, ours, that agent's, in force, for this site.\n */\n async function exchange(request: Request, body: string): Promise<Response> {\n const form = new URLSearchParams(body);\n if (form.get('grant_type') !== TOKEN_EXCHANGE) {\n throw new Refused('unsupported_grant_type', `Use ${TOKEN_EXCHANGE}.`);\n }\n const requested = form.get('requested_token_type');\n if (requested && requested !== TOKEN_TYPE_ACCESS && requested !== TOKEN_TYPE_JWT) {\n throw new Refused('invalid_request', `requested_token_type is ${TOKEN_TYPE_JWT} or absent.`);\n }\n const subjectToken = form.get('subject_token');\n if (!subjectToken || form.get('subject_token_type') !== TOKEN_TYPE_JWT) {\n throw new Refused(\n 'invalid_request',\n `subject_token is the agent's card, with subject_token_type ${TOKEN_TYPE_JWT}.`,\n );\n }\n const host = await clientHost(form.get('audience'));\n\n // 1. The signature: a key the directory gives an agent.\n const agents = await options.directory.agents();\n const headers: Record<string, string> = {};\n request.headers.forEach((value, name) => (headers[name] = value));\n const grantHeader = headers[GRANT_HEADER]?.trim() || null;\n let signer: DirectoryAgent | null = null;\n const check = await verifyRequest(\n { method: request.method, url: `${issuer}${PATHS.token}`, headers, body },\n {\n now: now(),\n key: async (keyid) => {\n signer =\n agents.find(\n (agent) =>\n jwkThumbprint(new Uint8Array(Buffer.from(agent.key, 'base64url'))) === keyid,\n ) ?? null;\n return signer ? new Uint8Array(Buffer.from(signer.key, 'base64url')) : null;\n },\n },\n );\n if (!check.ok || !signer) {\n throw new Refused(\n 'invalid_grant',\n check.ok || check.reason === 'unsigned'\n ? \"Sign the request with the agent's key (@pidgeon-ai/id's signInWithPidgeon).\"\n : `The request's signature does not hold (${check.reason}).`,\n );\n }\n const agent = signer as DirectoryAgent;\n const required = [...EXCHANGE_COMPONENTS, ...(grantHeader ? [GRANT_HEADER] : [])];\n const missing = required.find((component) => !check.components.includes(component));\n if (missing) {\n throw new Refused('invalid_grant', `The request's signature must cover ${missing}.`);\n }\n if (check.created < nowSeconds() - EXCHANGE_SIGNATURE_SECONDS) {\n throw new Refused('invalid_grant', \"The request's signature is too old. Sign a new one.\");\n }\n if (!check.nonce || check.nonce.length > 200) {\n throw new Refused('invalid_request', 'The signature needs a nonce, so it can be used once.');\n }\n if (check.from !== agent.address) {\n throw new Refused('invalid_grant', 'From must be the address of the agent whose key signed.');\n }\n\n // 2. The card: ours, current, this agent's, naming this key.\n const card = readOurs(subjectToken, 'agent-card+jwt');\n if (!card || card.iss !== issuer) {\n throw new Refused('invalid_grant', 'subject_token is not a card this issuer signed.');\n }\n if (typeof card.exp !== 'number' || card.exp <= nowSeconds()) {\n throw new Refused('invalid_grant', 'The card has expired.');\n }\n if (card.address !== agent.address || card.sub !== agent.sub) {\n throw new Refused('invalid_grant', 'The card is for another agent than the one that signed.');\n }\n if (\n !Array.isArray(card.keys) ||\n !card.keys.some(\n (key: { type?: string; domain?: string; kid?: string }) =>\n key.type === 'post' && key.domain === domain && key.kid === check.keyid,\n )\n ) {\n throw new Refused('invalid_grant', 'The card does not name the key that signed the request.');\n }\n\n // 3. Live now, asked of the identity provider itself, not the copy above.\n const live = await options.directory.agent(agent.sub);\n if (!live || live.address !== agent.address || live.key !== agent.key) {\n throw new Refused('invalid_grant', \"That card's agent is no longer live.\");\n }\n\n // 4. The grant, when it carries one.\n let grant: Record<string, unknown> | undefined;\n if (grantHeader) {\n const presented = grantHeader\n .split(',')\n .map((value) => value.trim())\n .filter(Boolean);\n if (presented.length !== 1)\n throw new Refused('invalid_request', 'Sign in with one grant at most.');\n const read = readOurs(presented[0]!, 'agent-grant+jwt');\n const reason = !read\n ? 'bad_signature'\n : read.iss !== issuer\n ? 'unknown_issuer'\n : read.sub !== live.sub || read.agent !== live.address\n ? 'wrong_agent'\n : typeof read.exp !== 'number' || read.exp <= nowSeconds()\n ? 'expired'\n : !rulesFor(live).some((rule) => grantId(live, rule) === read.jti)\n ? 'revoked'\n : read.aud && !(host === read.aud || host.endsWith(`.${read.aud}`))\n ? 'wrong_audience'\n : null;\n if (reason) throw new Refused('invalid_grant', `The grant does not hold (${reason}).`);\n grant = {\n id: read!.jti,\n scope: read!.scope,\n grantor: { type: 'organisation', domain },\n subject: read!.subject,\n audience: read!.aud ?? null,\n exp: read!.exp,\n };\n }\n\n // The replay check, last, so a refused request does not spend its nonce.\n if (\n !(await replay.use(\n `${check.keyid} ${check.nonce}`,\n nowSeconds() + EXCHANGE_SIGNATURE_SECONDS,\n ))\n ) {\n throw new Refused(\n 'invalid_grant',\n 'That signed request has already been used. Sign a new one.',\n );\n }\n\n const audience = form.get('audience')!;\n const iat = nowSeconds();\n const jti = randomUUID();\n const cnf = { jwk: { kty: 'OKP', crv: 'Ed25519', x: live.key } };\n const fresh = now() - Date.parse(live.createdAt) < NEW_ADDRESS_DAYS * 86_400_000;\n const idToken = await jws(\n { alg: 'EdDSA', typ: 'JWT' },\n {\n iss: issuer,\n aud: audience,\n iat,\n exp: iat + ID_TOKEN_SECONDS,\n auth_time: iat,\n jti,\n sub: live.sub,\n kind: live.kind,\n email: live.address,\n email_verified: true,\n on_behalf_of: organisation,\n operator: { domain, verified: true, shared: false },\n standing: fresh ? 'new' : 'established',\n card: cardUrl(live.address),\n ...(grant ? { grant } : {}),\n cnf,\n },\n );\n\n // No userinfo here, so without a delegation the ID token is the token issued (RFC 8693 §2.2.1).\n if (requested === TOKEN_TYPE_JWT) {\n if (!grant) {\n throw new Refused(\n 'invalid_request',\n `A ${TOKEN_TYPE_JWT} says whom the agent acts for, so it needs a grant in Post-Grant.`,\n );\n }\n const seconds = Math.max(1, Math.min(600, (grant.exp as number) - iat));\n const delegation = await jws(\n { alg: 'EdDSA', typ: 'JWT' },\n {\n iss: issuer,\n aud: audience,\n iat,\n exp: iat + seconds,\n jti,\n sub: domain,\n sub_type: 'organisation',\n act: { iss: issuer, sub: live.sub, email: live.address },\n scope: (grant.scope as { name: string }).name,\n grant: {\n id: grant.id,\n scope: grant.scope,\n subject: grant.subject,\n audience: grant.audience,\n exp: grant.exp,\n },\n cnf,\n },\n );\n return json({\n access_token: delegation,\n issued_token_type: TOKEN_TYPE_JWT,\n token_type: 'Bearer',\n expires_in: seconds,\n id_token: idToken,\n });\n }\n return json({\n access_token: idToken,\n issued_token_type: TOKEN_TYPE_ID,\n token_type: 'N_A',\n expires_in: ID_TOKEN_SECONDS,\n id_token: idToken,\n });\n }\n\n /** An agent's own grants: a request it signed, as itself. */\n async function listGrants(request: Request): Promise<Response> {\n const headers: Record<string, string> = {};\n request.headers.forEach((value, name) => (headers[name] = value));\n const agents = await options.directory.agents();\n let signer: DirectoryAgent | null = null;\n const check = await verifyRequest(\n { method: request.method, url: `${issuer}${new URL(request.url).pathname}`, headers },\n {\n now: now(),\n key: async (keyid) => {\n signer =\n agents.find(\n (agent) =>\n jwkThumbprint(new Uint8Array(Buffer.from(agent.key, 'base64url'))) === keyid,\n ) ?? null;\n return signer ? new Uint8Array(Buffer.from(signer.key, 'base64url')) : null;\n },\n },\n );\n const agent = signer as DirectoryAgent | null;\n if (!check.ok || !agent || check.from !== agent.address) {\n throw new Refused(\n 'invalid_request',\n \"Sign the request with the agent's key, From its address.\",\n 401,\n );\n }\n const grants = await grantsFor(agent);\n return json({ object: 'list', data: grants.map((grant) => ({ object: 'grant', ...grant })) });\n }\n\n // --- A person ---------------------------------------------------------------------\n\n interface Flow {\n site: {\n clientId: string;\n redirectUri: string;\n state: string | null;\n nonce: string | null;\n challenge: string;\n scope: string;\n };\n upstream: { state: string; nonce: string; verifier: string };\n exp: number;\n }\n\n interface Code {\n jti: string;\n clientId: string;\n redirectUri: string;\n challenge: string;\n nonce: string | null;\n scope: string;\n sub: string;\n email: string;\n authTime: number;\n exp: number;\n }\n\n const callbackUrl = `${issuer}${PATHS.callback}`;\n const random = () => b64url(randomBytes(32));\n\n function flowCookie(value: string, maxAge: number): string {\n const secure = issuer.startsWith('https:') ? '; Secure' : '';\n return `${FLOW_COOKIE}=${value}; Path=${PATHS.callback}; Max-Age=${maxAge}; HttpOnly; SameSite=Lax${secure}`;\n }\n\n /** Back to the site, once its return address is known to be its own. */\n function backToSite(\n redirectUri: string,\n state: string | null,\n values: Record<string, string>,\n headers: Record<string, string> = {},\n ): Response {\n const url = new URL(redirectUri);\n for (const [name, value] of Object.entries(values)) url.searchParams.set(name, value);\n if (state) url.searchParams.set('state', state);\n url.searchParams.set('iss', issuer);\n return new Response(null, {\n status: 302,\n headers: { location: url.toString(), 'cache-control': 'no-store', ...headers },\n });\n }\n\n /**\n * `GET /api/post/oidc/authorize`, Cloud's parameters. Nothing leaves the\n * issuer until the site is one it knows and `redirect_uri` is one of that\n * site's, compared as strings: a trailing slash, a port or a query makes\n * it another address, and the answer is a page here, never a redirect.\n */\n async function authorize(url: URL): Promise<Response> {\n const params = url.searchParams;\n for (const name of ['client_id', 'redirect_uri', 'state', 'nonce', 'code_challenge']) {\n if (params.getAll(name).length > 1) return page(`${name} is given more than once`);\n }\n const clientId = params.get('client_id');\n const redirectUri = params.get('redirect_uri');\n if (!clientId || !redirectUri) return page('client_id and redirect_uri are required');\n const known = await site(clientId).catch((error) => {\n if (error instanceof Refused) return null;\n throw error;\n });\n if (!known) return page(`${clientId} is not a site this issuer knows`);\n if (!known.redirectUris.includes(redirectUri)) {\n return page(`${redirectUri} is not where ${clientId} receives sign-ins`);\n }\n\n const state = params.get('state');\n const fail = (error: string, description: string) =>\n backToSite(redirectUri, state, { error, error_description: description });\n if (params.get('response_type') !== 'code') {\n return fail('unsupported_response_type', 'response_type is code.');\n }\n const scope = params.get('scope') ?? '';\n if (!scope.split(' ').includes('openid')) {\n return fail('invalid_scope', 'scope includes openid.');\n }\n const challenge = params.get('code_challenge');\n if (\n !challenge ||\n !/^[A-Za-z0-9_-]{43}$/.test(challenge) ||\n params.get('code_challenge_method') !== 'S256'\n ) {\n return fail('invalid_request', 'PKCE is required: code_challenge with S256.');\n }\n\n const flow: Flow = {\n site: { clientId, redirectUri, state, nonce: params.get('nonce'), challenge, scope },\n upstream: { state: random(), nonce: random(), verifier: random() },\n exp: nowSeconds() + FLOW_SECONDS,\n };\n const location = await upstream!.authorizeUrl({\n redirectUri: callbackUrl,\n state: flow.upstream.state,\n nonce: flow.upstream.nonce,\n verifier: flow.upstream.verifier,\n });\n return new Response(null, {\n status: 302,\n headers: {\n location,\n 'cache-control': 'no-store',\n 'set-cookie': flowCookie(seal(person!.secret, 'flow', flow), FLOW_SECONDS),\n },\n });\n }\n\n /**\n * `GET /api/post/oidc/callback`: the provider's answer, accepted only in\n * the browser that started this sign-in (the sealed cookie's `state`), so\n * a code for one member cannot be dropped into a colleague's browser.\n */\n async function callback(request: Request, url: URL): Promise<Response> {\n const flow = unseal<Flow>(person!.secret, 'flow', cookieOf(request, FLOW_COOKIE));\n const clear = { 'set-cookie': flowCookie('', 0) };\n if (\n !flow ||\n flow.exp <= nowSeconds() ||\n url.searchParams.get('state') !== flow.upstream.state\n ) {\n return page('this sign-in was not started in this browser. Start again from the site', clear);\n }\n const back = (values: Record<string, string>) =>\n backToSite(flow.site.redirectUri, flow.site.state, values, clear);\n const code = url.searchParams.get('code');\n if (url.searchParams.get('error') || !code) {\n return back({ error: 'access_denied', error_description: 'The person did not sign in.' });\n }\n\n let who;\n try {\n who = await upstream!.redeem({\n code,\n redirectUri: callbackUrl,\n verifier: flow.upstream.verifier,\n nonce: flow.upstream.nonce,\n });\n } catch (error) {\n if (!(error instanceof ProviderRefused)) throw error;\n return back({ error: 'access_denied', error_description: error.message });\n }\n const domains = (person!.emailDomains ?? [domain]).map((one) => one.toLowerCase());\n if (!domains.includes(who.email.slice(who.email.lastIndexOf('@') + 1))) {\n return back({\n error: 'access_denied',\n error_description: `${who.email} is not an address this issuer signs people in with.`,\n });\n }\n // An agent's address is the agent's: a person given it in the provider is not signed in as it.\n if ((await options.directory.agents()).some((agent) => agent.address === who.email)) {\n return back({\n error: 'access_denied',\n error_description: `${who.email} is an agent's address, not a person's.`,\n });\n }\n\n const sealed: Code = {\n jti: randomUUID(),\n clientId: flow.site.clientId,\n redirectUri: flow.site.redirectUri,\n challenge: flow.site.challenge,\n nonce: flow.site.nonce,\n scope: flow.site.scope,\n sub: who.sub,\n email: who.email,\n authTime: who.authTime,\n exp: nowSeconds() + CODE_SECONDS,\n };\n return back({ code: seal(person!.secret, 'code', sealed) });\n }\n\n /** `authorization_code` at the token endpoint, as Cloud's `exchangePersonCode`. */\n async function redeemCode(form: URLSearchParams): Promise<Response> {\n const verifier = form.get('code_verifier');\n const clientId = form.get('client_id');\n if (!verifier || !clientId) {\n throw new Refused('invalid_request', 'code, code_verifier and client_id are required.');\n }\n const code = unseal<Code>(person!.secret, 'code', form.get('code'));\n if (!code) throw new Refused('invalid_grant', 'That code is not valid.');\n if (code.clientId !== clientId) {\n throw new Refused('invalid_grant', 'That code was issued to a different client.');\n }\n // Spent before anything else is checked, so two requests with one code cannot both win.\n if (!(await replay.use(`code ${code.jti}`, code.exp + 60))) {\n throw new Refused('invalid_grant', 'That code has already been used.');\n }\n if (code.exp <= nowSeconds()) throw new Refused('invalid_grant', 'That code has expired.');\n const redirectUri = form.get('redirect_uri');\n if (redirectUri !== null && redirectUri !== code.redirectUri) {\n throw new Refused('invalid_grant', 'redirect_uri does not match the authorization request.');\n }\n if (!pkceHolds(verifier, code.challenge)) {\n throw new Refused('invalid_grant', 'code_verifier does not match the code_challenge.');\n }\n\n const iat = nowSeconds();\n const idToken = await jws(\n { alg: 'EdDSA', typ: 'JWT' },\n {\n iss: issuer,\n aud: clientId,\n iat,\n exp: iat + ID_TOKEN_SECONDS,\n auth_time: code.authTime,\n ...(code.nonce ? { nonce: code.nonce } : {}),\n jti: randomUUID(),\n sub: code.sub,\n kind: 'person',\n email: code.email,\n email_verified: true,\n // Grants here are the organisation's, to its agents; a person gives none at this issuer.\n grants: [],\n },\n );\n // No userinfo here, so the access token is the ID token.\n return json({\n access_token: idToken,\n token_type: 'Bearer',\n expires_in: ID_TOKEN_SECONDS,\n id_token: idToken,\n scope: code.scope,\n });\n }\n\n // --- Routes -----------------------------------------------------------------------\n\n async function handle(request: Request): Promise<Response | null> {\n const url = new URL(request.url);\n const path = url.pathname;\n const get = request.method === 'GET' || request.method === 'HEAD';\n try {\n if (get && path === PATHS.configuration) return json(configuration(), 300);\n if (get && path === PATHS.jwks) return json(jwks(), 300);\n if (get && path === PATHS.policy) {\n return text(await policy(), 'application/json', 300);\n }\n if (get && path === PATHS.directory) {\n return text(\n await keyDirectory(),\n 'application/http-message-signatures-directory+json',\n 300,\n );\n }\n if (get && path === PATHS.card) {\n const found = await card(url.searchParams.get('address') ?? '');\n if (!found)\n return json({ error: 'not_found', error_description: 'No such agent.' }, 0, 404);\n return json(\n { object: 'agent_card', url: found.card.url, jws: found.jws, card: found.card },\n 300,\n );\n }\n if (request.method === 'POST' && path === PATHS.token) {\n const body = await request.text();\n const form = new URLSearchParams(body);\n if (person && form.get('grant_type') === 'authorization_code') {\n return await redeemCode(form);\n }\n return await exchange(request, body);\n }\n if (person && get && path === PATHS.authorize) return await authorize(url);\n if (person && get && path === PATHS.callback) return await callback(request, url);\n if (get && path === PATHS.grants) return await listGrants(request);\n const status = /^\\/api\\/post\\/grants\\/(grt_[A-Za-z0-9_-]+)\\/status$/.exec(path);\n if (get && status) {\n const found = await grantStatus(status[1]!);\n return found ? json(found, 60) : json({ error: 'not_found' }, 0, 404);\n }\n return null;\n } catch (error) {\n if (error instanceof Refused) {\n return json({ error: error.code, error_description: error.message }, 0, error.status);\n }\n throw error;\n }\n }\n\n async function documents(): Promise<Record<string, string>> {\n const out: Record<string, string> = {\n [PATHS.configuration]: JSON.stringify(configuration(), null, 2),\n [PATHS.jwks]: JSON.stringify(jwks(), null, 2),\n [PATHS.policy]: await policy(),\n [PATHS.directory]: await keyDirectory(),\n };\n return out;\n }\n\n return { issuer, domain, handle, record, documents, card, grantsFor };\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n\n/** A page for the person, where a redirect would go somewhere the issuer cannot vouch for. */\nfunction page(reason: string, headers: Record<string, string> = {}): Response {\n return new Response(`This sign-in can’t go on: ${reason}.\\n`, {\n status: 400,\n headers: {\n 'content-type': 'text/plain; charset=utf-8',\n 'cache-control': 'no-store',\n ...headers,\n },\n });\n}\n\nfunction json(value: unknown, maxAge = 0, status = 200): Response {\n return text(JSON.stringify(value), 'application/json', maxAge, status);\n}\n\nfunction text(body: string, type: string, maxAge = 0, status = 200): Response {\n return new Response(body, {\n status,\n headers: {\n 'content-type': type,\n 'cache-control': maxAge > 0 ? `public, max-age=${maxAge}` : 'no-store',\n 'access-control-allow-origin': '*',\n },\n });\n}\n","import { createServer, type IncomingMessage, type Server } from 'node:http';\n\nimport type { Issuer } from './issuer';\n\n/**\n * The issuer on `node:http`. It answers on whatever host reaches it and\n * signs for its configured `issuer` URL, so it runs behind the company's own\n * reverse proxy: publish the read-only paths, keep the token endpoint inside.\n */\nexport function serve(issuer: Issuer, port: number, host = '0.0.0.0'): Promise<Server> {\n const server = createServer(async (req, res) => {\n try {\n const response = (await issuer.handle(await toRequest(req, issuer.issuer))) ?? notFound();\n res.writeHead(response.status, Object.fromEntries(response.headers));\n res.end(req.method === 'HEAD' ? undefined : Buffer.from(await response.arrayBuffer()));\n } catch (error) {\n console.error(error);\n res.writeHead(500, { 'content-type': 'application/json' });\n res.end(JSON.stringify({ error: 'server_error' }));\n }\n });\n return new Promise((resolve) => server.listen(port, host, () => resolve(server)));\n}\n\nconst MAX_BODY = 64 * 1024;\n\nasync function toRequest(req: IncomingMessage, base: string): Promise<Request> {\n const chunks: Buffer[] = [];\n let size = 0;\n for await (const chunk of req) {\n size += (chunk as Buffer).length;\n if (size > MAX_BODY) throw new Error('Request body too large.');\n chunks.push(chunk as Buffer);\n }\n const headers = new Headers();\n for (const [name, value] of Object.entries(req.headers)) {\n if (typeof value === 'string') headers.set(name, value);\n else if (Array.isArray(value)) headers.set(name, value.join(', '));\n }\n const method = req.method ?? 'GET';\n return new Request(new URL(req.url ?? '/', base), {\n method,\n headers,\n body: method === 'GET' || method === 'HEAD' ? undefined : Buffer.concat(chunks),\n });\n}\n\nfunction notFound(): Response {\n return new Response(JSON.stringify({ error: 'not_found' }), {\n status: 404,\n headers: { 'content-type': 'application/json' },\n });\n}\n","import { chmod, mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nimport { generateIdentity } from '@pidgeon-ai/id';\n\nimport { loadConfig } from './config';\nimport { createIssuer } from './issuer';\nimport { serve } from './server';\n\n/**\n * `pidgeon-issuer`: a Post issuer for your own domain, run inside your own\n * network. Nothing is sent to Pidgeon: not the key, not the agents.\n *\n * pidgeon-issuer keygen acme.com a key, the issuer's or an agent's, in a file only you hold\n * pidgeon-issuer serve the issuer, on PORT (default 8080)\n * pidgeon-issuer dns the record to publish at _post.<domain>\n * pidgeon-issuer export <dir> the public documents, for a static host\n *\n * The config is `issuer.json` here, or `PIDGEON_ISSUER_CONFIG`.\n */\n\nexport class UsageError extends Error {}\n\nconst HELP = `pidgeon-issuer — a Post issuer for your own domain, inside your own network.\n\n keygen <domain> [--out <file>] Make a key, the issuer's or an agent's (default ./pidgeon-issuer-key.json, mode 0600)\n serve Run the issuer on PORT (default 8080)\n dns Print the DNS records that make the domain findable\n export <dir> Write the public documents as static files\n\n --config <file> Default issuer.json, or PIDGEON_ISSUER_CONFIG`;\n\nfunction option(args: string[], name: string): string | undefined {\n const at = args.indexOf(name);\n return at >= 0 ? args[at + 1] : undefined;\n}\n\nexport async function runIssuer(\n args: string[],\n env: Record<string, string | undefined> = process.env,\n io: { log?: (line: string) => void } = {},\n): Promise<string> {\n const [command, ...rest] = args;\n const configPath = option(rest, '--config') ?? env.PIDGEON_ISSUER_CONFIG ?? 'issuer.json';\n\n switch (command) {\n case 'keygen': {\n const domain = rest.find((arg) => !arg.startsWith('--') && arg !== option(rest, '--out'));\n if (!domain) throw new UsageError('keygen <domain>');\n const out = option(rest, '--out') ?? 'pidgeon-issuer-key.json';\n const identity = generateIdentity(domain);\n await mkdir(dirname(out), { recursive: true });\n const file = {\n v: 1,\n domain: identity.domain,\n kid: identity.kid,\n seed: Buffer.from(identity.seed).toString('base64url'),\n previous: null,\n };\n await writeFile(out, `${JSON.stringify(file, null, 2)}\\n`, { mode: 0o600, flag: 'wx' });\n await chmod(out, 0o600);\n return [\n `Wrote ${out}. Keep it secret.`,\n ` kid ${identity.kid}`,\n ` key ${Buffer.from(identity.publicKey).toString('base64url')}`,\n '',\n 'For the issuer, name the file as `key` in issuer.json. For an agent, keep it where',\n `@pidgeon-ai/id looks (~/.config/pidgeon/id/${identity.domain}.json, or PIDGEON_ID_DIR)`,\n \"and give the identity provider its `key` line: that is the agent's pidgeon.key.\",\n ].join('\\n');\n }\n case 'serve': {\n const issuer = createIssuer(await loadConfig(configPath, env));\n const port = Number(env.PORT ?? 8080);\n await serve(issuer, port);\n io.log?.(`Issuing for ${issuer.domain} as ${issuer.issuer}, on port ${port}.`);\n return new Promise<string>(() => {});\n }\n case 'dns': {\n const issuer = createIssuer(await loadConfig(configPath, env));\n const host = new URL(issuer.issuer).hostname;\n return [\n `_post.${issuer.domain}. TXT \"${issuer.record()}\"`,\n `${host}. CNAME <where this issuer, or its exported documents, answer publicly>`,\n ].join('\\n');\n }\n case 'export': {\n const dir = rest.find((arg) => !arg.startsWith('--') && arg !== option(rest, '--config'));\n if (!dir) throw new UsageError('export <dir>');\n const issuer = createIssuer(await loadConfig(configPath, env));\n const written: string[] = [];\n for (const [path, body] of Object.entries(await issuer.documents())) {\n const target = join(dir, path);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, body);\n written.push(path);\n }\n return `Wrote ${written.length} documents to ${dir}. Re-export when an agent or a key changes.`;\n }\n case undefined:\n case 'help':\n case '--help':\n return HELP;\n default:\n throw new UsageError(`Unknown command ${command}.\\n\\n${HELP}`);\n }\n}\n"],"mappings":"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","names":["page","verify","createHash","sign","ptr","wasm","publicKey","wasm","createHash","value","publicKey","publicKey","verify","createHash","createPublicKey","randomBytes","verify","b64url","text","readFile","readFile","createHash","createPublicKey","randomBytes","randomUUID","verify","TOKEN_EXCHANGE","b64url","verify","createPublicKey","createHash","text","agent","card","randomUUID","randomBytes","resolve","dirname","UsageError","dirname"]}
|