@peac/protocol 0.10.12 → 0.10.14
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.
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/transport-profiles.d.ts +1 -1
- package/package.json +5 -5
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/telemetry.ts","../src/issue.ts","../src/verify.ts","../src/verify-local.ts","../src/headers.ts","../src/discovery.ts","../src/verifier-types.ts","../src/ssrf-safe-fetch.ts","../src/verification-report.ts","../src/verifier-core.ts","../src/transport-profiles.ts","../src/pointer-fetch.ts"],"names":["createHash","isValidPurposeToken","isCanonicalPurpose","isValidPurposeReason","isValidWorkflowContext","createWorkflowContextInvalidError","hasValidDagSemantics","createWorkflowDagInvalidError","uuidv7","WORKFLOW_EXTENSION_KEY","ReceiptClaims","ZodError","issue","createEvidenceNotJsonError","validateSubjectSnapshot","sign","decode","jwsVerify","parseReceiptClaims","PEAC_RECEIPT_HEADER","PEAC_PURPOSE_HEADER","parsePurposeHeader","PEAC_PURPOSE_APPLIED_HEADER","PEAC_PURPOSE_REASON_HEADER","PEAC_ISSUER_CONFIG_MAX_BYTES","PEAC_ISSUER_CONFIG_PATH","PEAC_POLICY_MAX_BYTES","PEAC_POLICY_PATH","PEAC_POLICY_FALLBACK_PATH","VERIFIER_LIMITS","VERIFIER_NETWORK","VERIFIER_POLICY_VERSION","VERIFICATION_REPORT_VERSION","body","rawBytes","sha256Hex","WIRE_TYPE","jwksCache","CACHE_TTL_MS","fetchIssuerConfig","result","computeJwkThumbprint","jwkToPublicKeyBytes","base64urlDecode"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Telemetry utilities for protocol package\n *\n * TelemetryHook is the protocol-local interface for observability.\n * Hooks are best-effort side effects: fire-and-forget, never awaited,\n * guarded against both sync throws and async rejections.\n */\n\nimport { createHash } from 'node:crypto';\n\n/**\n * Input for receipt issued telemetry event\n */\nexport interface ReceiptIssuedHookInput {\n receiptHash: string;\n issuer?: string;\n kid?: string;\n durationMs?: number;\n}\n\n/**\n * Input for receipt verified telemetry event\n */\nexport interface ReceiptVerifiedHookInput {\n receiptHash: string;\n valid: boolean;\n reasonCode?: string;\n issuer?: string;\n kid?: string;\n durationMs?: number;\n}\n\n/**\n * Telemetry hook interface for protocol observability\n *\n * Implementations SHOULD be no-throw. Protocol guards all calls,\n * but well-behaved hooks should not throw.\n *\n * Hooks may be sync or async -- protocol will NOT await the result.\n */\nexport type TelemetryHook = {\n onReceiptIssued?(input: ReceiptIssuedHookInput): void | Promise<void>;\n onReceiptVerified?(input: ReceiptVerifiedHookInput): void | Promise<void>;\n};\n\n/**\n * Safely invoke a telemetry hook (fire-and-forget)\n *\n * Guards both sync throws and async rejections.\n * Telemetry MUST NOT break core flow.\n */\nexport function fireTelemetryHook<T>(\n fn: ((input: T) => void | Promise<void>) | undefined,\n input: T\n): void {\n if (!fn) return;\n try {\n const result = fn(input);\n // Swallow async rejections\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {});\n }\n } catch {\n // Telemetry MUST NOT break core flow\n }\n}\n\n/**\n * Compute a SHA-256 hash of a receipt JWS\n *\n * Returns format: sha256:{hex prefix}\n * Uses first 16 chars of hex for brevity in logs/spans.\n */\nexport function hashReceipt(jws: string): string {\n const hash = createHash('sha256').update(jws).digest('hex');\n return `sha256:${hash.slice(0, 16)}`;\n}\n","/**\n * Receipt issuance\n * Validates input, generates UUIDv7 rid, and signs with Ed25519\n */\n\nimport { uuidv7 } from 'uuidv7';\nimport { sign } from '@peac/crypto';\nimport type { JsonValue } from '@peac/kernel';\nimport { ZodError } from 'zod';\nimport {\n PEACReceiptClaims,\n ReceiptClaims,\n SubjectProfileSnapshot,\n validateSubjectSnapshot,\n createEvidenceNotJsonError,\n createWorkflowContextInvalidError,\n createWorkflowDagInvalidError,\n type PEACError,\n type PurposeToken,\n type CanonicalPurpose,\n type PurposeReason,\n isValidPurposeToken,\n isCanonicalPurpose,\n isValidPurposeReason,\n // Workflow correlation (v0.10.2+)\n type WorkflowContext,\n isValidWorkflowContext,\n hasValidDagSemantics,\n WORKFLOW_EXTENSION_KEY,\n} from '@peac/schema';\nimport { hashReceipt, fireTelemetryHook, type TelemetryHook } from './telemetry.js';\n\n/**\n * Options for issuing a receipt\n */\nexport interface IssueOptions {\n /** Issuer URL (https://) */\n iss: string;\n\n /** Audience / resource URL (https://) */\n aud: string;\n\n /** Amount in smallest currency unit */\n amt: number;\n\n /** ISO 4217 currency code (uppercase) */\n cur: string;\n\n /** Payment rail identifier */\n rail: string;\n\n /** Rail-specific payment reference */\n reference: string;\n\n /** Asset transferred (e.g., \"USD\", \"USDC\", \"BTC\") - defaults to currency if not provided */\n asset?: string;\n\n /** Environment (\"live\" or \"test\") - defaults to \"test\" */\n env?: 'live' | 'test';\n\n /** Network/rail identifier (optional, SHOULD for crypto) */\n network?: string;\n\n /** Facilitator reference (optional) */\n facilitator_ref?: string;\n\n /** Rail-specific evidence (JSON-safe) - defaults to empty object if not provided */\n evidence?: JsonValue;\n\n /** Idempotency key (optional) */\n idempotency_key?: string;\n\n /** Rail-specific metadata (optional) */\n metadata?: Record<string, unknown>;\n\n /** Subject URI (optional) */\n subject?: string;\n\n /** Extensions (optional) */\n ext?: PEACReceiptClaims['ext'];\n\n /** Expiry timestamp (Unix seconds, optional) */\n exp?: number;\n\n /** Subject profile snapshot for envelope (v0.9.17+, optional) */\n subject_snapshot?: SubjectProfileSnapshot;\n\n /**\n * Purposes declared by the requesting agent (v0.9.24+, optional)\n *\n * From PEAC-Purpose request header. Accepts single token or array.\n * Unknown tokens are preserved for forward compatibility.\n */\n purpose?: PurposeToken | PurposeToken[];\n\n /**\n * Single purpose enforced by policy (v0.9.24+, optional)\n *\n * MUST be one of declared purposes OR a more restrictive downgrade.\n * Only canonical purposes have enforcement semantics.\n */\n purpose_enforced?: CanonicalPurpose;\n\n /**\n * Reason for enforcement decision (v0.9.24+, optional)\n *\n * The audit spine - explains WHY purpose was enforced as it was.\n */\n purpose_reason?: PurposeReason;\n\n /**\n * Workflow correlation context (v0.10.2+, optional)\n *\n * Links this receipt into a multi-step workflow DAG.\n * Added to ext['org.peacprotocol/workflow'].\n */\n workflow_context?: WorkflowContext;\n\n /** Ed25519 private key (32 bytes) */\n privateKey: Uint8Array;\n\n /** Key ID (ISO 8601 timestamp) */\n kid: string;\n\n /** Telemetry hook (optional, fire-and-forget) */\n telemetry?: TelemetryHook;\n}\n\n/**\n * Result of issuing a receipt\n */\nexport interface IssueResult {\n /** JWS compact serialization */\n jws: string;\n\n /** Validated subject snapshot (if provided) */\n subject_snapshot?: SubjectProfileSnapshot;\n}\n\n/**\n * Error thrown during receipt issuance\n *\n * Wraps a structured PEACError for programmatic handling.\n */\nexport class IssueError extends Error {\n /** Structured error details */\n readonly peacError: PEACError;\n\n constructor(peacError: PEACError) {\n const details = peacError.details as { message?: string } | undefined;\n super(details?.message ?? peacError.code);\n this.name = 'IssueError';\n this.peacError = peacError;\n }\n}\n\n/**\n * Issue a PEAC receipt\n *\n * @param options - Receipt options\n * @returns Issue result with JWS and optional subject_snapshot\n * @throws IssueError if evidence contains non-JSON-safe values\n */\nexport async function issue(options: IssueOptions): Promise<IssueResult> {\n // Validate URLs\n if (!options.iss.startsWith('https://')) {\n throw new Error('Issuer URL must start with https://');\n }\n if (!options.aud.startsWith('https://')) {\n throw new Error('Audience URL must start with https://');\n }\n if (options.subject && !options.subject.startsWith('https://')) {\n throw new Error('Subject URI must start with https://');\n }\n\n // Validate currency code\n if (!/^[A-Z]{3}$/.test(options.cur)) {\n throw new Error('Currency must be ISO 4217 uppercase (e.g., USD)');\n }\n\n // Validate amount\n if (!Number.isInteger(options.amt) || options.amt < 0) {\n throw new Error('Amount must be a non-negative integer');\n }\n\n // Validate expiry (if provided)\n if (options.exp !== undefined) {\n if (!Number.isInteger(options.exp) || options.exp < 0) {\n throw new Error('Expiry must be a non-negative integer');\n }\n }\n\n // Normalize and validate purpose (v0.9.24+)\n let purposeDeclared: PurposeToken[] | undefined;\n if (options.purpose !== undefined) {\n // Normalize to array\n const rawPurposes = Array.isArray(options.purpose) ? options.purpose : [options.purpose];\n\n // Validate each token\n const invalidTokens: string[] = [];\n for (const token of rawPurposes) {\n if (!isValidPurposeToken(token)) {\n invalidTokens.push(token);\n }\n }\n if (invalidTokens.length > 0) {\n throw new Error(`Invalid purpose tokens: ${invalidTokens.join(', ')}`);\n }\n\n // Check for explicit 'undeclared' which is invalid on wire\n if (rawPurposes.includes('undeclared')) {\n throw new Error(\"Explicit 'undeclared' is not a valid purpose token (internal-only)\");\n }\n\n purposeDeclared = rawPurposes;\n }\n\n // Validate purpose_enforced (must be canonical)\n if (options.purpose_enforced !== undefined) {\n if (!isCanonicalPurpose(options.purpose_enforced)) {\n throw new Error(\n `purpose_enforced must be a canonical purpose, got: ${options.purpose_enforced}`\n );\n }\n }\n\n // Validate purpose_reason\n if (options.purpose_reason !== undefined) {\n if (!isValidPurposeReason(options.purpose_reason)) {\n throw new Error(`Invalid purpose_reason: ${options.purpose_reason}`);\n }\n }\n\n // Validate workflow_context (v0.10.2+)\n if (options.workflow_context !== undefined) {\n if (!isValidWorkflowContext(options.workflow_context)) {\n throw new IssueError(\n createWorkflowContextInvalidError('Does not conform to WorkflowContextSchema')\n );\n }\n if (!hasValidDagSemantics(options.workflow_context)) {\n // Determine specific reason\n const ctx = options.workflow_context;\n const isSelfParent = ctx.parent_step_ids.includes(ctx.step_id);\n const hasDuplicates = new Set(ctx.parent_step_ids).size !== ctx.parent_step_ids.length;\n const reason = isSelfParent ? 'self_parent' : hasDuplicates ? 'duplicate_parent' : 'cycle';\n throw new IssueError(createWorkflowDagInvalidError(reason));\n }\n }\n\n // Generate UUIDv7 for receipt ID\n const rid = uuidv7();\n\n // Get current timestamp\n const iat = Math.floor(Date.now() / 1000);\n\n // Build receipt claims\n const claims: PEACReceiptClaims = {\n iss: options.iss,\n aud: options.aud,\n iat,\n rid,\n amt: options.amt,\n cur: options.cur,\n payment: {\n rail: options.rail,\n reference: options.reference,\n amount: options.amt,\n currency: options.cur,\n asset: options.asset ?? options.cur, // Default asset to currency for backward compatibility\n env: options.env ?? 'test', // Default to test environment for backward compatibility\n evidence: options.evidence ?? {}, // Default to empty object for backward compatibility\n ...(options.network && { network: options.network }),\n ...(options.facilitator_ref && { facilitator_ref: options.facilitator_ref }),\n ...(options.idempotency_key && { idempotency_key: options.idempotency_key }),\n ...(options.metadata && { metadata: options.metadata }),\n },\n ...(options.exp && { exp: options.exp }),\n ...(options.subject && { subject: { uri: options.subject } }),\n // Build extensions (merge user-provided ext with workflow_context)\n ...((options.ext || options.workflow_context) && {\n ext: {\n ...options.ext,\n ...(options.workflow_context && {\n [WORKFLOW_EXTENSION_KEY]: options.workflow_context,\n }),\n },\n }),\n // Purpose claims (v0.9.24+)\n ...(purposeDeclared && { purpose_declared: purposeDeclared }),\n ...(options.purpose_enforced && { purpose_enforced: options.purpose_enforced }),\n ...(options.purpose_reason && { purpose_reason: options.purpose_reason }),\n };\n\n // Validate claims with Zod - map evidence errors to typed error\n try {\n ReceiptClaims.parse(claims);\n } catch (err: unknown) {\n if (err instanceof ZodError) {\n // Check if any error path touches evidence\n const evidenceIssue = err.issues.find(\n (issue: { path: (string | number)[]; message: string }) =>\n issue.path.some((p: string | number) => p === 'evidence' || p === 'payment')\n );\n if (evidenceIssue && evidenceIssue.path.includes('evidence')) {\n const peacError = createEvidenceNotJsonError(evidenceIssue.message, evidenceIssue.path);\n throw new IssueError(peacError);\n }\n }\n throw err;\n }\n\n // Validate subject_snapshot if provided (v0.9.17+)\n // This validates schema and logs advisory PII warning if applicable\n const validatedSnapshot = validateSubjectSnapshot(options.subject_snapshot);\n\n // Track start time for telemetry\n const startTime = performance.now();\n\n // Sign with Ed25519\n const jws = await sign(claims, options.privateKey, options.kid);\n\n // Emit telemetry (fire-and-forget, guarded)\n fireTelemetryHook(options.telemetry?.onReceiptIssued, {\n receiptHash: hashReceipt(jws),\n issuer: options.iss,\n kid: options.kid,\n durationMs: performance.now() - startTime,\n });\n\n return {\n jws,\n ...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),\n };\n}\n\n/**\n * Issue a PEAC receipt and return just the JWS string\n *\n * Convenience wrapper for common header-centric flows where only the JWS is needed.\n * For access to validated subject_snapshot, use issue() instead.\n *\n * @param options - Receipt options\n * @returns JWS compact serialization\n */\nexport async function issueJws(options: IssueOptions): Promise<string> {\n const result = await issue(options);\n return result.jws;\n}\n","/**\n * Receipt verification with JWKS fetching and caching\n */\n\nimport { verify as jwsVerify, decode } from '@peac/crypto';\nimport {\n PEACReceiptClaims,\n ReceiptClaims,\n SubjectProfileSnapshot,\n validateSubjectSnapshot,\n} from '@peac/schema';\nimport { hashReceipt, fireTelemetryHook, type TelemetryHook } from './telemetry.js';\n\n/**\n * JWKS key entry\n */\ninterface JWK {\n kty: string;\n crv: string;\n x: string;\n kid: string;\n}\n\n/**\n * JWKS document\n */\ninterface JWKS {\n keys: JWK[];\n}\n\n/**\n * In-memory JWKS cache\n * Maps issuer URL to { keys, expiresAt }\n */\nconst jwksCache = new Map<string, { keys: JWKS; expiresAt: number }>();\n\n/**\n * Cache TTL (5 minutes)\n */\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\n/**\n * Verification result\n */\nexport interface VerifyResult {\n /** Verification succeeded */\n ok: true;\n\n /** Receipt claims */\n claims: PEACReceiptClaims;\n\n /** Subject profile snapshot (v0.9.17+, if provided) */\n subject_snapshot?: SubjectProfileSnapshot;\n\n /** Performance metrics */\n perf?: {\n verify_ms: number;\n jwks_fetch_ms?: number;\n };\n}\n\n/**\n * Verification failure\n */\nexport interface VerifyFailure {\n /** Verification failed */\n ok: false;\n\n /** Error reason */\n reason: string;\n\n /** Error details */\n details?: string;\n}\n\n/**\n * Fetch JWKS from issuer (SSRF-safe)\n */\nasync function fetchJWKS(issuerUrl: string): Promise<JWKS> {\n // SSRF protection: only allow https://\n if (!issuerUrl.startsWith('https://')) {\n throw new Error('Issuer URL must be https://');\n }\n\n // Construct JWKS URL from discovery\n const discoveryUrl = `${issuerUrl}/.well-known/peac.txt`;\n\n try {\n const discoveryResp = await fetch(discoveryUrl, {\n headers: { Accept: 'text/plain' },\n // Timeout after 5 seconds\n signal: AbortSignal.timeout(5000),\n });\n\n if (!discoveryResp.ok) {\n throw new Error(`Discovery fetch failed: ${discoveryResp.status}`);\n }\n\n const discoveryText = await discoveryResp.text();\n\n // Parse YAML-like discovery (simple key: value parsing)\n const jwksLine = discoveryText.split('\\n').find((line) => line.startsWith('jwks:'));\n if (!jwksLine) {\n throw new Error('No jwks field in discovery');\n }\n\n const jwksUrl = jwksLine.replace('jwks:', '').trim();\n\n // SSRF protection: verify JWKS URL is also https://\n if (!jwksUrl.startsWith('https://')) {\n throw new Error('JWKS URL must be https://');\n }\n\n // Fetch JWKS\n const jwksResp = await fetch(jwksUrl, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (!jwksResp.ok) {\n throw new Error(`JWKS fetch failed: ${jwksResp.status}`);\n }\n\n const jwks = (await jwksResp.json()) as JWKS;\n\n return jwks;\n } catch (err) {\n throw new Error(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`, {\n cause: err,\n });\n }\n}\n\n/**\n * Get JWKS (from cache or fetch)\n */\nasync function getJWKS(issuerUrl: string): Promise<{ jwks: JWKS; fromCache: boolean }> {\n const now = Date.now();\n\n // Check cache\n const cached = jwksCache.get(issuerUrl);\n if (cached && cached.expiresAt > now) {\n return { jwks: cached.keys, fromCache: true };\n }\n\n // Fetch fresh JWKS\n const jwks = await fetchJWKS(issuerUrl);\n\n // Cache it\n jwksCache.set(issuerUrl, {\n keys: jwks,\n expiresAt: now + CACHE_TTL_MS,\n });\n\n return { jwks, fromCache: false };\n}\n\n/**\n * Convert JWK x coordinate to Ed25519 public key\n */\nfunction jwkToPublicKey(jwk: JWK): Uint8Array {\n if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {\n throw new Error('Only Ed25519 keys (OKP/Ed25519) are supported');\n }\n\n // Decode base64url x coordinate\n const xBytes = Buffer.from(jwk.x, 'base64url');\n if (xBytes.length !== 32) {\n throw new Error('Ed25519 public key must be 32 bytes');\n }\n\n return new Uint8Array(xBytes);\n}\n\n/**\n * Options for verifying a receipt\n */\nexport interface VerifyOptions {\n /** JWS compact serialization */\n receiptJws: string;\n\n /** Subject profile snapshot (v0.9.17+, optional envelope metadata) */\n subject_snapshot?: SubjectProfileSnapshot;\n\n /** Telemetry hook (optional, fire-and-forget) */\n telemetry?: TelemetryHook;\n}\n\n/**\n * Verify a PEAC receipt JWS\n *\n * @param optionsOrJws - Verify options or JWS compact serialization (for backwards compatibility)\n * @returns Verification result or failure\n */\nexport async function verifyReceipt(\n optionsOrJws: string | VerifyOptions\n): Promise<VerifyResult | VerifyFailure> {\n // Support both old (string) and new (options) signatures for backwards compatibility\n const receiptJws = typeof optionsOrJws === 'string' ? optionsOrJws : optionsOrJws.receiptJws;\n const inputSnapshot =\n typeof optionsOrJws === 'string' ? undefined : optionsOrJws.subject_snapshot;\n const telemetry = typeof optionsOrJws === 'string' ? undefined : optionsOrJws.telemetry;\n const startTime = performance.now();\n let jwksFetchTime: number | undefined;\n\n try {\n // Decode JWS to get issuer\n const { header, payload } = decode<PEACReceiptClaims>(receiptJws);\n\n // Validate claims structure\n ReceiptClaims.parse(payload);\n\n // Check expiry\n if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'expired',\n issuer: payload.iss,\n kid: header.kid,\n durationMs,\n });\n return {\n ok: false,\n reason: 'expired',\n details: `Receipt expired at ${new Date(payload.exp * 1000).toISOString()}`,\n };\n }\n\n // Fetch JWKS\n const jwksFetchStart = performance.now();\n const { jwks, fromCache } = await getJWKS(payload.iss);\n if (!fromCache) {\n jwksFetchTime = performance.now() - jwksFetchStart;\n }\n\n // Find key by kid\n const jwk = jwks.keys.find((k) => k.kid === header.kid);\n if (!jwk) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'unknown_key',\n issuer: payload.iss,\n kid: header.kid,\n durationMs,\n });\n return {\n ok: false,\n reason: 'unknown_key',\n details: `No key found with kid=${header.kid}`,\n };\n }\n\n // Convert JWK to public key\n const publicKey = jwkToPublicKey(jwk);\n\n // Verify signature\n const result = await jwsVerify<PEACReceiptClaims>(receiptJws, publicKey);\n\n if (!result.valid) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'invalid_signature',\n issuer: payload.iss,\n kid: header.kid,\n durationMs,\n });\n return {\n ok: false,\n reason: 'invalid_signature',\n details: 'Ed25519 signature verification failed',\n };\n }\n\n // Validate subject_snapshot if provided (v0.9.17+)\n // This validates schema and logs advisory PII warning if applicable\n const validatedSnapshot = validateSubjectSnapshot(inputSnapshot);\n\n const verifyTime = performance.now() - startTime;\n\n // Emit success telemetry (fire-and-forget, guarded)\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: true,\n issuer: payload.iss,\n kid: header.kid,\n durationMs: verifyTime,\n });\n\n return {\n ok: true,\n claims: payload,\n ...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),\n perf: {\n verify_ms: verifyTime,\n ...(jwksFetchTime && { jwks_fetch_ms: jwksFetchTime }),\n },\n };\n } catch (err) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'verification_error',\n durationMs,\n });\n return {\n ok: false,\n reason: 'verification_error',\n details: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","/**\n * Local receipt verification with schema validation\n *\n * Use this for verifying receipts when you have the public key locally,\n * without JWKS discovery.\n */\n\nimport { verify as jwsVerify } from '@peac/crypto';\nimport {\n parseReceiptClaims,\n type ReceiptClaimsType,\n type AttestationReceiptClaims,\n} from '@peac/schema';\nimport type { PolicyBindingStatus } from './verifier-types';\n\n/**\n * Structural type for CryptoError\n * Used instead of instanceof for robustness across ESM/CJS boundaries\n */\ninterface CryptoErrorLike {\n name: 'CryptoError';\n code: string;\n message: string;\n}\n\n/**\n * Structural check for CryptoError\n * More robust than instanceof across module boundaries (ESM/CJS, duplicate packages)\n */\nfunction isCryptoError(err: unknown): err is CryptoErrorLike {\n return (\n err !== null &&\n typeof err === 'object' &&\n 'name' in err &&\n err.name === 'CryptoError' &&\n 'code' in err &&\n typeof err.code === 'string' &&\n err.code.startsWith('CRYPTO_') &&\n 'message' in err &&\n typeof err.message === 'string'\n );\n}\n\n/**\n * Canonical error codes for local verification\n *\n * These map to E_* codes in specs/kernel/errors.json\n */\nexport type VerifyLocalErrorCode =\n | 'E_INVALID_SIGNATURE'\n | 'E_INVALID_FORMAT'\n | 'E_EXPIRED'\n | 'E_NOT_YET_VALID'\n | 'E_INVALID_ISSUER'\n | 'E_INVALID_AUDIENCE'\n | 'E_INVALID_SUBJECT'\n | 'E_INVALID_RECEIPT_ID'\n | 'E_MISSING_EXP'\n | 'E_INTERNAL';\n\n/**\n * Options for local verification\n */\nexport interface VerifyLocalOptions {\n /**\n * Expected issuer URL\n *\n * If provided, verification fails if receipt.iss does not match.\n */\n issuer?: string;\n\n /**\n * Expected audience URL\n *\n * If provided, verification fails if receipt.aud does not match.\n */\n audience?: string;\n\n /**\n * Expected subject URI\n *\n * If provided, verification fails if receipt.subject.uri does not match.\n * Binds the receipt to a specific resource/interaction target.\n */\n subjectUri?: string;\n\n /**\n * Expected receipt ID (rid)\n *\n * If provided, verification fails if receipt.rid does not match.\n * Useful for idempotency checks or correlating with prior receipts.\n */\n rid?: string;\n\n /**\n * Require expiration claim\n *\n * If true, receipts without exp claim are rejected.\n * Defaults to false.\n */\n requireExp?: boolean;\n\n /**\n * Current timestamp (Unix seconds)\n *\n * Defaults to Date.now() / 1000. Override for testing.\n */\n now?: number;\n\n /**\n * Maximum clock skew tolerance (seconds)\n *\n * Allows for clock drift between issuer and verifier.\n * Defaults to 300 (5 minutes).\n */\n maxClockSkew?: number;\n}\n\n/**\n * Result of successful local verification\n *\n * Discriminated union on `variant` -- callers narrow claims type via variant check:\n * if (result.valid && result.variant === 'commerce') { result.claims.amt }\n */\nexport type VerifyLocalSuccess =\n | {\n /** Verification succeeded */\n valid: true;\n /** Receipt variant (commerce = payment receipt, attestation = non-payment) */\n variant: 'commerce';\n /** Validated commerce receipt claims */\n claims: ReceiptClaimsType;\n /** Key ID from JWS header (for logging/indexing) */\n kid: string;\n /**\n * Policy binding status (DD-49).\n *\n * Always 'unavailable' for Wire 0.1 receipts (no policy digest on wire).\n * Wire 0.2 receipts with `peac.policy.digest` will report 'verified' or 'failed'.\n */\n policy_binding: PolicyBindingStatus;\n }\n | {\n /** Verification succeeded */\n valid: true;\n /** Receipt variant (commerce = payment receipt, attestation = non-payment) */\n variant: 'attestation';\n /** Validated attestation receipt claims */\n claims: AttestationReceiptClaims;\n /** Key ID from JWS header (for logging/indexing) */\n kid: string;\n /**\n * Policy binding status (DD-49).\n *\n * Always 'unavailable' for Wire 0.1 receipts (no policy digest on wire).\n * Wire 0.2 receipts with `peac.policy.digest` will report 'verified' or 'failed'.\n */\n policy_binding: PolicyBindingStatus;\n };\n\n/**\n * Result of failed local verification\n */\nexport interface VerifyLocalFailure {\n /** Verification failed */\n valid: false;\n\n /** Canonical error code (maps to specs/kernel/errors.json) */\n code: VerifyLocalErrorCode;\n\n /** Human-readable error message */\n message: string;\n\n /** Structured details for debugging (stable error code preserved in `code`) */\n details?: {\n /** Precise parse error code from unified parser (e.g. E_PARSE_COMMERCE_INVALID) */\n parse_code?: string;\n /** Zod validation issues (bounded, stable shape -- non-normative, may change) */\n issues?: ReadonlyArray<{ path: string; message: string }>;\n };\n}\n\n/**\n * Union type for local verification result\n */\nexport type VerifyLocalResult = VerifyLocalSuccess | VerifyLocalFailure;\n\n/**\n * Crypto error codes that indicate format/validation issues\n * These are CRYPTO_* internal codes from @peac/crypto, mapped to canonical E_* codes\n */\nconst FORMAT_ERROR_CODES = new Set([\n 'CRYPTO_INVALID_JWS_FORMAT',\n 'CRYPTO_INVALID_TYP',\n 'CRYPTO_INVALID_ALG',\n 'CRYPTO_INVALID_KEY_LENGTH',\n]);\n\n/** Max parse issues to include in details (prevents log bloat) */\nconst MAX_PARSE_ISSUES = 25;\n\n/**\n * Sanitize Zod issues into a bounded, stable structure.\n * Avoids exposing raw Zod internals or unbounded arrays in the public API.\n */\nfunction sanitizeParseIssues(\n issues: unknown\n): ReadonlyArray<{ path: string; message: string }> | undefined {\n if (!Array.isArray(issues)) return undefined;\n return issues.slice(0, MAX_PARSE_ISSUES).map((issue) => ({\n path: Array.isArray(issue?.path) ? issue.path.join('.') : '',\n message: typeof issue?.message === 'string' ? issue.message : String(issue),\n }));\n}\n\n/**\n * Verify a PEAC receipt locally with a known public key\n *\n * This function:\n * 1. Verifies the Ed25519 signature and header (typ, alg)\n * 2. Validates the receipt schema with Zod\n * 3. Checks issuer/audience/subject binding (if options provided)\n * 4. Checks time validity (exp/iat with clock skew tolerance)\n *\n * Use this when you have the issuer's public key and don't need JWKS discovery.\n * For JWKS-based verification, use `verifyReceipt()` instead.\n *\n * @param jws - JWS compact serialization\n * @param publicKey - Ed25519 public key (32 bytes)\n * @param options - Optional verification options (issuer, audience, subject, clock skew)\n * @returns Typed verification result\n *\n * @example\n * ```typescript\n * const result = await verifyLocal(jws, publicKey, {\n * issuer: 'https://api.example.com',\n * audience: 'https://client.example.com',\n * subjectUri: 'https://api.example.com/inference/v1',\n * });\n * if (result.valid) {\n * console.log('Issuer:', result.claims.iss);\n * console.log('Amount:', result.claims.amt, result.claims.cur);\n * console.log('Key ID:', result.kid);\n * } else {\n * console.error('Verification failed:', result.code, result.message);\n * }\n * ```\n */\nexport async function verifyLocal(\n jws: string,\n publicKey: Uint8Array,\n options: VerifyLocalOptions = {}\n): Promise<VerifyLocalResult> {\n const { issuer, audience, subjectUri, rid, requireExp = false, maxClockSkew = 300 } = options;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n\n try {\n // 1. Verify signature and header (typ, alg validated by @peac/crypto)\n const result = await jwsVerify<unknown>(jws, publicKey);\n\n if (!result.valid) {\n return {\n valid: false,\n code: 'E_INVALID_SIGNATURE',\n message: 'Ed25519 signature verification failed',\n };\n }\n\n // 2. Validate schema (unified parser supports both commerce and attestation)\n const pr = parseReceiptClaims(result.payload);\n\n if (!pr.ok) {\n return {\n valid: false,\n code: 'E_INVALID_FORMAT',\n message: `Receipt schema validation failed: ${pr.error.message}`,\n details: { parse_code: pr.error.code, issues: sanitizeParseIssues(pr.error.issues) },\n };\n }\n\n // Shared binding checks (iss, aud, rid, iat, exp exist on both receipt types)\n // 3. Check issuer binding\n if (issuer !== undefined && pr.claims.iss !== issuer) {\n return {\n valid: false,\n code: 'E_INVALID_ISSUER',\n message: `Issuer mismatch: expected \"${issuer}\", got \"${pr.claims.iss}\"`,\n };\n }\n\n // 4. Check audience binding\n if (audience !== undefined && pr.claims.aud !== audience) {\n return {\n valid: false,\n code: 'E_INVALID_AUDIENCE',\n message: `Audience mismatch: expected \"${audience}\", got \"${pr.claims.aud}\"`,\n };\n }\n\n // 5. Check receipt ID binding\n if (rid !== undefined && pr.claims.rid !== rid) {\n return {\n valid: false,\n code: 'E_INVALID_RECEIPT_ID',\n message: `Receipt ID mismatch: expected \"${rid}\", got \"${pr.claims.rid}\"`,\n };\n }\n\n // 6. Check requireExp\n if (requireExp && pr.claims.exp === undefined) {\n return {\n valid: false,\n code: 'E_MISSING_EXP',\n message: 'Receipt missing required exp claim',\n };\n }\n\n // 7. Check not-yet-valid (iat with clock skew)\n if (pr.claims.iat > now + maxClockSkew) {\n return {\n valid: false,\n code: 'E_NOT_YET_VALID',\n message: `Receipt not yet valid: issued at ${new Date(pr.claims.iat * 1000).toISOString()}, now is ${new Date(now * 1000).toISOString()}`,\n };\n }\n\n // 8. Check expiry (with clock skew tolerance)\n if (pr.claims.exp !== undefined && pr.claims.exp < now - maxClockSkew) {\n return {\n valid: false,\n code: 'E_EXPIRED',\n message: `Receipt expired at ${new Date(pr.claims.exp * 1000).toISOString()}`,\n };\n }\n\n // 9. Subject binding + typed return (variant-branched, no unsafe casts)\n if (pr.variant === 'commerce') {\n const claims = pr.claims as ReceiptClaimsType;\n if (subjectUri !== undefined && claims.subject?.uri !== subjectUri) {\n return {\n valid: false,\n code: 'E_INVALID_SUBJECT',\n message: `Subject mismatch: expected \"${subjectUri}\", got \"${claims.subject?.uri ?? 'undefined'}\"`,\n };\n }\n // Wire 0.1: no policy digest on wire, always 'unavailable' (DD-49)\n return {\n valid: true,\n variant: 'commerce',\n claims,\n kid: result.header.kid,\n policy_binding: 'unavailable',\n };\n } else {\n const claims = pr.claims as AttestationReceiptClaims;\n if (subjectUri !== undefined && claims.sub !== subjectUri) {\n return {\n valid: false,\n code: 'E_INVALID_SUBJECT',\n message: `Subject mismatch: expected \"${subjectUri}\", got \"${claims.sub ?? 'undefined'}\"`,\n };\n }\n // Wire 0.1: no policy digest on wire, always 'unavailable' (DD-49)\n return {\n valid: true,\n variant: 'attestation',\n claims,\n kid: result.header.kid,\n policy_binding: 'unavailable',\n };\n }\n } catch (err) {\n // Handle typed CryptoError from @peac/crypto\n // Use structural check instead of instanceof for robustness across ESM/CJS boundaries\n // Map internal CRYPTO_* codes to canonical E_* codes\n if (isCryptoError(err)) {\n if (FORMAT_ERROR_CODES.has(err.code)) {\n return {\n valid: false,\n code: 'E_INVALID_FORMAT',\n message: err.message,\n };\n }\n if (err.code === 'CRYPTO_INVALID_SIGNATURE') {\n return {\n valid: false,\n code: 'E_INVALID_SIGNATURE',\n message: err.message,\n };\n }\n }\n\n // Handle JSON parse errors from malformed payloads\n // Use structural check for cross-boundary robustness (consistent with isCryptoError pattern)\n if (\n err !== null &&\n typeof err === 'object' &&\n 'name' in err &&\n (err as { name: unknown }).name === 'SyntaxError'\n ) {\n const syntaxMessage =\n 'message' in err && typeof (err as { message: unknown }).message === 'string'\n ? (err as { message: string }).message\n : 'Invalid JSON';\n return {\n valid: false,\n code: 'E_INVALID_FORMAT',\n message: `Invalid receipt payload: ${syntaxMessage}`,\n };\n }\n\n // All other errors -> E_INTERNAL\n // No message parsing - code-based mapping only\n const message = err instanceof Error ? err.message : String(err);\n return {\n valid: false,\n code: 'E_INTERNAL',\n message: `Unexpected verification error: ${message}`,\n };\n }\n}\n\n/**\n * Type guard: narrows a VerifyLocalResult to a commerce success.\n *\n * Use instead of manual `result.valid && result.variant === 'commerce'` checks\n * to get proper claims narrowing to ReceiptClaimsType.\n */\nexport function isCommerceResult(\n r: VerifyLocalResult\n): r is VerifyLocalSuccess & { variant: 'commerce' } {\n return r.valid === true && r.variant === 'commerce';\n}\n\n/**\n * Type guard: narrows a VerifyLocalResult to an attestation success.\n *\n * Use instead of manual `result.valid && result.variant === 'attestation'` checks\n * to get proper claims narrowing to AttestationReceiptClaims.\n */\nexport function isAttestationResult(\n r: VerifyLocalResult\n): r is VerifyLocalSuccess & { variant: 'attestation' } {\n return r.valid === true && r.variant === 'attestation';\n}\n","/**\n * HTTP header utilities for PEAC receipts and purpose\n */\n\nimport {\n PEAC_RECEIPT_HEADER,\n PEAC_PURPOSE_HEADER,\n PEAC_PURPOSE_APPLIED_HEADER,\n PEAC_PURPOSE_REASON_HEADER,\n parsePurposeHeader,\n type PurposeToken,\n type CanonicalPurpose,\n type PurposeReason,\n} from '@peac/schema';\n\n/**\n * Set PEAC-Receipt header on a response\n *\n * @param headers - Headers object (e.g., Response.headers)\n * @param receiptJws - JWS compact serialization\n */\nexport function setReceiptHeader(headers: Headers, receiptJws: string): void {\n headers.set(PEAC_RECEIPT_HEADER, receiptJws);\n}\n\n/**\n * Get PEAC-Receipt header from a request/response\n *\n * @param headers - Headers object\n * @returns JWS compact serialization, or null if not present\n */\nexport function getReceiptHeader(headers: Headers): string | null {\n return headers.get(PEAC_RECEIPT_HEADER);\n}\n\n/**\n * Set Vary: PEAC-Receipt header for caching\n *\n * @param headers - Response headers\n */\nexport function setVaryHeader(headers: Headers): void {\n const existing = headers.get('Vary');\n if (existing) {\n // Append to existing Vary header\n const varies = existing.split(',').map((v) => v.trim());\n if (!varies.includes(PEAC_RECEIPT_HEADER)) {\n headers.set('Vary', `${existing}, ${PEAC_RECEIPT_HEADER}`);\n }\n } else {\n headers.set('Vary', PEAC_RECEIPT_HEADER);\n }\n}\n\n// -----------------------------------------------------------------------------\n// Purpose Header Utilities (v0.9.24+)\n// -----------------------------------------------------------------------------\n\n/**\n * Get PEAC-Purpose header from a request\n *\n * Parses the comma-separated purpose token list into an array.\n * Normalizes tokens (lowercase, trim whitespace), deduplicates.\n *\n * @param headers - Request headers\n * @returns Array of normalized PurposeToken values, empty if header missing\n */\nexport function getPurposeHeader(headers: Headers): PurposeToken[] {\n const value = headers.get(PEAC_PURPOSE_HEADER);\n if (!value) {\n return [];\n }\n return parsePurposeHeader(value);\n}\n\n/**\n * Set PEAC-Purpose-Applied header on a response\n *\n * Indicates which purpose(s) were enforced for this request.\n *\n * @param headers - Response headers\n * @param purpose - Single canonical purpose that was enforced\n */\nexport function setPurposeAppliedHeader(headers: Headers, purpose: CanonicalPurpose): void {\n headers.set(PEAC_PURPOSE_APPLIED_HEADER, purpose);\n}\n\n/**\n * Set PEAC-Purpose-Reason header on a response\n *\n * Explains WHY the purpose was enforced as it was (audit trail).\n *\n * @param headers - Response headers\n * @param reason - Purpose reason enum value\n */\nexport function setPurposeReasonHeader(headers: Headers, reason: PurposeReason): void {\n headers.set(PEAC_PURPOSE_REASON_HEADER, reason);\n}\n\n/**\n * Set Vary: PEAC-Purpose header for caching\n *\n * If response behavior varies by declared purpose, MUST set this header.\n *\n * @param headers - Response headers\n */\nexport function setVaryPurposeHeader(headers: Headers): void {\n const existing = headers.get('Vary');\n if (existing) {\n const varies = existing.split(',').map((v) => v.trim());\n if (!varies.includes(PEAC_PURPOSE_HEADER)) {\n headers.set('Vary', `${existing}, ${PEAC_PURPOSE_HEADER}`);\n }\n } else {\n headers.set('Vary', PEAC_PURPOSE_HEADER);\n }\n}\n","/**\n * PEAC Discovery - Issuer Configuration and Policy Manifest\n *\n * This module provides functions for:\n * - Issuer configuration discovery (/.well-known/peac-issuer.json)\n * - Policy manifest parsing (/.well-known/peac.txt)\n *\n * @see docs/specs/PEAC-ISSUER.md\n * @see docs/specs/PEAC-TXT.md\n */\n\nimport {\n PEACIssuerConfig,\n PEACPolicyManifest,\n PEACDiscovery,\n PEAC_ISSUER_CONFIG_PATH,\n PEAC_ISSUER_CONFIG_MAX_BYTES,\n PEAC_POLICY_PATH,\n PEAC_POLICY_FALLBACK_PATH,\n PEAC_POLICY_MAX_BYTES,\n} from '@peac/schema';\n\n// ============================================================================\n// Issuer Configuration (/.well-known/peac-issuer.json)\n// ============================================================================\n\n/**\n * Parse PEAC issuer configuration from JSON\n *\n * @param json - JSON string or object\n * @returns Parsed issuer configuration\n * @throws Error if validation fails\n */\nexport function parseIssuerConfig(json: string | object): PEACIssuerConfig {\n let config: unknown;\n\n if (typeof json === 'string') {\n const bytes = new TextEncoder().encode(json).length;\n if (bytes > PEAC_ISSUER_CONFIG_MAX_BYTES) {\n throw new Error(`Issuer config exceeds ${PEAC_ISSUER_CONFIG_MAX_BYTES} bytes (got ${bytes})`);\n }\n\n try {\n config = JSON.parse(json);\n } catch {\n throw new Error('Issuer config is not valid JSON');\n }\n } else {\n config = json;\n }\n\n if (typeof config !== 'object' || config === null) {\n throw new Error('Issuer config must be an object');\n }\n\n const obj = config as Record<string, unknown>;\n\n // Validate required fields\n if (typeof obj.version !== 'string' || !obj.version) {\n throw new Error('Missing required field: version');\n }\n if (typeof obj.issuer !== 'string' || !obj.issuer) {\n throw new Error('Missing required field: issuer');\n }\n if (typeof obj.jwks_uri !== 'string' || !obj.jwks_uri) {\n throw new Error('Missing required field: jwks_uri');\n }\n\n // Validate URL fields\n if (!obj.issuer.startsWith('https://')) {\n throw new Error('issuer must be an HTTPS URL');\n }\n if (!obj.jwks_uri.startsWith('https://')) {\n throw new Error('jwks_uri must be an HTTPS URL');\n }\n\n // Validate optional fields\n if (obj.verify_endpoint !== undefined) {\n if (typeof obj.verify_endpoint !== 'string') {\n throw new Error('verify_endpoint must be a string');\n }\n if (!obj.verify_endpoint.startsWith('https://')) {\n throw new Error('verify_endpoint must be an HTTPS URL');\n }\n }\n\n if (obj.receipt_versions !== undefined) {\n if (!Array.isArray(obj.receipt_versions)) {\n throw new Error('receipt_versions must be an array');\n }\n }\n\n if (obj.algorithms !== undefined) {\n if (!Array.isArray(obj.algorithms)) {\n throw new Error('algorithms must be an array');\n }\n }\n\n if (obj.payment_rails !== undefined) {\n if (!Array.isArray(obj.payment_rails)) {\n throw new Error('payment_rails must be an array');\n }\n }\n\n return {\n version: obj.version,\n issuer: obj.issuer,\n jwks_uri: obj.jwks_uri,\n verify_endpoint: obj.verify_endpoint as string | undefined,\n receipt_versions: obj.receipt_versions as string[] | undefined,\n algorithms: obj.algorithms as string[] | undefined,\n payment_rails: obj.payment_rails as string[] | undefined,\n security_contact: obj.security_contact as string | undefined,\n };\n}\n\n/**\n * Fetch PEAC issuer configuration from an issuer URL\n *\n * @param issuerUrl - Issuer URL (https://)\n * @returns Parsed issuer configuration\n * @throws Error if fetch or validation fails\n */\nexport async function fetchIssuerConfig(issuerUrl: string): Promise<PEACIssuerConfig> {\n if (!issuerUrl.startsWith('https://')) {\n throw new Error('Issuer URL must be https://');\n }\n\n // Remove trailing slash for consistent URL construction\n const baseUrl = issuerUrl.replace(/\\/$/, '');\n const configUrl = `${baseUrl}${PEAC_ISSUER_CONFIG_PATH}`;\n\n try {\n const resp = await fetch(configUrl, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(10000),\n });\n\n if (!resp.ok) {\n throw new Error(`Issuer config fetch failed: ${resp.status}`);\n }\n\n const text = await resp.text();\n const config = parseIssuerConfig(text);\n\n // Verify issuer matches\n const normalizedExpected = baseUrl.replace(/\\/$/, '');\n const normalizedActual = config.issuer.replace(/\\/$/, '');\n if (normalizedActual !== normalizedExpected) {\n throw new Error(`Issuer mismatch: expected ${normalizedExpected}, got ${normalizedActual}`);\n }\n\n return config;\n } catch (err) {\n throw new Error(\n `Failed to fetch issuer config from ${issuerUrl}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err }\n );\n }\n}\n\n// ============================================================================\n// Policy Manifest (/.well-known/peac.txt)\n// ============================================================================\n\n/**\n * Detect if content is JSON or YAML\n */\nfunction isJsonContent(text: string, contentType?: string): boolean {\n if (contentType?.includes('application/json')) {\n return true;\n }\n const firstChar = text.trimStart()[0];\n return firstChar === '{';\n}\n\n/**\n * Parse PEAC policy manifest from YAML or JSON\n *\n * @param text - Policy manifest text (YAML or JSON)\n * @param contentType - Optional Content-Type header value\n * @returns Parsed policy manifest\n * @throws Error if validation fails\n */\nexport function parsePolicyManifest(text: string, contentType?: string): PEACPolicyManifest {\n const bytes = new TextEncoder().encode(text).length;\n if (bytes > PEAC_POLICY_MAX_BYTES) {\n throw new Error(`Policy manifest exceeds ${PEAC_POLICY_MAX_BYTES} bytes (got ${bytes})`);\n }\n\n let manifest: Record<string, unknown>;\n\n if (isJsonContent(text, contentType)) {\n // Parse as JSON\n try {\n manifest = JSON.parse(text);\n } catch {\n throw new Error('Policy manifest is not valid JSON');\n }\n } else {\n // Parse as simple YAML (key: value format)\n manifest = parseSimpleYaml(text);\n }\n\n // Validate required fields\n if (typeof manifest.version !== 'string' || !manifest.version) {\n throw new Error('Missing required field: version');\n }\n\n // Validate version format: must be peac-policy/<major>.<minor>\n if (!manifest.version.startsWith('peac-policy/')) {\n throw new Error(\n `Invalid version format: \"${manifest.version}\". Must start with \"peac-policy/\" (e.g., \"peac-policy/0.1\")`\n );\n }\n\n if (manifest.usage !== 'open' && manifest.usage !== 'conditional') {\n throw new Error('Missing or invalid field: usage (must be \"open\" or \"conditional\")');\n }\n\n return {\n version: manifest.version,\n usage: manifest.usage as 'open' | 'conditional',\n purposes: manifest.purposes as string[] | undefined,\n receipts: manifest.receipts as 'required' | 'optional' | 'omit' | undefined,\n attribution: manifest.attribution as 'required' | 'optional' | 'none' | undefined,\n rate_limit: manifest.rate_limit as string | undefined,\n daily_limit: manifest.daily_limit as number | undefined,\n negotiate: manifest.negotiate as string | undefined,\n contact: manifest.contact as string | undefined,\n license: manifest.license as string | undefined,\n price: manifest.price as number | undefined,\n currency: manifest.currency as string | undefined,\n payment_methods: manifest.payment_methods as string[] | undefined,\n payment_endpoint: manifest.payment_endpoint as string | undefined,\n };\n}\n\n/**\n * Parse simple YAML (key: value format, no complex features)\n * Rejects YAML features that are security risks (anchors, aliases, tags)\n */\nfunction parseSimpleYaml(text: string): Record<string, unknown> {\n const lines = text.split('\\n');\n const result: Record<string, unknown> = {};\n\n // Security: reject YAML features that are dangerous\n // Check merge keys first (they contain * which would trigger anchor check)\n if (text.includes('<<:')) {\n throw new Error('YAML merge keys are not allowed');\n }\n if (text.includes('&') || text.includes('*')) {\n throw new Error('YAML anchors and aliases are not allowed');\n }\n if (/!\\w+/.test(text)) {\n throw new Error('YAML custom tags are not allowed');\n }\n\n // Count document separators\n const docSeparators = text.match(/^---$/gm);\n if (docSeparators && docSeparators.length > 1) {\n throw new Error('Multi-document YAML is not allowed');\n }\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines, comments, and document markers\n if (!trimmed || trimmed.startsWith('#') || trimmed === '---') {\n continue;\n }\n\n // Parse key: value\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = trimmed.slice(0, colonIndex).trim();\n let value: unknown = trimmed.slice(colonIndex + 1).trim();\n\n // Parse value types\n if (value === '') {\n value = undefined;\n } else if (typeof value === 'string') {\n // Remove quotes if present\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n // Parse arrays [a, b, c]\n else if (value.startsWith('[') && value.endsWith(']')) {\n const inner = value.slice(1, -1);\n value = inner\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n }\n // Parse numbers\n else if (/^-?\\d+(\\.\\d+)?$/.test(value)) {\n value = parseFloat(value);\n }\n // Parse booleans\n else if (value === 'true') {\n value = true;\n } else if (value === 'false') {\n value = false;\n }\n }\n\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Fetch PEAC policy manifest from a domain\n *\n * @param baseUrl - Base URL (https://example.com)\n * @returns Parsed policy manifest\n * @throws Error if fetch or validation fails\n */\nexport async function fetchPolicyManifest(baseUrl: string): Promise<PEACPolicyManifest> {\n if (!baseUrl.startsWith('https://') && !baseUrl.startsWith('http://localhost')) {\n throw new Error('Base URL must be https://');\n }\n\n const normalizedBase = baseUrl.replace(/\\/$/, '');\n const primaryUrl = `${normalizedBase}${PEAC_POLICY_PATH}`;\n const fallbackUrl = `${normalizedBase}${PEAC_POLICY_FALLBACK_PATH}`;\n\n // Try primary location first\n try {\n const resp = await fetch(primaryUrl, {\n headers: { Accept: 'text/plain, application/json' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (resp.ok) {\n const text = await resp.text();\n const contentType = resp.headers.get('content-type') || undefined;\n return parsePolicyManifest(text, contentType);\n }\n\n // If 404, try fallback\n if (resp.status === 404) {\n const fallbackResp = await fetch(fallbackUrl, {\n headers: { Accept: 'text/plain, application/json' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (fallbackResp.ok) {\n const text = await fallbackResp.text();\n const contentType = fallbackResp.headers.get('content-type') || undefined;\n return parsePolicyManifest(text, contentType);\n }\n\n throw new Error('Policy manifest not found at primary or fallback location');\n }\n\n throw new Error(`Policy manifest fetch failed: ${resp.status}`);\n } catch (err) {\n throw new Error(\n `Failed to fetch policy manifest from ${baseUrl}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err }\n );\n }\n}\n\n// ============================================================================\n// Deprecated Legacy API (for backward compatibility)\n// ============================================================================\n\n/**\n * @deprecated Use parseIssuerConfig instead. Will be removed in v1.0.\n *\n * Parse a PEAC discovery manifest from YAML-like text.\n * This function is maintained for backward compatibility only.\n */\nexport function parseDiscovery(text: string): PEACDiscovery {\n const bytes = new TextEncoder().encode(text).length;\n if (bytes > 2000) {\n throw new Error(`Discovery manifest exceeds 2000 bytes (got ${bytes})`);\n }\n\n const lines = text.trim().split('\\n');\n if (lines.length > 20) {\n throw new Error(`Discovery manifest exceeds 20 lines (got ${lines.length})`);\n }\n\n const discovery: Partial<PEACIssuerConfig> = {};\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n if (trimmed.includes(':')) {\n const [key, ...valueParts] = trimmed.split(':');\n const value = valueParts.join(':').trim();\n\n switch (key.trim()) {\n case 'version':\n discovery.version = value;\n break;\n case 'issuer':\n discovery.issuer = value;\n break;\n case 'verify':\n discovery.verify_endpoint = value;\n break;\n case 'jwks':\n discovery.jwks_uri = value;\n break;\n case 'security':\n discovery.security_contact = value;\n break;\n }\n }\n }\n\n // Validate required fields\n if (!discovery.version) throw new Error('Missing required field: version');\n if (!discovery.issuer) throw new Error('Missing required field: issuer');\n if (!discovery.verify_endpoint) throw new Error('Missing required field: verify');\n if (!discovery.jwks_uri) throw new Error('Missing required field: jwks');\n\n return discovery as PEACDiscovery;\n}\n\n/**\n * @deprecated Use fetchIssuerConfig instead. Will be removed in v1.0.\n *\n * Fetch and parse PEAC discovery from an issuer URL.\n * This function is maintained for backward compatibility only.\n */\nexport async function fetchDiscovery(issuerUrl: string): Promise<PEACDiscovery> {\n if (!issuerUrl.startsWith('https://')) {\n throw new Error('Issuer URL must be https://');\n }\n\n const discoveryUrl = `${issuerUrl}/.well-known/peac.txt`;\n\n try {\n const resp = await fetch(discoveryUrl, {\n headers: { Accept: 'text/plain' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (!resp.ok) {\n throw new Error(`Discovery fetch failed: ${resp.status}`);\n }\n\n const text = await resp.text();\n return parseDiscovery(text);\n } catch (err) {\n throw new Error(\n `Failed to fetch discovery from ${issuerUrl}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err }\n );\n }\n}\n","/**\n * PEAC Verifier Types\n *\n * Types for verification policy, trust pinning, and verification reports\n * per VERIFIER-SECURITY-MODEL.md, TRUST-PINNING-POLICY.md, and\n * VERIFICATION-REPORT-FORMAT.md\n *\n * @packageDocumentation\n */\n\nimport {\n VERIFIER_LIMITS,\n VERIFIER_NETWORK,\n VERIFIER_POLICY_VERSION,\n VERIFICATION_REPORT_VERSION,\n} from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Policy Binding (DD-49)\n// ---------------------------------------------------------------------------\n\n/**\n * Three-state policy binding status (DD-49)\n *\n * - 'verified': Policy digest in receipt matches local policy bytes (Wire 0.2+)\n * - 'failed': Policy digest mismatch (Wire 0.2+)\n * - 'unavailable': No policy digest in receipt or no policy bytes available.\n * Always 'unavailable' for Wire 0.1 receipts.\n */\nexport type PolicyBindingStatus = 'verified' | 'failed' | 'unavailable';\n\n// ---------------------------------------------------------------------------\n// Verification Mode\n// ---------------------------------------------------------------------------\n\n/**\n * Verification mode per VERIFIER-SECURITY-MODEL.md\n */\nexport type VerificationMode = 'offline_only' | 'offline_preferred' | 'network_allowed';\n\n// ---------------------------------------------------------------------------\n// Trust Pinning\n// ---------------------------------------------------------------------------\n\n/**\n * Pinned key entry per TRUST-PINNING-POLICY.md\n *\n * Uses RFC 7638 JWK Thumbprint with base64url encoding (NOT hex).\n * SHA-256 thumbprints are 43 characters in base64url.\n *\n * For offline verification, include either `public_key` (base64url 32 bytes)\n * or the full `jwk` object. If only thumbprint is provided, the key can only\n * be pin-checked after fetching JWKS (requires network mode).\n */\nexport interface PinnedKey {\n /** Issuer origin (https://host[:port]) */\n issuer: string;\n /** Key identifier (kid from JWKS) */\n kid: string;\n /** RFC 7638 JWK Thumbprint, SHA-256, base64url-encoded (43 chars) */\n jwk_thumbprint_sha256: string;\n /**\n * Ed25519 public key bytes, base64url-encoded (43 chars for 32 bytes).\n * If provided, enables offline verification without JWKS fetch.\n */\n public_key?: string;\n /**\n * Full JWK for offline verification.\n * If provided, enables offline verification without JWKS fetch.\n * Takes precedence over public_key.\n */\n jwk?: {\n kty: 'OKP';\n crv: 'Ed25519';\n x: string;\n kid?: string;\n };\n}\n\n/**\n * Issuer allowlist entry\n *\n * Full origin format: https://host[:port]\n * The port is only included if non-standard (not 443 for HTTPS).\n */\nexport type IssuerOrigin = string;\n\n// ---------------------------------------------------------------------------\n// Verifier Limits\n// ---------------------------------------------------------------------------\n\n/**\n * Verifier security limits\n */\nexport interface VerifierLimits {\n /** Maximum receipt size in bytes */\n max_receipt_bytes: number;\n /** Maximum JWKS document size in bytes */\n max_jwks_bytes: number;\n /** Maximum number of keys in a JWKS */\n max_jwks_keys: number;\n /** Maximum redirects to follow */\n max_redirects: number;\n /** Network fetch timeout in milliseconds */\n fetch_timeout_ms: number;\n /** Maximum extension size in bytes */\n max_extension_bytes: number;\n}\n\n/**\n * Default verifier limits from VERIFIER-SECURITY-MODEL.md\n */\nexport const DEFAULT_VERIFIER_LIMITS: VerifierLimits = {\n max_receipt_bytes: VERIFIER_LIMITS.maxReceiptBytes,\n max_jwks_bytes: VERIFIER_LIMITS.maxJwksBytes,\n max_jwks_keys: VERIFIER_LIMITS.maxJwksKeys,\n max_redirects: VERIFIER_LIMITS.maxRedirects,\n fetch_timeout_ms: VERIFIER_LIMITS.fetchTimeoutMs,\n max_extension_bytes: VERIFIER_LIMITS.maxExtensionBytes,\n};\n\n// ---------------------------------------------------------------------------\n// Network Security\n// ---------------------------------------------------------------------------\n\n/**\n * Network security settings\n */\nexport interface NetworkSecurity {\n /** Only allow HTTPS URLs */\n https_only: boolean;\n /** Block requests to private IP ranges */\n block_private_ips: boolean;\n /** Allow redirects */\n allow_redirects: boolean;\n /**\n * Allow cross-origin redirects (default: true for CDN compatibility).\n * When true, redirects to different origins are allowed if they pass SSRF checks.\n * When false, only same-origin redirects are allowed.\n */\n allow_cross_origin_redirects?: boolean;\n /**\n * Behavior on DNS resolution failure (default: 'block' for security).\n * - 'block': Treat DNS failure as blocked (fail-closed, more secure)\n * - 'fail': Return fetch error (allows retry, less restrictive)\n */\n dns_failure_behavior?: 'block' | 'fail';\n}\n\n/**\n * Default network security settings from VERIFIER-SECURITY-MODEL.md\n */\nexport const DEFAULT_NETWORK_SECURITY: NetworkSecurity = {\n https_only: VERIFIER_NETWORK.httpsOnly,\n block_private_ips: VERIFIER_NETWORK.blockPrivateIps,\n allow_redirects: VERIFIER_NETWORK.allowRedirects,\n allow_cross_origin_redirects: true, // Allow for CDN compatibility\n dns_failure_behavior: 'block', // Fail-closed by default\n};\n\n// ---------------------------------------------------------------------------\n// Verifier Policy\n// ---------------------------------------------------------------------------\n\n/**\n * Verifier policy configuration\n *\n * This structure echoes the policy used for verification, making trust\n * decisions auditable per VERIFICATION-REPORT-FORMAT.md.\n */\nexport interface VerifierPolicy {\n /** Policy schema version */\n policy_version: typeof VERIFIER_POLICY_VERSION;\n /** Verification mode */\n mode: VerificationMode;\n /** Allowed issuer origins (optional, if empty all issuers allowed) */\n issuer_allowlist?: IssuerOrigin[];\n /** Pinned keys for offline verification */\n pinned_keys?: PinnedKey[];\n /** Effective security limits */\n limits: VerifierLimits;\n /** Network security settings */\n network: NetworkSecurity;\n}\n\n/**\n * Create a default verifier policy\n */\nexport function createDefaultPolicy(mode: VerificationMode): VerifierPolicy {\n return {\n policy_version: VERIFIER_POLICY_VERSION,\n mode,\n limits: { ...DEFAULT_VERIFIER_LIMITS },\n network: { ...DEFAULT_NETWORK_SECURITY },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Verification Checks\n// ---------------------------------------------------------------------------\n\n/**\n * Check status\n */\nexport type CheckStatus = 'pass' | 'fail' | 'skip';\n\n/**\n * Standard check IDs per VERIFIER-SECURITY-MODEL.md (in order).\n *\n * APPEND-ONLY CONTRACT:\n * - New checks MUST only be appended to the end of this array.\n * - Existing entries MUST NOT be removed, reordered, or renamed.\n * - Downstream consumers (conformance fixtures, report builders, dashboards)\n * depend on stable indices and the `as const` tuple type.\n * - Breaking this contract invalidates all existing verification reports\n * and conformance vectors.\n * - Enforced by prefix-pinning test in verification-report.test.ts.\n *\n * OUTPUT ORDER vs EVALUATION ORDER:\n * This array defines the report output (render) order only. Verifier\n * implementations MAY evaluate checks in any order internally (e.g.,\n * checking signature before discovery). The report builder normalizes\n * results into this canonical order regardless of evaluation sequence.\n *\n * To add a new check:\n * 1. Append the new ID to the end of this array.\n * 2. Update the conformance fixture: specs/conformance/fixtures/verifier/verification-report.json\n * 3. Update the spec: docs/specs/VERIFICATION-REPORT-FORMAT.md (Section 5.5)\n * 4. Update the spec: docs/specs/VERIFIER-SECURITY-MODEL.md (Section 6.1)\n */\nexport const CHECK_IDS = [\n 'jws.parse',\n 'limits.receipt_bytes',\n 'jws.protected_header',\n 'claims.schema_unverified',\n 'issuer.trust_policy',\n 'issuer.discovery',\n 'key.resolve',\n 'jws.signature',\n 'claims.time_window',\n 'extensions.limits',\n 'transport.profile_binding',\n 'policy.binding',\n] as const;\n\nexport type CheckId = (typeof CHECK_IDS)[number];\n\n/**\n * Single verification check result\n */\nexport interface CheckResult {\n /** Stable check identifier */\n id: CheckId;\n /** Check status */\n status: CheckStatus;\n /** Machine-readable details (optional) */\n detail?: Record<string, unknown>;\n /** Stable error code (if failed) */\n error_code?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report Input\n// ---------------------------------------------------------------------------\n\n/**\n * Input type for verification\n */\nexport type InputType = 'receipt_jws' | 'bundle_entry';\n\n/**\n * Digest object (algorithm + value)\n */\nexport interface DigestObject {\n /** Hash algorithm */\n alg: 'sha-256';\n /** Hash value in lowercase hex */\n value: string;\n}\n\n/**\n * Bundle context for bundle_entry input type\n */\nexport interface BundleContext {\n /** Digest of bundle bytes */\n bundle_digest: DigestObject;\n /** 0-based entry index */\n entry_index: number;\n /** Stable entry ID (optional) */\n entry_id?: string;\n}\n\n/**\n * Verification input descriptor\n */\nexport interface VerificationInput {\n /** Input type */\n type: InputType;\n /** Digest of receipt bytes */\n receipt_digest: DigestObject;\n /** Bundle context (if type = bundle_entry) */\n bundle?: BundleContext;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report Result\n// ---------------------------------------------------------------------------\n\n/**\n * Result severity\n */\nexport type ResultSeverity = 'info' | 'warning' | 'error';\n\n/**\n * Reason codes per VERIFIER-SECURITY-MODEL.md\n */\nexport type ReasonCode =\n | 'ok'\n | 'receipt_too_large'\n | 'malformed_receipt'\n | 'signature_invalid'\n | 'issuer_not_allowed'\n | 'key_not_found'\n | 'key_fetch_blocked'\n | 'key_fetch_failed'\n | 'key_fetch_timeout'\n | 'pointer_fetch_blocked'\n | 'pointer_fetch_failed'\n | 'pointer_fetch_timeout'\n | 'pointer_fetch_too_large'\n | 'pointer_digest_mismatch'\n | 'jwks_too_large'\n | 'jwks_too_many_keys'\n | 'expired'\n | 'not_yet_valid'\n | 'audience_mismatch'\n | 'schema_invalid'\n | 'policy_violation'\n | 'extension_too_large'\n | 'invalid_transport';\n\n/**\n * High-level verification result\n */\nexport interface VerificationResult {\n /** Overall verification result */\n valid: boolean;\n /** Stable reason code */\n reason: ReasonCode;\n /** Result severity */\n severity: ResultSeverity;\n /** Receipt wire format (e.g., peac-receipt/0.1) */\n receipt_type: string;\n /** Normalized issuer origin (optional) */\n issuer?: string;\n /** Key ID used for verification (optional) */\n kid?: string;\n /**\n * Policy binding status (DD-49).\n *\n * Always 'unavailable' for Wire 0.1 receipts.\n * Wire 0.2+ receipts with `peac.policy.digest` will report 'verified' or 'failed'.\n *\n * This field is ALWAYS present (never undefined). Consumers can rely on it\n * without null checks.\n */\n policy_binding: PolicyBindingStatus;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report Artifacts\n// ---------------------------------------------------------------------------\n\n/**\n * Pointer resolution details\n */\nexport interface PointerArtifact {\n /** Pointer URL */\n url: string;\n /** Expected digest from header */\n expected_digest: DigestObject;\n /** Actual digest of fetched content */\n actual_digest?: DigestObject;\n /** Whether digests matched */\n digest_matched?: boolean;\n}\n\n/**\n * Key source for enterprise debuggability\n */\nexport type KeySource = 'pinned' | 'jwks_fetch';\n\n/**\n * Additional verification artifacts\n *\n * Artifacts are divided into two categories:\n *\n * **Deterministic artifacts** (same inputs and policy -> same values):\n * - `issuer_key_source`: Always determined by policy and receipt\n * - `issuer_key_thumbprint`: Computed from the signing key\n * - `normalized_claims_digest`: Computed from the claims\n * - `receipt_pointer`: Derived from the input pointer header\n *\n * **Non-deterministic artifacts** (may vary based on runtime state):\n * - `issuer_jwks_digest`: Only present when JWKS is fetched fresh (not from cache)\n *\n * Use `buildDeterministic()` to exclude non-deterministic artifacts for\n * reproducible report generation.\n */\nexport interface VerificationArtifacts {\n /**\n * Digest of JWKS used for verification.\n *\n * NON-DETERMINISTIC: Only present when JWKS is fetched fresh (not from cache).\n * Excluded by `buildDeterministic()`.\n */\n issuer_jwks_digest?: DigestObject;\n /** Source of the signing key used for verification (DETERMINISTIC) */\n issuer_key_source?: KeySource;\n /** RFC 7638 JWK Thumbprint (SHA-256, base64url) of the key used (DETERMINISTIC) */\n issuer_key_thumbprint?: string;\n /** Digest of canonicalized claims (DETERMINISTIC) */\n normalized_claims_digest?: DigestObject;\n /** Pointer resolution details (DETERMINISTIC) */\n receipt_pointer?: PointerArtifact;\n}\n\n/**\n * Keys of artifacts that are non-deterministic (depend on runtime state)\n */\nexport const NON_DETERMINISTIC_ARTIFACT_KEYS: (keyof VerificationArtifacts)[] = [\n 'issuer_jwks_digest',\n];\n\n// ---------------------------------------------------------------------------\n// Verification Report Meta\n// ---------------------------------------------------------------------------\n\n/**\n * Verifier implementation info\n */\nexport interface VerifierInfo {\n /** Verifier name */\n name: string;\n /** Verifier version */\n version: string;\n}\n\n/**\n * Non-deterministic metadata (MUST be excluded from report hashes)\n */\nexport interface VerificationMeta {\n /** RFC 3339 timestamp when report was generated */\n generated_at?: string;\n /** Verifier implementation info */\n verifier?: VerifierInfo;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report\n// ---------------------------------------------------------------------------\n\n/**\n * PEAC Verification Report per VERIFICATION-REPORT-FORMAT.md\n *\n * This report is designed to be:\n * - Portable: shareable across organizations\n * - Deterministic: reproducible given same inputs\n * - Safe: bounded resource usage\n * - Policy-aware: trust decisions are explicit\n */\nexport interface VerificationReport {\n /** Format version identifier (REQUIRED) */\n report_version: typeof VERIFICATION_REPORT_VERSION;\n /** What was verified (REQUIRED) */\n input: VerificationInput;\n /** Policy used for verification (REQUIRED) */\n policy: VerifierPolicy;\n /** High-level outcome (REQUIRED) */\n result: VerificationResult;\n /** Ordered list of checks (REQUIRED) */\n checks: CheckResult[];\n /** Additional outputs (OPTIONAL) */\n artifacts?: VerificationArtifacts;\n /** Non-deterministic fields (OPTIONAL, excluded from hashes) */\n meta?: VerificationMeta;\n}\n\n// ---------------------------------------------------------------------------\n// Report Builder Utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Create a digest object from a hex string\n */\nexport function createDigest(hexValue: string): DigestObject {\n return {\n alg: 'sha-256',\n value: hexValue.toLowerCase(),\n };\n}\n\n/**\n * Create an empty verification report structure\n */\nexport function createEmptyReport(\n policy: VerifierPolicy\n): Omit<VerificationReport, 'input' | 'result' | 'checks'> {\n return {\n report_version: VERIFICATION_REPORT_VERSION,\n policy,\n };\n}\n\n/**\n * Map SSRF fetch error reason to verification reason code\n */\nexport function ssrfErrorToReasonCode(\n ssrfReason: string,\n fetchType: 'key' | 'pointer'\n): ReasonCode {\n const prefix = fetchType === 'key' ? 'key_fetch' : 'pointer_fetch';\n\n switch (ssrfReason) {\n case 'not_https':\n case 'private_ip':\n case 'loopback':\n case 'link_local':\n case 'cross_origin_redirect':\n case 'dns_failure':\n return `${prefix}_blocked` as ReasonCode;\n case 'timeout':\n return `${prefix}_timeout` as ReasonCode;\n case 'response_too_large':\n return fetchType === 'pointer' ? 'pointer_fetch_too_large' : 'jwks_too_large';\n case 'jwks_too_many_keys':\n return 'jwks_too_many_keys';\n case 'too_many_redirects':\n case 'scheme_downgrade':\n case 'network_error':\n case 'invalid_url':\n default:\n return `${prefix}_failed` as ReasonCode;\n }\n}\n\n/**\n * Map reason code to severity\n */\nexport function reasonCodeToSeverity(reason: ReasonCode): ResultSeverity {\n if (reason === 'ok') return 'info';\n return 'error';\n}\n\n/**\n * Map reason code to error code\n */\nexport function reasonCodeToErrorCode(reason: ReasonCode): string {\n const mapping: Record<ReasonCode, string> = {\n ok: '',\n receipt_too_large: 'E_VERIFY_RECEIPT_TOO_LARGE',\n malformed_receipt: 'E_VERIFY_MALFORMED_RECEIPT',\n signature_invalid: 'E_VERIFY_SIGNATURE_INVALID',\n issuer_not_allowed: 'E_VERIFY_ISSUER_NOT_ALLOWED',\n key_not_found: 'E_VERIFY_KEY_NOT_FOUND',\n key_fetch_blocked: 'E_VERIFY_KEY_FETCH_BLOCKED',\n key_fetch_failed: 'E_VERIFY_KEY_FETCH_FAILED',\n key_fetch_timeout: 'E_VERIFY_KEY_FETCH_TIMEOUT',\n pointer_fetch_blocked: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n pointer_fetch_failed: 'E_VERIFY_POINTER_FETCH_FAILED',\n pointer_fetch_timeout: 'E_VERIFY_POINTER_FETCH_TIMEOUT',\n pointer_fetch_too_large: 'E_VERIFY_POINTER_FETCH_TOO_LARGE',\n pointer_digest_mismatch: 'E_VERIFY_POINTER_DIGEST_MISMATCH',\n jwks_too_large: 'E_VERIFY_JWKS_TOO_LARGE',\n jwks_too_many_keys: 'E_VERIFY_JWKS_TOO_MANY_KEYS',\n expired: 'E_VERIFY_EXPIRED',\n not_yet_valid: 'E_VERIFY_NOT_YET_VALID',\n audience_mismatch: 'E_VERIFY_AUDIENCE_MISMATCH',\n schema_invalid: 'E_VERIFY_SCHEMA_INVALID',\n policy_violation: 'E_VERIFY_POLICY_VIOLATION',\n extension_too_large: 'E_VERIFY_EXTENSION_TOO_LARGE',\n invalid_transport: 'E_VERIFY_INVALID_TRANSPORT',\n };\n return mapping[reason] || 'E_VERIFY_POLICY_VIOLATION';\n}\n","/**\n * SSRF-safe fetch utility for PEAC verifiers\n *\n * Implements SSRF protection per VERIFIER-SECURITY-MODEL.md:\n * - HTTPS only\n * - Block private IP ranges (RFC 1918)\n * - Block link-local addresses\n * - Block loopback addresses\n * - Redirect limits and scheme downgrade protection\n *\n * ## Security Model: Best-Effort Protection\n *\n * **IMPORTANT**: SSRF protection is BEST-EFFORT, not a guarantee. The level of\n * protection depends on the runtime environment's capabilities. In environments\n * without DNS pre-resolution (browsers, edge workers), protection is limited to\n * URL scheme validation and response limits. Defense-in-depth: combine with\n * network-level controls (firewalls, egress filtering) in production.\n *\n * ## Hard Invariants (ALWAYS Enforced)\n *\n * These protections are enforced in ALL runtimes:\n *\n * | Invariant | Enforcement |\n * |-----------|-------------|\n * | HTTPS only | URL scheme validation before fetch |\n * | No redirects (pointer fetch) | `redirect: 'manual'` + policy check |\n * | Response size cap | Streaming with byte counter, abort on limit |\n * | Timeout | AbortController with configurable timeout |\n * | No scheme downgrade | Redirect target scheme validation |\n *\n * ## Runtime-Dependent Protections\n *\n * These protections require DNS pre-resolution capability:\n *\n * | Protection | Requires |\n * |------------|----------|\n * | Private IP blocking (RFC 1918) | DNS pre-resolution |\n * | Loopback blocking (127.0.0.0/8) | DNS pre-resolution |\n * | Link-local blocking (169.254.0.0/16) | DNS pre-resolution |\n *\n * ## Runtime Capability Model\n *\n * SSRF protection capabilities vary by runtime environment:\n *\n * | Runtime | DNS Pre-Resolution | IP Blocking | Notes |\n * |-------------------|-------------------|-------------|-------|\n * | Node.js | YES | YES | Full protection via dns module |\n * | Browser | NO | NO | Relies on server-side validation |\n * | Cloudflare Workers| NO | NO | No DNS access, relies on CF network |\n * | Deno | NO | NO | dns module not available by default |\n * | Bun | YES | YES | Compatible with Node.js dns module |\n *\n * Use `getSSRFCapabilities()` to detect runtime capabilities.\n *\n * @packageDocumentation\n */\n\nimport { VERIFIER_LIMITS, VERIFIER_NETWORK } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// SSRF Capability Model\n// ---------------------------------------------------------------------------\n\n/**\n * Runtime environment where SSRF protection is running\n */\nexport type SSRFRuntime =\n | 'node'\n | 'bun'\n | 'deno'\n | 'browser'\n | 'cloudflare-workers'\n | 'edge-generic'\n | 'unknown';\n\n/**\n * SSRF protection capabilities available in the current runtime\n *\n * These capabilities determine what security measures can be applied:\n * - `dnsPreResolution`: Can resolve hostnames to IPs before connecting\n * - `ipBlocking`: Can inspect and block connections based on resolved IPs\n * - `networkIsolation`: Runtime provides network-level isolation (e.g., CF Workers)\n *\n * When `dnsPreResolution` is false, SSRF protection is limited to:\n * - URL scheme validation (HTTPS only)\n * - Hostname pattern matching (if configured)\n * - Response size limits\n * - Timeout enforcement\n *\n * This is a defense-in-depth model: even without DNS pre-resolution,\n * multiple layers of protection remain active.\n */\nexport interface SSRFCapabilities {\n /** Detected runtime environment */\n runtime: SSRFRuntime;\n /** Can resolve DNS before making HTTP connection */\n dnsPreResolution: boolean;\n /** Can block connections based on resolved IP addresses */\n ipBlocking: boolean;\n /** Runtime provides network-level isolation */\n networkIsolation: boolean;\n /** Human-readable description of protection level */\n protectionLevel: 'full' | 'partial' | 'minimal';\n /** Advisory notes for operators */\n notes: string[];\n}\n\n/**\n * Cached capabilities (detected once per process)\n */\nlet cachedCapabilities: SSRFCapabilities | null = null;\n\n/**\n * Detect SSRF protection capabilities for the current runtime\n *\n * This function performs runtime detection and returns a capability object\n * that describes what SSRF protections are available.\n *\n * @returns SSRF capabilities for the current runtime\n *\n * @example\n * ```typescript\n * const caps = getSSRFCapabilities();\n * if (!caps.dnsPreResolution) {\n * console.warn('Running without DNS pre-resolution; SSRF protection is limited');\n * }\n * ```\n */\nexport function getSSRFCapabilities(): SSRFCapabilities {\n if (cachedCapabilities) {\n return cachedCapabilities;\n }\n\n cachedCapabilities = detectCapabilities();\n return cachedCapabilities;\n}\n\n/**\n * Internal: Detect runtime capabilities\n */\nfunction detectCapabilities(): SSRFCapabilities {\n // Check for Node.js\n if (typeof process !== 'undefined' && process.versions?.node) {\n return {\n runtime: 'node',\n dnsPreResolution: true,\n ipBlocking: true,\n networkIsolation: false,\n protectionLevel: 'full',\n notes: [\n 'Full SSRF protection available via Node.js dns module',\n 'DNS resolution checked before HTTP connection',\n 'All RFC 1918 private ranges blocked',\n ],\n };\n }\n\n // Check for Bun\n if (typeof process !== 'undefined' && process.versions?.bun) {\n return {\n runtime: 'bun',\n dnsPreResolution: true,\n ipBlocking: true,\n networkIsolation: false,\n protectionLevel: 'full',\n notes: [\n 'Full SSRF protection available via Bun dns compatibility',\n 'DNS resolution checked before HTTP connection',\n ],\n };\n }\n\n // Check for Deno\n if (typeof globalThis !== 'undefined' && 'Deno' in globalThis) {\n return {\n runtime: 'deno',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: false,\n protectionLevel: 'partial',\n notes: [\n 'DNS pre-resolution not available in Deno by default',\n 'SSRF protection limited to URL validation and response limits',\n 'Consider using Deno.connect with hostname resolution for enhanced protection',\n ],\n };\n }\n\n // Check for Cloudflare Workers\n if (\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as Record<string, unknown>).caches !== 'undefined' &&\n typeof (globalThis as Record<string, unknown>).HTMLRewriter !== 'undefined'\n ) {\n return {\n runtime: 'cloudflare-workers',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: true,\n protectionLevel: 'partial',\n notes: [\n 'Cloudflare Workers provide network-level isolation',\n 'DNS pre-resolution not available in Workers runtime',\n 'CF network blocks many SSRF vectors at infrastructure level',\n 'SSRF protection supplemented by URL validation and response limits',\n ],\n };\n }\n\n // Check for browser environment\n // Use globalThis to avoid DOM type references\n const g = globalThis as Record<string, unknown>;\n if (typeof g.window !== 'undefined' || typeof g.document !== 'undefined') {\n return {\n runtime: 'browser',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: false,\n protectionLevel: 'minimal',\n notes: [\n 'Browser environment detected; DNS pre-resolution not available',\n 'SSRF protection limited to URL scheme validation',\n 'Consider validating URLs server-side before browser fetch',\n 'Same-origin policy provides some protection against SSRF',\n ],\n };\n }\n\n // Generic edge runtime\n return {\n runtime: 'edge-generic',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: false,\n protectionLevel: 'partial',\n notes: [\n 'Edge runtime detected; DNS pre-resolution may not be available',\n 'SSRF protection limited to URL validation and response limits',\n 'Verify runtime provides additional network-level protections',\n ],\n };\n}\n\n/**\n * Reset cached capabilities (for testing)\n * @internal\n */\nexport function resetSSRFCapabilitiesCache(): void {\n cachedCapabilities = null;\n}\n\n/**\n * SSRF fetch options\n */\nexport interface SSRFFetchOptions {\n /** Timeout in milliseconds (default: VERIFIER_LIMITS.fetchTimeoutMs) */\n timeoutMs?: number;\n /** Maximum response size in bytes (default: VERIFIER_LIMITS.maxResponseBytes) */\n maxBytes?: number;\n /** Maximum redirects to follow (default: 0 for SSRF safety) */\n maxRedirects?: number;\n /** Allow redirects (default: VERIFIER_NETWORK.allowRedirects) */\n allowRedirects?: boolean;\n /**\n * Allow cross-origin redirects (default: true for CDN compatibility).\n * When true, redirects to different origins are allowed if the target passes SSRF checks.\n * When false, redirects must stay within the same origin.\n */\n allowCrossOriginRedirects?: boolean;\n /**\n * How to handle DNS resolution failures (default: 'block' for fail-closed security).\n * - 'block': Treat DNS failure as blocked (fail-closed, recommended)\n * - 'fail': Return network_error and allow caller to decide\n */\n dnsFailureBehavior?: 'block' | 'fail';\n /** Custom headers to include */\n headers?: Record<string, string>;\n}\n\n/**\n * SSRF fetch result\n */\nexport interface SSRFFetchResult {\n /** Whether the fetch succeeded */\n ok: true;\n /** Response status code */\n status: number;\n /** Response body as string */\n body: string;\n /**\n * Raw response bytes for digest computation.\n * Use this for computing digests to avoid encoding round-trip issues.\n */\n rawBytes: Uint8Array;\n /** Response content type */\n contentType?: string;\n}\n\n/**\n * SSRF fetch error\n */\nexport interface SSRFFetchError {\n /** Fetch failed */\n ok: false;\n /** Error reason code */\n reason:\n | 'invalid_url'\n | 'not_https'\n | 'private_ip'\n | 'loopback'\n | 'link_local'\n | 'dns_failure'\n | 'too_many_redirects'\n | 'scheme_downgrade'\n | 'cross_origin_redirect'\n | 'timeout'\n | 'response_too_large'\n | 'jwks_too_many_keys'\n | 'network_error';\n /** Human-readable error message */\n message: string;\n /** Blocked URL (if applicable) */\n blockedUrl?: string;\n}\n\n/**\n * IPv4 address parsed into components\n */\ninterface IPv4Address {\n octets: [number, number, number, number];\n}\n\n/**\n * Parse an IPv4 address string into octets\n */\nfunction parseIPv4(ip: string): IPv4Address | null {\n const parts = ip.split('.');\n if (parts.length !== 4) return null;\n\n const octets: number[] = [];\n for (const part of parts) {\n const num = parseInt(part, 10);\n if (isNaN(num) || num < 0 || num > 255) return null;\n octets.push(num);\n }\n\n return { octets: octets as [number, number, number, number] };\n}\n\n/**\n * Check if an IPv4 address is in a CIDR range\n */\nfunction isInCIDR(ip: IPv4Address, cidr: string): boolean {\n const [rangeStr, maskStr] = cidr.split('/');\n const range = parseIPv4(rangeStr);\n if (!range) return false;\n\n const maskBits = parseInt(maskStr, 10);\n if (isNaN(maskBits) || maskBits < 0 || maskBits > 32) return false;\n\n // Convert to 32-bit integers\n const ipNum = (ip.octets[0] << 24) | (ip.octets[1] << 16) | (ip.octets[2] << 8) | ip.octets[3];\n const rangeNum =\n (range.octets[0] << 24) | (range.octets[1] << 16) | (range.octets[2] << 8) | range.octets[3];\n\n // Create mask\n const mask = maskBits === 0 ? 0 : ~((1 << (32 - maskBits)) - 1);\n\n return (ipNum & mask) === (rangeNum & mask);\n}\n\n/**\n * Check if an IPv6 address is loopback (::1)\n */\nfunction isIPv6Loopback(ip: string): boolean {\n const normalized = ip.toLowerCase().replace(/^::ffff:/, '');\n return normalized === '::1' || normalized === '0:0:0:0:0:0:0:1';\n}\n\n/**\n * Check if an IPv6 address is link-local (fe80::/10)\n */\nfunction isIPv6LinkLocal(ip: string): boolean {\n const normalized = ip.toLowerCase();\n return (\n normalized.startsWith('fe8') ||\n normalized.startsWith('fe9') ||\n normalized.startsWith('fea') ||\n normalized.startsWith('feb')\n );\n}\n\n/**\n * Check if an IP address is private/blocked\n */\nexport function isBlockedIP(\n ip: string\n): { blocked: true; reason: 'private_ip' | 'loopback' | 'link_local' } | { blocked: false } {\n // Handle IPv4-mapped IPv6 addresses\n const ipv4Match = ip.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/i);\n const effectiveIP = ipv4Match ? ipv4Match[1] : ip;\n\n // Check IPv4\n const ipv4 = parseIPv4(effectiveIP);\n if (ipv4) {\n // RFC 1918 private ranges\n if (\n isInCIDR(ipv4, '10.0.0.0/8') ||\n isInCIDR(ipv4, '172.16.0.0/12') ||\n isInCIDR(ipv4, '192.168.0.0/16')\n ) {\n return { blocked: true, reason: 'private_ip' };\n }\n\n // Loopback\n if (isInCIDR(ipv4, '127.0.0.0/8')) {\n return { blocked: true, reason: 'loopback' };\n }\n\n // Link-local\n if (isInCIDR(ipv4, '169.254.0.0/16')) {\n return { blocked: true, reason: 'link_local' };\n }\n\n return { blocked: false };\n }\n\n // Check IPv6\n if (isIPv6Loopback(ip)) {\n return { blocked: true, reason: 'loopback' };\n }\n if (isIPv6LinkLocal(ip)) {\n return { blocked: true, reason: 'link_local' };\n }\n\n return { blocked: false };\n}\n\n/**\n * DNS resolution result\n */\ninterface DNSResolutionResult {\n /** Whether resolution succeeded */\n ok: true;\n /** Resolved IP addresses */\n ips: string[];\n /** Whether this is a browser environment (no pre-resolution possible) */\n browser: boolean;\n}\n\n/**\n * DNS resolution failure\n */\ninterface DNSResolutionFailure {\n /** Resolution failed */\n ok: false;\n /** Error message */\n message: string;\n}\n\n/**\n * Resolve hostname to IP addresses (platform-specific)\n *\n * In Node.js environments, this uses dns.resolve.\n * In browser environments, we cannot check IPs before fetch.\n */\nasync function resolveHostname(\n hostname: string\n): Promise<DNSResolutionResult | DNSResolutionFailure> {\n // Node.js environment detection\n if (typeof process !== 'undefined' && process.versions?.node) {\n try {\n const dns = await import('dns');\n const { promisify } = await import('util');\n const resolve4 = promisify(dns.resolve4);\n const resolve6 = promisify(dns.resolve6);\n\n const results: string[] = [];\n let ipv4Error: Error | null = null;\n let ipv6Error: Error | null = null;\n\n try {\n const ipv4 = await resolve4(hostname);\n results.push(...ipv4);\n } catch (err) {\n ipv4Error = err as Error;\n }\n\n try {\n const ipv6 = await resolve6(hostname);\n results.push(...ipv6);\n } catch (err) {\n ipv6Error = err as Error;\n }\n\n // If we got at least one result, resolution succeeded\n if (results.length > 0) {\n return { ok: true, ips: results, browser: false };\n }\n\n // Both failed - this is a DNS failure\n if (ipv4Error && ipv6Error) {\n return {\n ok: false,\n message: `DNS resolution failed for ${hostname}: ${ipv4Error.message}`,\n };\n }\n\n // No results but no errors either (unlikely)\n return { ok: true, ips: [], browser: false };\n } catch (err) {\n // DNS module import failed or other error\n return {\n ok: false,\n message: `DNS resolution error: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n\n // Browser environment: cannot pre-resolve, return empty\n // SSRF check will rely on server-side validation\n return { ok: true, ips: [], browser: true };\n}\n\n/**\n * Perform an SSRF-safe fetch\n *\n * This function implements the SSRF protection algorithm from VERIFIER-SECURITY-MODEL.md:\n * 1. Parse URL; reject if not https://\n * 2. Resolve hostname to IP(s)\n * 3. For each IP: reject if private, link-local, or loopback\n * 4. Perform fetch with timeout\n * 5. On redirect: increment counter, reject if > max, apply checks to redirect URL\n * 6. Validate response size\n *\n * @param url - URL to fetch (must be https://)\n * @param options - Fetch options\n * @returns Fetch result or error\n */\nexport async function ssrfSafeFetch(\n url: string,\n options: SSRFFetchOptions = {}\n): Promise<SSRFFetchResult | SSRFFetchError> {\n const {\n timeoutMs = VERIFIER_LIMITS.fetchTimeoutMs,\n maxBytes = VERIFIER_LIMITS.maxResponseBytes,\n maxRedirects = 0,\n allowRedirects = VERIFIER_NETWORK.allowRedirects,\n allowCrossOriginRedirects = true, // Default: allow for CDN compatibility\n dnsFailureBehavior = 'block', // Default: fail-closed for security\n headers = {},\n } = options;\n\n // Step 1: Parse and validate URL\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(url);\n } catch {\n return {\n ok: false,\n reason: 'invalid_url',\n message: `Invalid URL: ${url}`,\n blockedUrl: url,\n };\n }\n\n // Step 1b: Require HTTPS\n if (parsedUrl.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'not_https',\n message: `URL must use HTTPS: ${url}`,\n blockedUrl: url,\n };\n }\n\n // Step 2: Resolve hostname to IPs\n const dnsResult = await resolveHostname(parsedUrl.hostname);\n\n // Step 2b: Handle DNS resolution failure (fail-closed by default)\n if (!dnsResult.ok) {\n if (dnsFailureBehavior === 'block') {\n return {\n ok: false,\n reason: 'dns_failure',\n message: `DNS resolution blocked: ${dnsResult.message}`,\n blockedUrl: url,\n };\n }\n // dnsFailureBehavior === 'fail': return network_error\n return {\n ok: false,\n reason: 'network_error',\n message: dnsResult.message,\n blockedUrl: url,\n };\n }\n\n // Step 3: Check each resolved IP (if not browser environment)\n if (!dnsResult.browser) {\n for (const ip of dnsResult.ips) {\n const blockResult = isBlockedIP(ip);\n if (blockResult.blocked) {\n return {\n ok: false,\n reason: blockResult.reason,\n message: `Blocked ${blockResult.reason} address: ${ip} for ${url}`,\n blockedUrl: url,\n };\n }\n }\n }\n\n // Step 4: Perform fetch with timeout\n let redirectCount = 0;\n let currentUrl = url;\n const originalOrigin = parsedUrl.origin;\n\n while (true) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n const response = await fetch(currentUrl, {\n headers: {\n Accept: 'application/json, text/plain',\n ...headers,\n },\n signal: controller.signal,\n redirect: 'manual', // Handle redirects manually for security\n });\n\n clearTimeout(timeoutId);\n\n // Step 5: Handle redirects\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location');\n\n if (!location) {\n return {\n ok: false,\n reason: 'network_error',\n message: `Redirect without Location header from ${currentUrl}`,\n };\n }\n\n // Check redirect policy\n if (!allowRedirects) {\n return {\n ok: false,\n reason: 'too_many_redirects',\n message: `Redirects not allowed: ${currentUrl} -> ${location}`,\n blockedUrl: location,\n };\n }\n\n // Increment redirect counter\n redirectCount++;\n if (redirectCount > maxRedirects) {\n return {\n ok: false,\n reason: 'too_many_redirects',\n message: `Too many redirects (${redirectCount} > ${maxRedirects})`,\n blockedUrl: location,\n };\n }\n\n // Resolve redirect URL\n let redirectUrl: URL;\n try {\n redirectUrl = new URL(location, currentUrl);\n } catch {\n return {\n ok: false,\n reason: 'invalid_url',\n message: `Invalid redirect URL: ${location}`,\n blockedUrl: location,\n };\n }\n\n // Check for scheme downgrade (https -> http)\n if (redirectUrl.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'scheme_downgrade',\n message: `HTTPS to HTTP downgrade not allowed: ${currentUrl} -> ${redirectUrl.href}`,\n blockedUrl: redirectUrl.href,\n };\n }\n\n // Check for cross-origin redirects (configurable for CDN compatibility)\n if (redirectUrl.origin !== originalOrigin && !allowCrossOriginRedirects) {\n return {\n ok: false,\n reason: 'cross_origin_redirect',\n message: `Cross-origin redirect not allowed: ${originalOrigin} -> ${redirectUrl.origin}`,\n blockedUrl: redirectUrl.href,\n };\n }\n\n // Check redirect target IPs (DNS resolution + SSRF checks)\n const redirectDnsResult = await resolveHostname(redirectUrl.hostname);\n\n // Handle DNS failure for redirect target\n if (!redirectDnsResult.ok) {\n if (dnsFailureBehavior === 'block') {\n return {\n ok: false,\n reason: 'dns_failure',\n message: `Redirect DNS resolution blocked: ${redirectDnsResult.message}`,\n blockedUrl: redirectUrl.href,\n };\n }\n return {\n ok: false,\n reason: 'network_error',\n message: redirectDnsResult.message,\n blockedUrl: redirectUrl.href,\n };\n }\n\n // Check redirect target IPs for SSRF (if not browser environment)\n if (!redirectDnsResult.browser) {\n for (const ip of redirectDnsResult.ips) {\n const blockResult = isBlockedIP(ip);\n if (blockResult.blocked) {\n return {\n ok: false,\n reason: blockResult.reason,\n message: `Redirect to blocked ${blockResult.reason} address: ${ip}`,\n blockedUrl: redirectUrl.href,\n };\n }\n }\n }\n\n currentUrl = redirectUrl.href;\n continue;\n }\n\n // Step 6: Validate response size\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > maxBytes) {\n return {\n ok: false,\n reason: 'response_too_large',\n message: `Response too large: ${contentLength} bytes > ${maxBytes} max`,\n };\n }\n\n // Read response body with size limit\n const reader = response.body?.getReader();\n if (!reader) {\n const body = await response.text();\n if (body.length > maxBytes) {\n return {\n ok: false,\n reason: 'response_too_large',\n message: `Response too large: ${body.length} bytes > ${maxBytes} max`,\n };\n }\n // Convert body back to bytes for rawBytes (fallback path)\n const rawBytes = new TextEncoder().encode(body);\n return {\n ok: true,\n status: response.status,\n body,\n rawBytes,\n contentType: response.headers.get('content-type') ?? undefined,\n };\n }\n\n // Stream with size limit\n const chunks: Uint8Array[] = [];\n let totalSize = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalSize += value.length;\n if (totalSize > maxBytes) {\n reader.cancel();\n return {\n ok: false,\n reason: 'response_too_large',\n message: `Response too large: ${totalSize} bytes > ${maxBytes} max`,\n };\n }\n\n chunks.push(value);\n }\n\n // Concatenate chunks into raw bytes (preserve original bytes for digest)\n const rawBytes = chunks.reduce((acc, chunk) => {\n const result = new Uint8Array(acc.length + chunk.length);\n result.set(acc);\n result.set(chunk, acc.length);\n return result;\n }, new Uint8Array());\n\n // Decode to string for body\n const body = new TextDecoder().decode(rawBytes);\n\n return {\n ok: true,\n status: response.status,\n body,\n rawBytes,\n contentType: response.headers.get('content-type') ?? undefined,\n };\n } catch (err) {\n if (err instanceof Error) {\n if (err.name === 'AbortError' || err.message.includes('timeout')) {\n return {\n ok: false,\n reason: 'timeout',\n message: `Fetch timeout after ${timeoutMs}ms: ${currentUrl}`,\n };\n }\n }\n\n return {\n ok: false,\n reason: 'network_error',\n message: `Network error: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n}\n\n/**\n * Convenience function to fetch JWKS with SSRF protection\n */\nexport async function fetchJWKSSafe(\n jwksUrl: string,\n options?: Omit<SSRFFetchOptions, 'maxBytes'>\n): Promise<SSRFFetchResult | SSRFFetchError> {\n return ssrfSafeFetch(jwksUrl, {\n ...options,\n maxBytes: VERIFIER_LIMITS.maxJwksBytes,\n headers: {\n Accept: 'application/json',\n ...options?.headers,\n },\n });\n}\n\n/**\n * Convenience function to fetch pointer target with SSRF protection\n */\nexport async function fetchPointerSafe(\n pointerUrl: string,\n options?: Omit<SSRFFetchOptions, 'maxBytes'>\n): Promise<SSRFFetchResult | SSRFFetchError> {\n return ssrfSafeFetch(pointerUrl, {\n ...options,\n maxBytes: VERIFIER_LIMITS.maxReceiptBytes,\n headers: {\n Accept: 'application/jose, application/json',\n ...options?.headers,\n },\n });\n}\n","/**\n * PEAC Verification Report Builder\n *\n * Constructs deterministic verification reports per VERIFICATION-REPORT-FORMAT.md.\n * Reports are designed to be portable, deterministic, safe, and policy-aware.\n *\n * @packageDocumentation\n */\n\nimport { sha256Hex } from '@peac/crypto';\nimport { VERIFICATION_REPORT_VERSION, WIRE_TYPE } from '@peac/kernel';\nimport type {\n CheckId,\n CheckResult,\n CheckStatus,\n DigestObject,\n ReasonCode,\n VerificationArtifacts,\n VerificationInput,\n VerificationMeta,\n VerificationReport,\n VerificationResult,\n VerifierPolicy,\n} from './verifier-types.js';\nimport {\n CHECK_IDS,\n createDigest,\n NON_DETERMINISTIC_ARTIFACT_KEYS,\n reasonCodeToErrorCode,\n reasonCodeToSeverity,\n} from './verifier-types.js';\n\n/**\n * Report builder state\n */\ninterface ReportBuilderState {\n input?: VerificationInput;\n receiptDigestHex?: string;\n policy: VerifierPolicy;\n checks: Map<CheckId, CheckResult>;\n result?: VerificationResult;\n artifacts?: Record<string, unknown>;\n meta?: VerificationMeta;\n shortCircuited: boolean;\n failedAtCheck?: CheckId;\n}\n\n/**\n * Verification Report Builder\n *\n * Builds verification reports with proper check ordering and short-circuit behavior.\n * Ensures reports conform to VERIFICATION-REPORT-FORMAT.md requirements.\n *\n * Shape-stable: Always emits all checks with pass/fail/skip status.\n */\nexport class VerificationReportBuilder {\n private state: ReportBuilderState;\n\n constructor(policy: VerifierPolicy) {\n this.state = {\n policy,\n checks: new Map(),\n shortCircuited: false,\n };\n }\n\n /**\n * Set the input descriptor with pre-computed digest\n *\n * Use this when you've already computed the SHA-256 hash.\n *\n * @param digestHex - SHA-256 digest as lowercase hex (64 chars)\n * @param type - Input type\n */\n setInputWithDigest(\n digestHex: string,\n type: 'receipt_jws' | 'bundle_entry' = 'receipt_jws'\n ): this {\n this.state.receiptDigestHex = digestHex;\n this.state.input = {\n type,\n receipt_digest: createDigest(digestHex),\n };\n return this;\n }\n\n /**\n * Set the input descriptor (async - computes SHA-256)\n *\n * @param receiptBytes - Raw receipt bytes\n * @param type - Input type\n */\n async setInputAsync(\n receiptBytes: Uint8Array,\n type: 'receipt_jws' | 'bundle_entry' = 'receipt_jws'\n ): Promise<this> {\n const digestHex = await sha256Hex(receiptBytes);\n return this.setInputWithDigest(digestHex, type);\n }\n\n /**\n * Add a check result\n *\n * Checks can be added in any order; they will be sorted in build().\n * If a previous check failed, subsequent checks should be marked as skip.\n */\n addCheck(\n id: CheckId,\n status: CheckStatus,\n detail?: Record<string, unknown>,\n errorCode?: string\n ): this {\n const check: CheckResult = { id, status };\n if (detail && Object.keys(detail).length > 0) {\n check.detail = detail;\n }\n if (errorCode) {\n check.error_code = errorCode;\n }\n\n this.state.checks.set(id, check);\n\n // Track short-circuit on failure\n if (status === 'fail' && !this.state.shortCircuited) {\n this.state.shortCircuited = true;\n this.state.failedAtCheck = id;\n }\n\n return this;\n }\n\n /**\n * Add a passing check\n */\n pass(id: CheckId, detail?: Record<string, unknown>): this {\n return this.addCheck(id, 'pass', detail);\n }\n\n /**\n * Add a failing check\n */\n fail(id: CheckId, errorCode: string, detail?: Record<string, unknown>): this {\n return this.addCheck(id, 'fail', detail, errorCode);\n }\n\n /**\n * Add a skipped check\n */\n skip(id: CheckId, detail?: Record<string, unknown>): this {\n return this.addCheck(id, 'skip', detail);\n }\n\n /**\n * Set the final result\n */\n setResult(\n valid: boolean,\n reason: ReasonCode,\n options?: {\n issuer?: string;\n kid?: string;\n receiptType?: string;\n }\n ): this {\n this.state.result = {\n valid,\n reason,\n severity: reasonCodeToSeverity(reason),\n receipt_type: options?.receiptType ?? WIRE_TYPE,\n // Wire 0.1: always 'unavailable' (DD-49). Wire 0.2 will set this via options.\n policy_binding: 'unavailable',\n ...(options?.issuer && { issuer: options.issuer }),\n ...(options?.kid && { kid: options.kid }),\n };\n return this;\n }\n\n /**\n * Set success result\n */\n success(issuer: string, kid: string): this {\n return this.setResult(true, 'ok', { issuer, kid });\n }\n\n /**\n * Set failure result\n */\n failure(reason: ReasonCode, issuer?: string, kid?: string): this {\n return this.setResult(false, reason, { issuer, kid });\n }\n\n /**\n * Add artifacts\n */\n addArtifact(key: string, value: unknown): this {\n if (!this.state.artifacts) {\n this.state.artifacts = {};\n }\n this.state.artifacts[key] = value;\n return this;\n }\n\n /**\n * Set metadata (non-deterministic fields)\n */\n setMeta(meta: VerificationMeta): this {\n this.state.meta = meta;\n return this;\n }\n\n /**\n * Add current timestamp to meta\n */\n addTimestamp(): this {\n if (!this.state.meta) {\n this.state.meta = {};\n }\n this.state.meta.generated_at = new Date().toISOString();\n return this;\n }\n\n /**\n * Build the final report\n *\n * Ensures all checks are present (shape-stable).\n * Missing checks after a failure are marked as 'skip'.\n * Missing checks before a failure (or in success) are marked as 'pass'.\n */\n build(): VerificationReport {\n // Validate required fields\n if (!this.state.input) {\n throw new Error('Input is required. Call setInputWithDigest() or setInputAsync() first.');\n }\n if (!this.state.result) {\n throw new Error('Result is required. Call setResult() or success()/failure() first.');\n }\n\n // Build shape-stable checks array\n const checks: CheckResult[] = [];\n const failedIndex = this.state.failedAtCheck ? CHECK_IDS.indexOf(this.state.failedAtCheck) : -1;\n\n for (let i = 0; i < CHECK_IDS.length; i++) {\n const checkId = CHECK_IDS[i];\n const existing = this.state.checks.get(checkId);\n\n if (existing) {\n checks.push(existing);\n } else if (this.state.shortCircuited && i > failedIndex) {\n // After failure, missing checks are skipped\n checks.push({ id: checkId, status: 'skip', detail: { reason: 'short_circuit' } });\n } else {\n // Before failure or in success, missing checks get default status\n // For optional/deferred checks, mark as skip with appropriate reason\n if (checkId === 'transport.profile_binding') {\n checks.push({ id: checkId, status: 'skip', detail: { reason: 'not_applicable' } });\n } else if (checkId === 'policy.binding') {\n // Wire 0.1: always skip (DD-49). Wire 0.2 will produce pass/fail.\n checks.push({\n id: checkId,\n status: 'skip',\n detail: { reason: 'wire_01_no_policy_digest' },\n });\n } else {\n // This shouldn't happen in well-formed builds - indicates a bug\n checks.push({ id: checkId, status: 'skip', detail: { reason: 'not_executed' } });\n }\n }\n }\n\n const report: VerificationReport = {\n report_version: VERIFICATION_REPORT_VERSION,\n input: this.state.input,\n policy: this.state.policy,\n result: this.state.result,\n checks,\n };\n\n if (this.state.artifacts && Object.keys(this.state.artifacts).length > 0) {\n report.artifacts = this.state.artifacts as VerificationReport['artifacts'];\n }\n\n if (this.state.meta) {\n report.meta = this.state.meta;\n }\n\n return report;\n }\n\n /**\n * Build in deterministic mode (excludes meta and non-deterministic artifacts)\n *\n * Deterministic mode ensures that the same inputs and policy always produce\n * the same report output, regardless of cache state or timing.\n *\n * Excludes:\n * - `meta`: Contains timestamps and verifier info\n * - Non-deterministic artifacts: `issuer_jwks_digest` (depends on cache state)\n *\n * @returns Report without meta and with only deterministic artifacts\n */\n buildDeterministic(): Omit<VerificationReport, 'meta'> {\n const report = this.build();\n const { meta: _meta, ...deterministic } = report;\n\n // Filter out non-deterministic artifacts\n if (deterministic.artifacts) {\n const filteredArtifacts: Partial<VerificationArtifacts> = { ...deterministic.artifacts };\n for (const key of NON_DETERMINISTIC_ARTIFACT_KEYS) {\n delete filteredArtifacts[key];\n }\n\n // Remove artifacts object if empty after filtering\n if (Object.keys(filteredArtifacts).length === 0) {\n delete deterministic.artifacts;\n } else {\n deterministic.artifacts = filteredArtifacts as VerificationArtifacts;\n }\n }\n\n return deterministic;\n }\n}\n\n/**\n * Create a new report builder\n */\nexport function createReportBuilder(policy: VerifierPolicy): VerificationReportBuilder {\n return new VerificationReportBuilder(policy);\n}\n\n/**\n * Compute receipt digest for report input\n *\n * @param receiptBytes - Raw receipt bytes (JWS string as UTF-8)\n * @returns SHA-256 digest as lowercase hex (64 chars)\n */\nexport async function computeReceiptDigest(receiptBytes: Uint8Array | string): Promise<string> {\n const bytes =\n typeof receiptBytes === 'string' ? new TextEncoder().encode(receiptBytes) : receiptBytes;\n return sha256Hex(bytes);\n}\n\n/**\n * Build a quick failure report without going through all checks\n *\n * Useful for early failures like receipt_too_large or malformed_receipt\n * where most checks are skipped.\n */\nexport async function buildFailureReport(\n policy: VerifierPolicy,\n receiptBytes: Uint8Array | string,\n reason: ReasonCode,\n failedCheckId: CheckId,\n errorCode?: string,\n detail?: Record<string, unknown>,\n options?: {\n issuer?: string;\n kid?: string;\n meta?: VerificationMeta;\n }\n): Promise<VerificationReport> {\n const bytes =\n typeof receiptBytes === 'string' ? new TextEncoder().encode(receiptBytes) : receiptBytes;\n const digestHex = await sha256Hex(bytes);\n\n const builder = createReportBuilder(policy)\n .setInputWithDigest(digestHex)\n .failure(reason, options?.issuer, options?.kid);\n\n // Add passing checks up to the failure point\n const failedIndex = CHECK_IDS.indexOf(failedCheckId);\n for (let i = 0; i < CHECK_IDS.length; i++) {\n const checkId = CHECK_IDS[i];\n if (i < failedIndex) {\n builder.pass(checkId);\n } else if (i === failedIndex) {\n builder.fail(checkId, errorCode ?? reasonCodeToErrorCode(reason), detail);\n }\n // Remaining checks will be auto-skipped by build()\n }\n\n if (options?.meta) {\n builder.setMeta(options.meta);\n }\n\n return builder.build();\n}\n\n/**\n * Build a success report\n */\nexport async function buildSuccessReport(\n policy: VerifierPolicy,\n receiptBytes: Uint8Array | string,\n issuer: string,\n kid: string,\n checkDetails?: Partial<Record<CheckId, Record<string, unknown>>>,\n options?: {\n artifacts?: VerificationReport['artifacts'];\n meta?: VerificationMeta;\n }\n): Promise<VerificationReport> {\n const bytes =\n typeof receiptBytes === 'string' ? new TextEncoder().encode(receiptBytes) : receiptBytes;\n const digestHex = await sha256Hex(bytes);\n\n const builder = createReportBuilder(policy).setInputWithDigest(digestHex).success(issuer, kid);\n\n // Add all checks as passing (except optional ones)\n for (const checkId of CHECK_IDS) {\n // Skip issuer.discovery for offline mode\n if (checkId === 'issuer.discovery' && policy.mode === 'offline_only') {\n builder.skip(checkId, { reason: 'offline_mode' });\n continue;\n }\n\n // transport.profile_binding is optional\n if (checkId === 'transport.profile_binding') {\n if (checkDetails?.[checkId]) {\n builder.pass(checkId, checkDetails[checkId]);\n }\n // Will be marked as skip by build() if not added\n continue;\n }\n\n // policy.binding: Wire 0.1 always skip (DD-49)\n if (checkId === 'policy.binding') {\n // Will be marked as skip with wire_01_no_policy_digest by build()\n continue;\n }\n\n builder.pass(checkId, checkDetails?.[checkId]);\n }\n\n if (options?.artifacts) {\n for (const [key, value] of Object.entries(options.artifacts)) {\n builder.addArtifact(key, value);\n }\n }\n\n if (options?.meta) {\n builder.setMeta(options.meta);\n }\n\n return builder.build();\n}\n","/**\n * PEAC Verifier Core\n *\n * Implements the verification flow per VERIFIER-SECURITY-MODEL.md with:\n * - Ordered checks with short-circuit behavior\n * - Trust pinning (issuer allowlist + RFC 7638 thumbprints)\n * - SSRF-safe network fetches\n * - Deterministic verification reports\n *\n * @packageDocumentation\n */\n\nimport {\n base64urlDecode,\n computeJwkThumbprint,\n decode,\n jwkToPublicKeyBytes,\n sha256Hex,\n verify as jwsVerify,\n} from '@peac/crypto';\nimport { VERIFIER_LIMITS, WIRE_TYPE } from '@peac/kernel';\nimport { PEACReceiptClaims, ReceiptClaims } from '@peac/schema';\nimport type { SSRFFetchError } from './ssrf-safe-fetch.js';\nimport { fetchJWKSSafe, ssrfSafeFetch } from './ssrf-safe-fetch.js';\nimport { createReportBuilder } from './verification-report.js';\nimport type { PinnedKey, VerificationReport, VerifierPolicy } from './verifier-types.js';\nimport {\n createDefaultPolicy,\n createDigest,\n reasonCodeToErrorCode,\n ssrfErrorToReasonCode,\n} from './verifier-types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * JWK structure for Ed25519 keys\n */\ninterface JWK {\n kty: string;\n crv: string;\n x: string;\n kid: string;\n}\n\n/**\n * JWKS document\n */\ninterface JWKS {\n keys: JWK[];\n}\n\n/**\n * Issuer configuration document (/.well-known/peac-issuer.json)\n */\ninterface IssuerConfig {\n issuer: string;\n jwks_uri: string;\n}\n\n/**\n * Verification options for verifier-core\n */\nexport interface VerifyCoreOptions {\n /** Receipt JWS (compact serialization) or raw bytes */\n receipt: string | Uint8Array;\n /** Verification policy */\n policy?: VerifierPolicy;\n /** Reference time for deterministic verification (seconds since epoch) */\n referenceTime?: number;\n /** Include non-deterministic metadata in report */\n includeMeta?: boolean;\n}\n\n/**\n * Verification result\n */\nexport interface VerifyCoreResult {\n /** Whether verification succeeded */\n valid: boolean;\n /** Verification report */\n report: VerificationReport;\n /** Parsed claims (if valid) */\n claims?: PEACReceiptClaims;\n}\n\n// ---------------------------------------------------------------------------\n// Internal State\n// ---------------------------------------------------------------------------\n\n/**\n * JWKS cache entry\n */\ninterface JWKSCacheEntry {\n jwks: JWKS;\n expiresAt: number;\n}\n\n/**\n * In-memory JWKS cache (5 minute TTL)\n */\nconst jwksCache = new Map<string, JWKSCacheEntry>();\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\n// ---------------------------------------------------------------------------\n// Helper Functions\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize issuer to origin format (https://host[:port])\n */\nfunction normalizeIssuer(issuer: string): string {\n try {\n const url = new URL(issuer);\n // Include port only if non-standard for HTTPS\n if (url.port && url.port !== '443') {\n return `${url.protocol}//${url.hostname}:${url.port}`;\n }\n return `${url.protocol}//${url.hostname}`;\n } catch {\n return issuer;\n }\n}\n\n/**\n * Check if issuer is in the allowlist\n */\nfunction isIssuerAllowed(issuer: string, allowlist?: string[]): boolean {\n if (!allowlist || allowlist.length === 0) {\n // No allowlist means all issuers are allowed\n return true;\n }\n\n const normalized = normalizeIssuer(issuer);\n return allowlist.some((allowed) => normalizeIssuer(allowed) === normalized);\n}\n\n/**\n * Find pinned key for issuer and kid\n */\nfunction findPinnedKey(\n issuer: string,\n kid: string,\n pinnedKeys?: PinnedKey[]\n): PinnedKey | undefined {\n if (!pinnedKeys || pinnedKeys.length === 0) {\n return undefined;\n }\n\n const normalizedIssuer = normalizeIssuer(issuer);\n return pinnedKeys.find((pk) => normalizeIssuer(pk.issuer) === normalizedIssuer && pk.kid === kid);\n}\n\n/**\n * Fetch issuer configuration\n */\nasync function fetchIssuerConfig(issuerOrigin: string): Promise<IssuerConfig | null> {\n const configUrl = `${issuerOrigin}/.well-known/peac-issuer.json`;\n\n const result = await ssrfSafeFetch(configUrl, {\n maxBytes: 65536, // 64 KB\n headers: { Accept: 'application/json' },\n });\n\n if (!result.ok) {\n return null;\n }\n\n try {\n return JSON.parse(result.body) as IssuerConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * JWKS fetch result (success case)\n */\ninterface JWKSFetchSuccess {\n jwks: JWKS;\n fromCache: boolean;\n /** Raw JWKS bytes for digest computation (only present when not from cache) */\n rawBytes?: Uint8Array;\n}\n\n/**\n * Fetch JWKS from issuer\n */\nasync function fetchIssuerJWKS(\n issuerOrigin: string\n): Promise<JWKSFetchSuccess | { error: SSRFFetchError }> {\n const now = Date.now();\n\n // Check cache\n const cached = jwksCache.get(issuerOrigin);\n if (cached && cached.expiresAt > now) {\n return { jwks: cached.jwks, fromCache: true };\n }\n\n // Fetch issuer config first\n const config = await fetchIssuerConfig(issuerOrigin);\n if (!config?.jwks_uri) {\n // Fallback to well-known JWKS path\n const fallbackUrl = `${issuerOrigin}/.well-known/jwks.json`;\n const result = await fetchJWKSSafe(fallbackUrl);\n\n if (!result.ok) {\n return { error: result };\n }\n\n try {\n const jwks = JSON.parse(result.body) as JWKS;\n jwksCache.set(issuerOrigin, { jwks, expiresAt: now + CACHE_TTL_MS });\n return { jwks, fromCache: false, rawBytes: result.rawBytes };\n } catch {\n return {\n error: {\n ok: false,\n reason: 'network_error',\n message: 'Invalid JWKS JSON',\n } as SSRFFetchError,\n };\n }\n }\n\n // Fetch JWKS from discovered URI\n const result = await fetchJWKSSafe(config.jwks_uri);\n\n if (!result.ok) {\n return { error: result };\n }\n\n try {\n const jwks = JSON.parse(result.body) as JWKS;\n\n // Validate JWKS limits\n if (jwks.keys.length > VERIFIER_LIMITS.maxJwksKeys) {\n return {\n error: {\n ok: false,\n reason: 'jwks_too_many_keys',\n message: `JWKS has too many keys: ${jwks.keys.length} > ${VERIFIER_LIMITS.maxJwksKeys}`,\n } as SSRFFetchError,\n };\n }\n\n jwksCache.set(issuerOrigin, { jwks, expiresAt: now + CACHE_TTL_MS });\n return { jwks, fromCache: false, rawBytes: result.rawBytes };\n } catch {\n return {\n error: {\n ok: false,\n reason: 'network_error',\n message: 'Invalid JWKS JSON',\n } as SSRFFetchError,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main Verification Function\n// ---------------------------------------------------------------------------\n\n/**\n * Verify a PEAC receipt with full security checks and report emission\n *\n * Implements the verification flow per VERIFIER-SECURITY-MODEL.md:\n * 1. jws.parse - Parse JWS structure\n * 2. limits.receipt_bytes - Check receipt size\n * 3. jws.protected_header - Validate protected header\n * 4. claims.schema_unverified - Pre-signature schema check\n * 5. issuer.trust_policy - Check issuer allowlist/pins\n * 6. issuer.discovery - Fetch JWKS (if network mode)\n * 7. key.resolve - Resolve signing key by kid\n * 8. jws.signature - Verify signature\n * 9. claims.time_window - Check iat/exp\n * 10. extensions.limits - Check extension sizes\n */\nexport async function verifyReceiptCore(options: VerifyCoreOptions): Promise<VerifyCoreResult> {\n const {\n receipt,\n policy = createDefaultPolicy('offline_preferred'),\n referenceTime,\n includeMeta = false,\n } = options;\n\n // Convert receipt to string if needed\n const receiptJws = typeof receipt === 'string' ? receipt : new TextDecoder().decode(receipt);\n const receiptBytes = typeof receipt === 'string' ? new TextEncoder().encode(receipt) : receipt;\n\n // Compute receipt digest for report\n const receiptDigestHex = await sha256Hex(receiptBytes);\n\n // Start building report\n const builder = createReportBuilder(policy);\n builder.setInputWithDigest(receiptDigestHex);\n\n // Current time (or reference time for deterministic verification)\n const nowSeconds = referenceTime ?? Math.floor(Date.now() / 1000);\n\n // Track issuer and kid for result\n let issuer: string | undefined;\n let kid: string | undefined;\n let parsedClaims: PEACReceiptClaims | undefined;\n\n // ---------------------------------------------------------------------------\n // Check 1: jws.parse - Parse JWS structure\n // ---------------------------------------------------------------------------\n let header: { alg: string; typ: string; kid: string };\n let payload: PEACReceiptClaims;\n\n try {\n const decoded = decode<PEACReceiptClaims>(receiptJws);\n header = decoded.header;\n payload = decoded.payload;\n builder.pass('jws.parse');\n } catch (err) {\n builder.fail('jws.parse', 'E_VERIFY_MALFORMED_RECEIPT', {\n error: err instanceof Error ? err.message : String(err),\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // ---------------------------------------------------------------------------\n // Check 2: limits.receipt_bytes - Check receipt size\n // ---------------------------------------------------------------------------\n if (receiptBytes.length > policy.limits.max_receipt_bytes) {\n builder.fail('limits.receipt_bytes', 'E_VERIFY_RECEIPT_TOO_LARGE', {\n size: receiptBytes.length,\n limit: policy.limits.max_receipt_bytes,\n });\n builder.failure('receipt_too_large');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n builder.pass('limits.receipt_bytes', { size: receiptBytes.length });\n\n // ---------------------------------------------------------------------------\n // Check 3: jws.protected_header - Validate protected header\n // ---------------------------------------------------------------------------\n if (header.alg !== 'EdDSA') {\n builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {\n expected_alg: 'EdDSA',\n actual_alg: header.alg,\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n if (header.typ !== WIRE_TYPE) {\n builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {\n expected_typ: WIRE_TYPE,\n actual_typ: header.typ,\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n if (!header.kid) {\n builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {\n error: 'Missing kid in protected header',\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n kid = header.kid;\n builder.pass('jws.protected_header', { alg: header.alg, typ: header.typ, kid: header.kid });\n\n // ---------------------------------------------------------------------------\n // Check 4: claims.schema_unverified - Pre-signature schema check\n // ---------------------------------------------------------------------------\n try {\n ReceiptClaims.parse(payload);\n issuer = payload.iss;\n builder.pass('claims.schema_unverified');\n } catch (err) {\n builder.fail('claims.schema_unverified', 'E_VERIFY_SCHEMA_INVALID', {\n error: err instanceof Error ? err.message : String(err),\n });\n builder.failure('schema_invalid');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // ---------------------------------------------------------------------------\n // Check 5: issuer.trust_policy - Check issuer allowlist/pins\n // ---------------------------------------------------------------------------\n const normalizedIssuer = normalizeIssuer(issuer!);\n\n if (!isIssuerAllowed(issuer!, policy.issuer_allowlist)) {\n builder.fail('issuer.trust_policy', 'E_VERIFY_ISSUER_NOT_ALLOWED', {\n issuer: normalizedIssuer,\n allowlist: policy.issuer_allowlist,\n });\n builder.failure('issuer_not_allowed', normalizedIssuer, kid);\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n builder.pass('issuer.trust_policy', { issuer: normalizedIssuer });\n\n // ---------------------------------------------------------------------------\n // Check 6: issuer.discovery - Fetch JWKS (if network mode)\n // Check 7: key.resolve - Resolve signing key by kid\n // ---------------------------------------------------------------------------\n let publicKey: Uint8Array;\n let keySource: 'pinned_keys' | 'jwks_discovery';\n let keyThumbprint: string | undefined;\n let jwksRawBytes: Uint8Array | undefined;\n\n // Check for pinned key first\n const pinnedKey = findPinnedKey(issuer!, kid!, policy.pinned_keys);\n\n if (pinnedKey) {\n // Use pinned key - skip discovery\n builder.skip('issuer.discovery', { reason: 'pinned_key_available' });\n\n // Check if pinned key has key material for offline verification\n if (pinnedKey.jwk) {\n // Full JWK provided - verify thumbprint and use directly\n const actualThumbprint = await computeJwkThumbprint(pinnedKey.jwk);\n if (actualThumbprint !== pinnedKey.jwk_thumbprint_sha256) {\n builder.fail('key.resolve', 'E_VERIFY_POLICY_VIOLATION', {\n error: 'Pinned JWK thumbprint does not match declared thumbprint',\n expected: pinnedKey.jwk_thumbprint_sha256,\n actual: actualThumbprint,\n });\n builder.failure('policy_violation', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n publicKey = jwkToPublicKeyBytes(pinnedKey.jwk);\n keySource = 'pinned_keys';\n keyThumbprint = actualThumbprint;\n builder.pass('key.resolve', {\n source: keySource,\n kid,\n thumbprint_verified: true,\n offline: true,\n });\n } else if (pinnedKey.public_key) {\n // Raw public key bytes provided (base64url, 32 bytes for Ed25519)\n try {\n publicKey = base64urlDecode(pinnedKey.public_key);\n if (publicKey.length !== 32) {\n throw new Error(`Expected 32 bytes, got ${publicKey.length}`);\n }\n keySource = 'pinned_keys';\n // Note: We can't compute thumbprint from raw key bytes alone\n // The thumbprint is computed from canonical JWK JSON\n // Use the declared thumbprint from the pinned key entry\n keyThumbprint = pinnedKey.jwk_thumbprint_sha256;\n builder.pass('key.resolve', {\n source: keySource,\n kid,\n offline: true,\n thumbprint_verified: false,\n });\n } catch (err) {\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n error: `Invalid pinned public_key: ${err instanceof Error ? err.message : String(err)}`,\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n } else if (policy.mode === 'offline_only') {\n // Offline mode but pinned key has no key material - fail\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n error: 'Offline mode requires key material (jwk or public_key) in pinned_keys',\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n } else {\n // Network mode - fetch JWKS and verify thumbprint\n const jwksResult = await fetchIssuerJWKS(normalizedIssuer);\n\n if ('error' in jwksResult) {\n const reason = ssrfErrorToReasonCode(jwksResult.error.reason, 'key');\n builder.fail('issuer.discovery', reasonCodeToErrorCode(reason), {\n error: jwksResult.error.message,\n url: jwksResult.error.blockedUrl,\n });\n builder.failure(reason, normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n // Store raw bytes for digest computation (only when not from cache)\n if (jwksResult.rawBytes) {\n jwksRawBytes = jwksResult.rawBytes;\n }\n\n builder.pass('issuer.discovery', {\n from_cache: jwksResult.fromCache,\n keys_count: jwksResult.jwks.keys.length,\n });\n\n // Find the key\n const jwk = jwksResult.jwks.keys.find((k) => k.kid === kid);\n if (!jwk) {\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n kid,\n available_kids: jwksResult.jwks.keys.map((k) => k.kid),\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n // Verify thumbprint matches\n const actualThumbprint = await computeJwkThumbprint(jwk);\n if (actualThumbprint !== pinnedKey.jwk_thumbprint_sha256) {\n builder.fail('key.resolve', 'E_VERIFY_POLICY_VIOLATION', {\n error: 'JWK thumbprint does not match pinned key',\n expected: pinnedKey.jwk_thumbprint_sha256,\n actual: actualThumbprint,\n });\n builder.failure('policy_violation', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n publicKey = jwkToPublicKeyBytes(jwk);\n keySource = 'pinned_keys';\n keyThumbprint = actualThumbprint;\n builder.pass('key.resolve', { source: keySource, kid, thumbprint_verified: true });\n }\n } else {\n // No pinned key - need to discover\n if (policy.mode === 'offline_only') {\n builder.fail('issuer.discovery', 'E_VERIFY_KEY_NOT_FOUND', {\n error: 'Offline mode requires pinned keys',\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n const jwksResult = await fetchIssuerJWKS(normalizedIssuer);\n\n if ('error' in jwksResult) {\n const reason = ssrfErrorToReasonCode(jwksResult.error.reason, 'key');\n builder.fail('issuer.discovery', reasonCodeToErrorCode(reason), {\n error: jwksResult.error.message,\n url: jwksResult.error.blockedUrl,\n });\n builder.failure(reason, normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n // Store raw bytes for digest computation (only when not from cache)\n if (jwksResult.rawBytes) {\n jwksRawBytes = jwksResult.rawBytes;\n }\n\n builder.pass('issuer.discovery', {\n from_cache: jwksResult.fromCache,\n keys_count: jwksResult.jwks.keys.length,\n });\n\n // Find the key\n const jwk = jwksResult.jwks.keys.find((k) => k.kid === kid);\n if (!jwk) {\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n kid,\n available_kids: jwksResult.jwks.keys.map((k) => k.kid),\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n publicKey = jwkToPublicKeyBytes(jwk);\n keySource = 'jwks_discovery';\n keyThumbprint = await computeJwkThumbprint(jwk);\n builder.pass('key.resolve', { source: keySource, kid, thumbprint: keyThumbprint });\n }\n\n // ---------------------------------------------------------------------------\n // Check 8: jws.signature - Verify signature\n // ---------------------------------------------------------------------------\n try {\n const result = await jwsVerify<PEACReceiptClaims>(receiptJws, publicKey);\n\n if (!result.valid) {\n builder.fail('jws.signature', 'E_VERIFY_SIGNATURE_INVALID', {\n error: 'Ed25519 signature verification failed',\n });\n builder.failure('signature_invalid', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n parsedClaims = result.payload;\n builder.pass('jws.signature');\n } catch (err) {\n builder.fail('jws.signature', 'E_VERIFY_SIGNATURE_INVALID', {\n error: err instanceof Error ? err.message : String(err),\n });\n builder.failure('signature_invalid', normalizedIssuer, kid);\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // ---------------------------------------------------------------------------\n // Check 9: claims.time_window - Check iat/exp\n // ---------------------------------------------------------------------------\n const iatTolerance = 60; // 60 seconds tolerance for future iat\n\n // Check iat (issued at) - required field per schema\n if (parsedClaims!.iat > nowSeconds + iatTolerance) {\n builder.fail('claims.time_window', 'E_VERIFY_NOT_YET_VALID', {\n error: 'Receipt issued in the future',\n iat: parsedClaims!.iat,\n now: nowSeconds,\n tolerance: iatTolerance,\n });\n builder.failure('not_yet_valid', normalizedIssuer, kid);\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // Check exp (expiration) - no tolerance\n if (parsedClaims!.exp) {\n if (parsedClaims!.exp < nowSeconds) {\n builder.fail('claims.time_window', 'E_VERIFY_EXPIRED', {\n error: 'Receipt expired',\n exp: parsedClaims!.exp,\n now: nowSeconds,\n });\n builder.failure('expired', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n }\n\n builder.pass('claims.time_window', {\n iat: parsedClaims!.iat,\n exp: parsedClaims!.exp,\n now: nowSeconds,\n });\n\n // ---------------------------------------------------------------------------\n // Check 10: extensions.limits - Check extension sizes\n // ---------------------------------------------------------------------------\n // Check for oversized extensions in ext object\n if (parsedClaims!.ext) {\n for (const [extKey, extValue] of Object.entries(parsedClaims!.ext)) {\n if (extValue !== undefined) {\n const extJson = JSON.stringify(extValue);\n if (extJson.length > policy.limits.max_extension_bytes) {\n builder.fail('extensions.limits', 'E_VERIFY_EXTENSION_TOO_LARGE', {\n extension: extKey,\n size: extJson.length,\n limit: policy.limits.max_extension_bytes,\n });\n builder.failure('extension_too_large', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n }\n }\n }\n\n builder.pass('extensions.limits');\n\n // ---------------------------------------------------------------------------\n // Success!\n // ---------------------------------------------------------------------------\n builder.success(normalizedIssuer, kid!);\n\n // Add JWKS artifacts for enterprise debuggability\n // Map internal key source to artifact format\n const artifactKeySource = keySource === 'pinned_keys' ? 'pinned' : 'jwks_fetch';\n builder.addArtifact('issuer_key_source', artifactKeySource);\n\n if (keyThumbprint) {\n builder.addArtifact('issuer_key_thumbprint', keyThumbprint);\n }\n\n // Add JWKS digest when fetched (not from cache)\n // Computed over raw bytes to avoid encoding round-trip issues\n if (jwksRawBytes) {\n const jwksDigestHex = await sha256Hex(jwksRawBytes);\n builder.addArtifact('issuer_jwks_digest', createDigest(jwksDigestHex));\n }\n\n const report = includeMeta ? builder.addTimestamp().build() : builder.build();\n\n return {\n valid: true,\n report,\n claims: parsedClaims,\n };\n}\n\n/**\n * Clear the JWKS cache\n */\nexport function clearJWKSCache(): void {\n jwksCache.clear();\n}\n\n/**\n * Get JWKS cache size (for testing)\n */\nexport function getJWKSCacheSize(): number {\n return jwksCache.size;\n}\n","/**\n * PEAC Transport Profile Parsers\n *\n * Implements parsing for transport profiles per TRANSPORT-PROFILES.md:\n * - Header profile (PEAC-Receipt header)\n * - Pointer profile (PEAC-Receipt-Pointer header)\n * - Body profile (peac_receipt/peac_receipts in JSON body)\n *\n * @packageDocumentation\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Transport profile type\n */\nexport type TransportProfile = 'header' | 'pointer' | 'body';\n\n/**\n * Result of parsing a header transport profile\n */\nexport interface HeaderProfileResult {\n profile: 'header';\n receipt: string;\n}\n\n/**\n * Result of parsing a pointer transport profile\n */\nexport interface PointerProfileResult {\n profile: 'pointer';\n digestAlg: 'sha256';\n digestValue: string;\n url: string;\n /**\n * Extension parameters (keys starting with ext_).\n * Stored separately from normative fields for forward-compatibility.\n * Consumers SHOULD NOT rely on extension keys for core verification logic.\n */\n extensions?: Record<string, string>;\n}\n\n/**\n * Result of parsing a body transport profile\n */\nexport interface BodyProfileResult {\n profile: 'body';\n receipts: string[];\n}\n\n/**\n * Parsed transport profile (discriminated union)\n */\nexport type ParsedTransportProfile = HeaderProfileResult | PointerProfileResult | BodyProfileResult;\n\n/**\n * Transport profile parse error\n */\nexport interface TransportProfileError {\n ok: false;\n reason: 'invalid_transport' | 'malformed_receipt' | 'pointer_fetch_blocked';\n errorCode: string;\n message: string;\n}\n\n/**\n * Transport profile parse success\n */\nexport interface TransportProfileSuccess<\n T extends ParsedTransportProfile = ParsedTransportProfile,\n> {\n ok: true;\n result: T;\n}\n\n/**\n * Transport profile parse result\n */\nexport type TransportProfileParseResult<T extends ParsedTransportProfile = ParsedTransportProfile> =\n | TransportProfileSuccess<T>\n | TransportProfileError;\n\n// ---------------------------------------------------------------------------\n// Header Profile Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse PEAC-Receipt header\n *\n * Per TRANSPORT-PROFILES.md:\n * - Multiple headers MUST be rejected\n * - Comma-separated values MUST be rejected\n * - Value MUST be JWS compact serialization (three dot-separated segments)\n *\n * @param headerValue - PEAC-Receipt header value (string or array if multiple)\n * @returns Parse result\n */\nexport function parseHeaderProfile(\n headerValue: string | string[] | undefined\n): TransportProfileParseResult<HeaderProfileResult> {\n // Check for missing header\n if (headerValue === undefined || headerValue === '') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt header is missing',\n };\n }\n\n // Check for multiple headers (array)\n if (Array.isArray(headerValue)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Multiple PEAC-Receipt headers are not allowed',\n };\n }\n\n // Check for comma-separated values (HTTP header list syntax)\n if (headerValue.includes(',')) {\n // Could be comma in base64url, but JWS compact has exactly 2 periods\n // If there are commas between periods, it's likely multiple values\n const parts = headerValue.split('.');\n if (parts.length !== 3 || parts.some((p) => p.includes(','))) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Comma-separated PEAC-Receipt values are not allowed',\n };\n }\n }\n\n // Validate JWS compact serialization structure (three segments)\n const segments = headerValue.split('.');\n if (segments.length !== 3) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: `Invalid JWS compact serialization: expected 3 segments, got ${segments.length}`,\n };\n }\n\n // All segments must be non-empty base64url strings\n const base64urlRegex = /^[A-Za-z0-9_-]*$/;\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment.length === 0) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: `Invalid JWS compact serialization: segment ${i + 1} is empty`,\n };\n }\n if (!base64urlRegex.test(segment)) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: `Invalid JWS compact serialization: segment ${i + 1} contains invalid characters`,\n };\n }\n }\n\n return {\n ok: true,\n result: {\n profile: 'header',\n receipt: headerValue,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Pointer Profile Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse PEAC-Receipt-Pointer header\n *\n * Per TRANSPORT-PROFILES.md:\n * - Format: RFC 8941 dictionary with sha256 and url parameters\n * - Multiple headers MUST be rejected\n * - URL MUST be HTTPS\n *\n * Example: sha256=\"7d8f...\", url=\"https://receipts.example.com/abc123\"\n *\n * @param headerValue - PEAC-Receipt-Pointer header value (string or array if multiple)\n * @returns Parse result\n */\nexport function parsePointerProfile(\n headerValue: string | string[] | undefined\n): TransportProfileParseResult<PointerProfileResult> {\n // Check for missing header\n if (headerValue === undefined || headerValue === '') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer header is missing',\n };\n }\n\n // Check for multiple headers (array)\n if (Array.isArray(headerValue)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Multiple PEAC-Receipt-Pointer headers are not allowed',\n };\n }\n\n // Parse RFC 8941 dictionary format\n // Format: sha256=\"<hex>\", url=\"<url>\"\n // We use a simple parser here instead of a full RFC 8941 implementation\n\n const parseResult = parseSimpleDictionary(headerValue);\n\n // Strict: Reject duplicate parameters\n if (parseResult.duplicates.length > 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: `PEAC-Receipt-Pointer has duplicate parameter: ${parseResult.duplicates[0]}`,\n };\n }\n\n // Strict: Reject unknown parameters (only sha256, url, and ext_* are valid)\n // Extension keys (ext_*) are allowed for forward-compatibility\n const ALLOWED_KEYS = new Set(['sha256', 'url']);\n const unknownKeys = parseResult.keys.filter((k) => !ALLOWED_KEYS.has(k) && !k.startsWith('ext_'));\n if (unknownKeys.length > 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: `PEAC-Receipt-Pointer has unknown parameter: ${unknownKeys[0]}`,\n };\n }\n\n const params = parseResult.params;\n\n if (!params.sha256) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer missing sha256 parameter',\n };\n }\n\n if (!params.url) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer missing url parameter',\n };\n }\n\n // Validate digest is lowercase hex\n const hexRegex = /^[0-9a-f]{64}$/;\n if (!hexRegex.test(params.sha256)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer sha256 must be 64 lowercase hex characters',\n };\n }\n\n // Validate URL is HTTPS\n try {\n const url = new URL(params.url);\n if (url.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'pointer_fetch_blocked',\n errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n message: 'Pointer URL must use HTTPS',\n };\n }\n } catch {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer url is not a valid URL',\n };\n }\n\n // Extract extension keys (ext_*) for forward-compatibility\n const extensions: Record<string, string> = {};\n for (const key of parseResult.keys) {\n if (key.startsWith('ext_')) {\n extensions[key] = params[key];\n }\n }\n\n return {\n ok: true,\n result: {\n profile: 'pointer',\n digestAlg: 'sha256',\n digestValue: params.sha256,\n url: params.url,\n ...(Object.keys(extensions).length > 0 && { extensions }),\n },\n };\n}\n\n/**\n * Simple RFC 8941-like dictionary parser result\n */\ninterface DictionaryParseResult {\n /** Parsed key-value pairs */\n params: Record<string, string>;\n /** Duplicate keys found (strict mode violation) */\n duplicates: string[];\n /** All keys found (for unknown key detection) */\n keys: string[];\n}\n\n/**\n * Simple RFC 8941-like dictionary parser (ReDoS-safe)\n *\n * Parses: key1=\"value1\", key2=\"value2\"\n * Returns map of key -> value (unquoted) plus metadata for strict validation\n *\n * Uses explicit character-by-character parsing to avoid ReDoS vulnerabilities\n * from regex alternation patterns.\n */\nfunction parseSimpleDictionary(input: string): DictionaryParseResult {\n const params: Record<string, string> = {};\n const duplicates: string[] = [];\n const keys: string[] = [];\n\n let i = 0;\n const len = input.length;\n\n while (i < len) {\n // Skip whitespace and commas\n while (i < len && (input[i] === ' ' || input[i] === ',' || input[i] === '\\t')) {\n i++;\n }\n if (i >= len) break;\n\n // Parse key (word characters only)\n const keyStart = i;\n while (i < len && /\\w/.test(input[i])) {\n i++;\n }\n const key = input.slice(keyStart, i);\n if (!key) break;\n\n // Skip whitespace before '='\n while (i < len && input[i] === ' ') i++;\n\n // Expect '='\n if (i >= len || input[i] !== '=') break;\n i++; // skip '='\n\n // Skip whitespace after '='\n while (i < len && input[i] === ' ') i++;\n\n // Parse value (quoted or unquoted)\n let value: string;\n if (input[i] === '\"') {\n // Quoted value - find closing quote\n i++; // skip opening quote\n const valueStart = i;\n while (i < len && input[i] !== '\"') {\n i++;\n }\n value = input.slice(valueStart, i);\n if (i < len) i++; // skip closing quote\n } else {\n // Unquoted value - read until comma or whitespace\n const valueStart = i;\n while (i < len && input[i] !== ',' && input[i] !== ' ' && input[i] !== '\\t') {\n i++;\n }\n value = input.slice(valueStart, i);\n }\n\n keys.push(key);\n\n // Track duplicates\n if (key in params) {\n duplicates.push(key);\n }\n\n params[key] = value;\n }\n\n return { params, duplicates, keys };\n}\n\n// ---------------------------------------------------------------------------\n// Body Profile Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse body profile (JSON body with peac_receipt or peac_receipts)\n *\n * Per TRANSPORT-PROFILES.md:\n * - peac_receipt: single receipt (string)\n * - peac_receipts: multiple receipts (array of strings)\n *\n * @param body - Parsed JSON body object\n * @returns Parse result\n */\nexport function parseBodyProfile(body: unknown): TransportProfileParseResult<BodyProfileResult> {\n if (body === null || typeof body !== 'object') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Body must be a JSON object',\n };\n }\n\n const obj = body as Record<string, unknown>;\n\n // Check for peac_receipts (array, takes precedence)\n if ('peac_receipts' in obj) {\n if (!Array.isArray(obj.peac_receipts)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipts must be an array',\n };\n }\n\n const receipts: string[] = [];\n for (let i = 0; i < obj.peac_receipts.length; i++) {\n const receipt = obj.peac_receipts[i];\n if (typeof receipt !== 'string') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: `peac_receipts[${i}] must be a string`,\n };\n }\n receipts.push(receipt);\n }\n\n if (receipts.length === 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipts array is empty',\n };\n }\n\n return {\n ok: true,\n result: {\n profile: 'body',\n receipts,\n },\n };\n }\n\n // Check for peac_receipt (single)\n if ('peac_receipt' in obj) {\n if (typeof obj.peac_receipt !== 'string') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipt must be a string',\n };\n }\n\n if (obj.peac_receipt.length === 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipt is empty',\n };\n }\n\n return {\n ok: true,\n result: {\n profile: 'body',\n receipts: [obj.peac_receipt],\n },\n };\n }\n\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Body must contain peac_receipt or peac_receipts',\n };\n}\n\n// ---------------------------------------------------------------------------\n// Auto-detect Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect and parse transport profile from request context\n *\n * @param context - Request context with headers and optional body\n * @returns Parse result\n */\nexport function parseTransportProfile(context: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n}): TransportProfileParseResult {\n const peacReceipt = context.headers['peac-receipt'] ?? context.headers['PEAC-Receipt'];\n const peacPointer =\n context.headers['peac-receipt-pointer'] ?? context.headers['PEAC-Receipt-Pointer'];\n\n // Header profile takes precedence\n if (peacReceipt !== undefined) {\n return parseHeaderProfile(peacReceipt);\n }\n\n // Pointer profile second\n if (peacPointer !== undefined) {\n return parsePointerProfile(peacPointer);\n }\n\n // Body profile last (if body provided)\n if (context.body !== undefined) {\n return parseBodyProfile(context.body);\n }\n\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message:\n 'No transport profile detected (missing PEAC-Receipt, PEAC-Receipt-Pointer, or body receipt)',\n };\n}\n","/**\n * PEAC Pointer Fetch with Digest Verification\n *\n * Implements secure receipt fetching via pointers per TRANSPORT-PROFILES.md:\n * - SSRF-safe fetch\n * - SHA-256 digest verification\n * - Size limits\n *\n * @packageDocumentation\n */\n\nimport { sha256Hex } from '@peac/crypto';\nimport { VERIFIER_LIMITS } from '@peac/kernel';\nimport { ssrfSafeFetch, type SSRFFetchOptions, type SSRFFetchError } from './ssrf-safe-fetch.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Pointer fetch options\n */\nexport interface PointerFetchOptions {\n /** URL to fetch the receipt from */\n url: string;\n /** Expected SHA-256 digest (lowercase hex, 64 chars) */\n expectedDigest: string;\n /** Optional SSRF fetch options */\n fetchOptions?: Omit<SSRFFetchOptions, 'maxBytes'>;\n}\n\n/**\n * Successful pointer fetch result\n */\nexport interface PointerFetchSuccess {\n ok: true;\n /** Fetched receipt (JWS compact serialization) */\n receipt: string;\n /** Actual SHA-256 digest of fetched content */\n actualDigest: string;\n /** Whether digest matched expected */\n digestMatched: true;\n /** Content-Type header (if present) */\n contentType?: string;\n /**\n * Warning about unexpected Content-Type.\n * Present when Content-Type is not application/jose, application/json, or text/plain.\n * Does not cause rejection (for interoperability) but callers may want to log.\n */\n contentTypeWarning?: string;\n}\n\n/**\n * Failed pointer fetch result\n */\nexport interface PointerFetchError {\n ok: false;\n /** Error reason */\n reason:\n | 'pointer_fetch_blocked'\n | 'pointer_fetch_failed'\n | 'pointer_fetch_timeout'\n | 'pointer_fetch_too_large'\n | 'pointer_digest_mismatch'\n | 'malformed_receipt';\n /** Error code for reports */\n errorCode: string;\n /** Human-readable error message */\n message: string;\n /** Actual digest if computed (for mismatch errors) */\n actualDigest?: string;\n /** Expected digest */\n expectedDigest?: string;\n}\n\n/**\n * Pointer fetch result\n */\nexport type PointerFetchResult = PointerFetchSuccess | PointerFetchError;\n\n// ---------------------------------------------------------------------------\n// Error Mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Map SSRF error reason to pointer error reason\n */\nfunction mapSsrfError(ssrfError: SSRFFetchError): PointerFetchError {\n const reason = ssrfError.reason;\n\n switch (reason) {\n case 'not_https':\n case 'private_ip':\n case 'loopback':\n case 'link_local':\n case 'dns_failure':\n case 'cross_origin_redirect':\n return {\n ok: false,\n reason: 'pointer_fetch_blocked',\n errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n message: ssrfError.message,\n };\n\n case 'timeout':\n return {\n ok: false,\n reason: 'pointer_fetch_timeout',\n errorCode: 'E_VERIFY_POINTER_FETCH_TIMEOUT',\n message: ssrfError.message,\n };\n\n case 'response_too_large':\n return {\n ok: false,\n reason: 'pointer_fetch_too_large',\n errorCode: 'E_VERIFY_POINTER_FETCH_TOO_LARGE',\n message: ssrfError.message,\n };\n\n default:\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: ssrfError.message,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pointer Fetch\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch a receipt via pointer with digest verification\n *\n * Per TRANSPORT-PROFILES.md:\n * - Fetch the URL using SSRF-safe fetch\n * - Compute SHA-256 digest of response\n * - Verify digest matches expected value from header\n * - Return receipt only if digest matches\n *\n * @param options - Pointer fetch options\n * @returns Fetch result\n */\nexport async function fetchPointerWithDigest(\n options: PointerFetchOptions\n): Promise<PointerFetchResult> {\n const { url, expectedDigest, fetchOptions = {} } = options;\n\n // Validate expected digest format\n const hexRegex = /^[0-9a-f]{64}$/;\n if (!hexRegex.test(expectedDigest)) {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'Invalid expected digest: must be 64 lowercase hex characters',\n };\n }\n\n // Validate URL is HTTPS (pre-check before fetch)\n try {\n const parsedUrl = new URL(url);\n if (parsedUrl.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'pointer_fetch_blocked',\n errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n message: 'Pointer URL must use HTTPS',\n };\n }\n } catch {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'Invalid pointer URL',\n };\n }\n\n // Fetch with SSRF protection and DoS bounds\n // - Size cap: maxReceiptBytes (prevents memory exhaustion)\n // - No redirects: prevents redirect-based SSRF (pointer URL must be direct)\n // - Timeout: prevents slow-loris style attacks\n const fetchResult = await ssrfSafeFetch(url, {\n ...fetchOptions,\n maxBytes: VERIFIER_LIMITS.maxReceiptBytes,\n allowRedirects: false, // Pointer URL must be direct - no redirects\n timeoutMs: fetchOptions?.timeoutMs ?? VERIFIER_LIMITS.fetchTimeoutMs,\n headers: {\n Accept: 'application/jose, application/json, text/plain',\n ...fetchOptions.headers,\n },\n });\n\n if (!fetchResult.ok) {\n return mapSsrfError(fetchResult);\n }\n\n const receipt = fetchResult.body;\n\n // Validate Content-Type if present (warn but don't reject for interoperability)\n // Expected: application/jose, application/json, or text/plain\n const contentType = fetchResult.contentType;\n const expectedContentTypes = ['application/jose', 'application/json', 'text/plain'];\n const contentTypeWarning =\n contentType && !expectedContentTypes.some((expected) => contentType.startsWith(expected))\n ? `Unexpected Content-Type: ${contentType}; expected application/jose, application/json, or text/plain`\n : undefined;\n\n // Validate: reject empty body\n if (!receipt || receipt.trim().length === 0) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: 'Pointer target returned empty content',\n };\n }\n\n // Validate: content must look like JWS compact serialization (3 dot-separated segments)\n const jwsValidation = validateJwsCompactStructure(receipt);\n if (!jwsValidation.valid) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: jwsValidation.message,\n };\n }\n\n // Compute digest of fetched content (hash the raw string bytes)\n const actualDigest = await sha256Hex(receipt);\n\n // Verify digest matches\n if (actualDigest !== expectedDigest) {\n return {\n ok: false,\n reason: 'pointer_digest_mismatch',\n errorCode: 'E_VERIFY_POINTER_DIGEST_MISMATCH',\n message: 'Fetched receipt digest does not match expected digest',\n actualDigest,\n expectedDigest,\n };\n }\n\n return {\n ok: true,\n receipt,\n actualDigest,\n digestMatched: true,\n contentType: fetchResult.contentType,\n ...(contentTypeWarning && { contentTypeWarning }),\n };\n}\n\n/**\n * Validate that a string looks like JWS compact serialization\n *\n * A valid JWS compact has exactly 3 dot-separated base64url segments.\n *\n * @param value - String to validate\n * @returns Validation result\n */\nfunction validateJwsCompactStructure(\n value: string\n): { valid: true } | { valid: false; message: string } {\n const segments = value.split('.');\n\n if (segments.length !== 3) {\n return {\n valid: false,\n message: `Invalid JWS compact serialization: expected 3 segments, got ${segments.length}`,\n };\n }\n\n // All segments must be non-empty and contain only base64url characters\n const base64urlRegex = /^[A-Za-z0-9_-]+$/;\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment.length === 0) {\n return {\n valid: false,\n message: `Invalid JWS compact serialization: segment ${i + 1} is empty`,\n };\n }\n if (!base64urlRegex.test(segment)) {\n return {\n valid: false,\n message: `Invalid JWS compact serialization: segment ${i + 1} contains invalid characters`,\n };\n }\n }\n\n return { valid: true };\n}\n\n/**\n * Parse pointer header key=value pairs (ReDoS-safe)\n *\n * Handles both quoted and unquoted values without complex regex alternation.\n */\nfunction parsePointerHeader(input: string): Record<string, string> {\n const params: Record<string, string> = {};\n let i = 0;\n const len = input.length;\n\n while (i < len) {\n // Skip whitespace and commas\n while (i < len && (input[i] === ' ' || input[i] === ',' || input[i] === '\\t')) {\n i++;\n }\n if (i >= len) break;\n\n // Parse key (word characters only)\n const keyStart = i;\n while (i < len && /\\w/.test(input[i])) {\n i++;\n }\n const key = input.slice(keyStart, i);\n if (!key) break;\n\n // Skip whitespace before '='\n while (i < len && input[i] === ' ') i++;\n\n // Expect '='\n if (i >= len || input[i] !== '=') break;\n i++; // skip '='\n\n // Skip whitespace after '='\n while (i < len && input[i] === ' ') i++;\n\n // Parse value (quoted or unquoted)\n let value: string;\n if (input[i] === '\"') {\n // Quoted value - find closing quote\n i++; // skip opening quote\n const valueStart = i;\n while (i < len && input[i] !== '\"') {\n i++;\n }\n value = input.slice(valueStart, i);\n if (i < len) i++; // skip closing quote\n } else {\n // Unquoted value - read until comma or whitespace\n const valueStart = i;\n while (i < len && input[i] !== ',' && input[i] !== ' ' && input[i] !== '\\t') {\n i++;\n }\n value = input.slice(valueStart, i);\n }\n\n params[key] = value;\n }\n\n return params;\n}\n\n/**\n * Verify a pointer header and fetch the receipt\n *\n * Combines parsing and fetching in a single operation.\n *\n * @param pointerHeader - PEAC-Receipt-Pointer header value\n * @param fetchOptions - Optional SSRF fetch options\n * @returns Fetch result\n */\nexport async function verifyAndFetchPointer(\n pointerHeader: string,\n fetchOptions?: Omit<SSRFFetchOptions, 'maxBytes'>\n): Promise<PointerFetchResult> {\n // Parse pointer header (RFC 8941 dictionary format)\n // Format: sha256=\"<hex>\", url=\"<url>\"\n // Using explicit parsing to avoid ReDoS in regex alternation\n const params = parsePointerHeader(pointerHeader);\n\n if (!params.sha256) {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'PEAC-Receipt-Pointer missing sha256 parameter',\n };\n }\n\n if (!params.url) {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'PEAC-Receipt-Pointer missing url parameter',\n };\n }\n\n return fetchPointerWithDigest({\n url: params.url,\n expectedDigest: params.sha256,\n fetchOptions,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/telemetry.ts","../src/issue.ts","../src/verify.ts","../src/verify-local.ts","../src/headers.ts","../src/discovery.ts","../src/verifier-types.ts","../src/ssrf-safe-fetch.ts","../src/verification-report.ts","../src/verifier-core.ts","../src/transport-profiles.ts","../src/pointer-fetch.ts"],"names":["createHash","isValidPurposeToken","isCanonicalPurpose","isValidPurposeReason","isValidWorkflowContext","createWorkflowContextInvalidError","hasValidDagSemantics","createWorkflowDagInvalidError","uuidv7","WORKFLOW_EXTENSION_KEY","ReceiptClaims","ZodError","issue","createEvidenceNotJsonError","validateSubjectSnapshot","sign","decode","jwsVerify","parseReceiptClaims","PEAC_RECEIPT_HEADER","PEAC_PURPOSE_HEADER","parsePurposeHeader","PEAC_PURPOSE_APPLIED_HEADER","PEAC_PURPOSE_REASON_HEADER","PEAC_ISSUER_CONFIG_MAX_BYTES","PEAC_ISSUER_CONFIG_PATH","PEAC_POLICY_MAX_BYTES","PEAC_POLICY_PATH","PEAC_POLICY_FALLBACK_PATH","VERIFIER_LIMITS","VERIFIER_NETWORK","VERIFIER_POLICY_VERSION","VERIFICATION_REPORT_VERSION","body","rawBytes","sha256Hex","WIRE_TYPE","jwksCache","CACHE_TTL_MS","fetchIssuerConfig","result","computeJwkThumbprint","jwkToPublicKeyBytes","base64urlDecode"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Telemetry utilities for protocol package\n *\n * TelemetryHook is the protocol-local interface for observability.\n * Hooks are best-effort side effects: fire-and-forget, never awaited,\n * guarded against both sync throws and async rejections.\n */\n\nimport { createHash } from 'node:crypto';\n\n/**\n * Input for receipt issued telemetry event\n */\nexport interface ReceiptIssuedHookInput {\n receiptHash: string;\n issuer?: string;\n kid?: string;\n durationMs?: number;\n}\n\n/**\n * Input for receipt verified telemetry event\n */\nexport interface ReceiptVerifiedHookInput {\n receiptHash: string;\n valid: boolean;\n reasonCode?: string;\n issuer?: string;\n kid?: string;\n durationMs?: number;\n}\n\n/**\n * Telemetry hook interface for protocol observability\n *\n * Implementations SHOULD be no-throw. Protocol guards all calls,\n * but well-behaved hooks should not throw.\n *\n * Hooks may be sync or async -- protocol will NOT await the result.\n */\nexport type TelemetryHook = {\n onReceiptIssued?(input: ReceiptIssuedHookInput): void | Promise<void>;\n onReceiptVerified?(input: ReceiptVerifiedHookInput): void | Promise<void>;\n};\n\n/**\n * Safely invoke a telemetry hook (fire-and-forget)\n *\n * Guards both sync throws and async rejections.\n * Telemetry MUST NOT break core flow.\n */\nexport function fireTelemetryHook<T>(\n fn: ((input: T) => void | Promise<void>) | undefined,\n input: T\n): void {\n if (!fn) return;\n try {\n const result = fn(input);\n // Swallow async rejections\n if (result && typeof (result as Promise<void>).catch === 'function') {\n (result as Promise<void>).catch(() => {});\n }\n } catch {\n // Telemetry MUST NOT break core flow\n }\n}\n\n/**\n * Compute a SHA-256 hash of a receipt JWS\n *\n * Returns format: sha256:{hex prefix}\n * Uses first 16 chars of hex for brevity in logs/spans.\n */\nexport function hashReceipt(jws: string): string {\n const hash = createHash('sha256').update(jws).digest('hex');\n return `sha256:${hash.slice(0, 16)}`;\n}\n","/**\n * Receipt issuance\n * Validates input, generates UUIDv7 rid, and signs with Ed25519\n */\n\nimport { uuidv7 } from 'uuidv7';\nimport { sign } from '@peac/crypto';\nimport type { JsonValue } from '@peac/kernel';\nimport { ZodError } from 'zod';\nimport {\n PEACReceiptClaims,\n ReceiptClaims,\n SubjectProfileSnapshot,\n validateSubjectSnapshot,\n createEvidenceNotJsonError,\n createWorkflowContextInvalidError,\n createWorkflowDagInvalidError,\n type PEACError,\n type PurposeToken,\n type CanonicalPurpose,\n type PurposeReason,\n isValidPurposeToken,\n isCanonicalPurpose,\n isValidPurposeReason,\n // Workflow correlation (v0.10.2+)\n type WorkflowContext,\n isValidWorkflowContext,\n hasValidDagSemantics,\n WORKFLOW_EXTENSION_KEY,\n} from '@peac/schema';\nimport { hashReceipt, fireTelemetryHook, type TelemetryHook } from './telemetry.js';\n\n/**\n * Options for issuing a receipt\n */\nexport interface IssueOptions {\n /** Issuer URL (https://) */\n iss: string;\n\n /** Audience / resource URL (https://) */\n aud: string;\n\n /** Amount in smallest currency unit */\n amt: number;\n\n /** ISO 4217 currency code (uppercase) */\n cur: string;\n\n /** Payment rail identifier */\n rail: string;\n\n /** Rail-specific payment reference */\n reference: string;\n\n /** Asset transferred (e.g., \"USD\", \"USDC\", \"BTC\") - defaults to currency if not provided */\n asset?: string;\n\n /** Environment (\"live\" or \"test\") - defaults to \"test\" */\n env?: 'live' | 'test';\n\n /** Network/rail identifier (optional, SHOULD for crypto) */\n network?: string;\n\n /** Facilitator reference (optional) */\n facilitator_ref?: string;\n\n /** Rail-specific evidence (JSON-safe) - defaults to empty object if not provided */\n evidence?: JsonValue;\n\n /** Idempotency key (optional) */\n idempotency_key?: string;\n\n /** Rail-specific metadata (optional) */\n metadata?: Record<string, unknown>;\n\n /** Subject URI (optional) */\n subject?: string;\n\n /** Extensions (optional) */\n ext?: PEACReceiptClaims['ext'];\n\n /** Expiry timestamp (Unix seconds, optional) */\n exp?: number;\n\n /** Subject profile snapshot for envelope (v0.9.17+, optional) */\n subject_snapshot?: SubjectProfileSnapshot;\n\n /**\n * Purposes declared by the requesting agent (v0.9.24+, optional)\n *\n * From PEAC-Purpose request header. Accepts single token or array.\n * Unknown tokens are preserved for forward compatibility.\n */\n purpose?: PurposeToken | PurposeToken[];\n\n /**\n * Single purpose enforced by policy (v0.9.24+, optional)\n *\n * MUST be one of declared purposes OR a more restrictive downgrade.\n * Only canonical purposes have enforcement semantics.\n */\n purpose_enforced?: CanonicalPurpose;\n\n /**\n * Reason for enforcement decision (v0.9.24+, optional)\n *\n * The audit spine - explains WHY purpose was enforced as it was.\n */\n purpose_reason?: PurposeReason;\n\n /**\n * Workflow correlation context (v0.10.2+, optional)\n *\n * Links this receipt into a multi-step workflow DAG.\n * Added to ext['org.peacprotocol/workflow'].\n */\n workflow_context?: WorkflowContext;\n\n /** Ed25519 private key (32 bytes) */\n privateKey: Uint8Array;\n\n /** Key ID (ISO 8601 timestamp) */\n kid: string;\n\n /** Telemetry hook (optional, fire-and-forget) */\n telemetry?: TelemetryHook;\n}\n\n/**\n * Result of issuing a receipt\n */\nexport interface IssueResult {\n /** JWS compact serialization */\n jws: string;\n\n /** Validated subject snapshot (if provided) */\n subject_snapshot?: SubjectProfileSnapshot;\n}\n\n/**\n * Error thrown during receipt issuance\n *\n * Wraps a structured PEACError for programmatic handling.\n */\nexport class IssueError extends Error {\n /** Structured error details */\n readonly peacError: PEACError;\n\n constructor(peacError: PEACError) {\n const details = peacError.details as { message?: string } | undefined;\n super(details?.message ?? peacError.code);\n this.name = 'IssueError';\n this.peacError = peacError;\n }\n}\n\n/**\n * Issue a PEAC receipt\n *\n * @param options - Receipt options\n * @returns Issue result with JWS and optional subject_snapshot\n * @throws IssueError if evidence contains non-JSON-safe values\n */\nexport async function issue(options: IssueOptions): Promise<IssueResult> {\n // Validate URLs\n if (!options.iss.startsWith('https://')) {\n throw new Error('Issuer URL must start with https://');\n }\n if (!options.aud.startsWith('https://')) {\n throw new Error('Audience URL must start with https://');\n }\n if (options.subject && !options.subject.startsWith('https://')) {\n throw new Error('Subject URI must start with https://');\n }\n\n // Validate currency code\n if (!/^[A-Z]{3}$/.test(options.cur)) {\n throw new Error('Currency must be ISO 4217 uppercase (e.g., USD)');\n }\n\n // Validate amount\n if (!Number.isInteger(options.amt) || options.amt < 0) {\n throw new Error('Amount must be a non-negative integer');\n }\n\n // Validate expiry (if provided)\n if (options.exp !== undefined) {\n if (!Number.isInteger(options.exp) || options.exp < 0) {\n throw new Error('Expiry must be a non-negative integer');\n }\n }\n\n // Normalize and validate purpose (v0.9.24+)\n let purposeDeclared: PurposeToken[] | undefined;\n if (options.purpose !== undefined) {\n // Normalize to array\n const rawPurposes = Array.isArray(options.purpose) ? options.purpose : [options.purpose];\n\n // Validate each token\n const invalidTokens: string[] = [];\n for (const token of rawPurposes) {\n if (!isValidPurposeToken(token)) {\n invalidTokens.push(token);\n }\n }\n if (invalidTokens.length > 0) {\n throw new Error(`Invalid purpose tokens: ${invalidTokens.join(', ')}`);\n }\n\n // Check for explicit 'undeclared' which is invalid on wire\n if (rawPurposes.includes('undeclared')) {\n throw new Error(\"Explicit 'undeclared' is not a valid purpose token (internal-only)\");\n }\n\n purposeDeclared = rawPurposes;\n }\n\n // Validate purpose_enforced (must be canonical)\n if (options.purpose_enforced !== undefined) {\n if (!isCanonicalPurpose(options.purpose_enforced)) {\n throw new Error(\n `purpose_enforced must be a canonical purpose, got: ${options.purpose_enforced}`\n );\n }\n }\n\n // Validate purpose_reason\n if (options.purpose_reason !== undefined) {\n if (!isValidPurposeReason(options.purpose_reason)) {\n throw new Error(`Invalid purpose_reason: ${options.purpose_reason}`);\n }\n }\n\n // Validate workflow_context (v0.10.2+)\n if (options.workflow_context !== undefined) {\n if (!isValidWorkflowContext(options.workflow_context)) {\n throw new IssueError(\n createWorkflowContextInvalidError('Does not conform to WorkflowContextSchema')\n );\n }\n if (!hasValidDagSemantics(options.workflow_context)) {\n // Determine specific reason\n const ctx = options.workflow_context;\n const isSelfParent = ctx.parent_step_ids.includes(ctx.step_id);\n const hasDuplicates = new Set(ctx.parent_step_ids).size !== ctx.parent_step_ids.length;\n const reason = isSelfParent ? 'self_parent' : hasDuplicates ? 'duplicate_parent' : 'cycle';\n throw new IssueError(createWorkflowDagInvalidError(reason));\n }\n }\n\n // Generate UUIDv7 for receipt ID\n const rid = uuidv7();\n\n // Get current timestamp\n const iat = Math.floor(Date.now() / 1000);\n\n // Build receipt claims\n const claims: PEACReceiptClaims = {\n iss: options.iss,\n aud: options.aud,\n iat,\n rid,\n amt: options.amt,\n cur: options.cur,\n payment: {\n rail: options.rail,\n reference: options.reference,\n amount: options.amt,\n currency: options.cur,\n asset: options.asset ?? options.cur, // Default asset to currency for backward compatibility\n env: options.env ?? 'test', // Default to test environment for backward compatibility\n evidence: options.evidence ?? {}, // Default to empty object for backward compatibility\n ...(options.network && { network: options.network }),\n ...(options.facilitator_ref && { facilitator_ref: options.facilitator_ref }),\n ...(options.idempotency_key && { idempotency_key: options.idempotency_key }),\n ...(options.metadata && { metadata: options.metadata }),\n },\n ...(options.exp && { exp: options.exp }),\n ...(options.subject && { subject: { uri: options.subject } }),\n // Build extensions (merge user-provided ext with workflow_context)\n ...((options.ext || options.workflow_context) && {\n ext: {\n ...options.ext,\n ...(options.workflow_context && {\n [WORKFLOW_EXTENSION_KEY]: options.workflow_context,\n }),\n },\n }),\n // Purpose claims (v0.9.24+)\n ...(purposeDeclared && { purpose_declared: purposeDeclared }),\n ...(options.purpose_enforced && { purpose_enforced: options.purpose_enforced }),\n ...(options.purpose_reason && { purpose_reason: options.purpose_reason }),\n };\n\n // Validate claims with Zod - map evidence errors to typed error\n try {\n ReceiptClaims.parse(claims);\n } catch (err: unknown) {\n if (err instanceof ZodError) {\n // Check if any error path touches evidence\n const evidenceIssue = err.issues.find(\n (issue: { path: (string | number)[]; message: string }) =>\n issue.path.some((p: string | number) => p === 'evidence' || p === 'payment')\n );\n if (evidenceIssue && evidenceIssue.path.includes('evidence')) {\n const peacError = createEvidenceNotJsonError(evidenceIssue.message, evidenceIssue.path);\n throw new IssueError(peacError);\n }\n }\n throw err;\n }\n\n // Validate subject_snapshot if provided (v0.9.17+)\n // This validates schema and logs advisory PII warning if applicable\n const validatedSnapshot = validateSubjectSnapshot(options.subject_snapshot);\n\n // Track start time for telemetry\n const startTime = performance.now();\n\n // Sign with Ed25519\n const jws = await sign(claims, options.privateKey, options.kid);\n\n // Emit telemetry (fire-and-forget, guarded)\n fireTelemetryHook(options.telemetry?.onReceiptIssued, {\n receiptHash: hashReceipt(jws),\n issuer: options.iss,\n kid: options.kid,\n durationMs: performance.now() - startTime,\n });\n\n return {\n jws,\n ...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),\n };\n}\n\n/**\n * Issue a PEAC receipt and return just the JWS string\n *\n * Convenience wrapper for common header-centric flows where only the JWS is needed.\n * For access to validated subject_snapshot, use issue() instead.\n *\n * @param options - Receipt options\n * @returns JWS compact serialization\n */\nexport async function issueJws(options: IssueOptions): Promise<string> {\n const result = await issue(options);\n return result.jws;\n}\n","/**\n * Receipt verification with JWKS fetching and caching\n */\n\nimport { verify as jwsVerify, decode } from '@peac/crypto';\nimport {\n PEACReceiptClaims,\n ReceiptClaims,\n SubjectProfileSnapshot,\n validateSubjectSnapshot,\n} from '@peac/schema';\nimport { hashReceipt, fireTelemetryHook, type TelemetryHook } from './telemetry.js';\n\n/**\n * JWKS key entry\n */\ninterface JWK {\n kty: string;\n crv: string;\n x: string;\n kid: string;\n}\n\n/**\n * JWKS document\n */\ninterface JWKS {\n keys: JWK[];\n}\n\n/**\n * In-memory JWKS cache\n * Maps issuer URL to { keys, expiresAt }\n */\nconst jwksCache = new Map<string, { keys: JWKS; expiresAt: number }>();\n\n/**\n * Cache TTL (5 minutes)\n */\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\n/**\n * Verification result\n */\nexport interface VerifyResult {\n /** Verification succeeded */\n ok: true;\n\n /** Receipt claims */\n claims: PEACReceiptClaims;\n\n /** Subject profile snapshot (v0.9.17+, if provided) */\n subject_snapshot?: SubjectProfileSnapshot;\n\n /** Performance metrics */\n perf?: {\n verify_ms: number;\n jwks_fetch_ms?: number;\n };\n}\n\n/**\n * Verification failure\n */\nexport interface VerifyFailure {\n /** Verification failed */\n ok: false;\n\n /** Error reason */\n reason: string;\n\n /** Error details */\n details?: string;\n}\n\n/**\n * Fetch JWKS from issuer (SSRF-safe)\n */\nasync function fetchJWKS(issuerUrl: string): Promise<JWKS> {\n // SSRF protection: only allow https://\n if (!issuerUrl.startsWith('https://')) {\n throw new Error('Issuer URL must be https://');\n }\n\n // Construct JWKS URL from discovery\n const discoveryUrl = `${issuerUrl}/.well-known/peac.txt`;\n\n try {\n const discoveryResp = await fetch(discoveryUrl, {\n headers: { Accept: 'text/plain' },\n // Timeout after 5 seconds\n signal: AbortSignal.timeout(5000),\n });\n\n if (!discoveryResp.ok) {\n throw new Error(`Discovery fetch failed: ${discoveryResp.status}`);\n }\n\n const discoveryText = await discoveryResp.text();\n\n // Parse YAML-like discovery (simple key: value parsing)\n const jwksLine = discoveryText.split('\\n').find((line) => line.startsWith('jwks:'));\n if (!jwksLine) {\n throw new Error('No jwks field in discovery');\n }\n\n const jwksUrl = jwksLine.replace('jwks:', '').trim();\n\n // SSRF protection: verify JWKS URL is also https://\n if (!jwksUrl.startsWith('https://')) {\n throw new Error('JWKS URL must be https://');\n }\n\n // Fetch JWKS\n const jwksResp = await fetch(jwksUrl, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (!jwksResp.ok) {\n throw new Error(`JWKS fetch failed: ${jwksResp.status}`);\n }\n\n const jwks = (await jwksResp.json()) as JWKS;\n\n return jwks;\n } catch (err) {\n throw new Error(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`, {\n cause: err,\n });\n }\n}\n\n/**\n * Get JWKS (from cache or fetch)\n */\nasync function getJWKS(issuerUrl: string): Promise<{ jwks: JWKS; fromCache: boolean }> {\n const now = Date.now();\n\n // Check cache\n const cached = jwksCache.get(issuerUrl);\n if (cached && cached.expiresAt > now) {\n return { jwks: cached.keys, fromCache: true };\n }\n\n // Fetch fresh JWKS\n const jwks = await fetchJWKS(issuerUrl);\n\n // Cache it\n jwksCache.set(issuerUrl, {\n keys: jwks,\n expiresAt: now + CACHE_TTL_MS,\n });\n\n return { jwks, fromCache: false };\n}\n\n/**\n * Convert JWK x coordinate to Ed25519 public key\n */\nfunction jwkToPublicKey(jwk: JWK): Uint8Array {\n if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') {\n throw new Error('Only Ed25519 keys (OKP/Ed25519) are supported');\n }\n\n // Decode base64url x coordinate\n const xBytes = Buffer.from(jwk.x, 'base64url');\n if (xBytes.length !== 32) {\n throw new Error('Ed25519 public key must be 32 bytes');\n }\n\n return new Uint8Array(xBytes);\n}\n\n/**\n * Options for verifying a receipt\n */\nexport interface VerifyOptions {\n /** JWS compact serialization */\n receiptJws: string;\n\n /** Subject profile snapshot (v0.9.17+, optional envelope metadata) */\n subject_snapshot?: SubjectProfileSnapshot;\n\n /** Telemetry hook (optional, fire-and-forget) */\n telemetry?: TelemetryHook;\n}\n\n/**\n * Verify a PEAC receipt JWS\n *\n * @param optionsOrJws - Verify options or JWS compact serialization (for backwards compatibility)\n * @returns Verification result or failure\n */\nexport async function verifyReceipt(\n optionsOrJws: string | VerifyOptions\n): Promise<VerifyResult | VerifyFailure> {\n // Support both old (string) and new (options) signatures for backwards compatibility\n const receiptJws = typeof optionsOrJws === 'string' ? optionsOrJws : optionsOrJws.receiptJws;\n const inputSnapshot =\n typeof optionsOrJws === 'string' ? undefined : optionsOrJws.subject_snapshot;\n const telemetry = typeof optionsOrJws === 'string' ? undefined : optionsOrJws.telemetry;\n const startTime = performance.now();\n let jwksFetchTime: number | undefined;\n\n try {\n // Decode JWS to get issuer\n const { header, payload } = decode<PEACReceiptClaims>(receiptJws);\n\n // Validate claims structure\n ReceiptClaims.parse(payload);\n\n // Check expiry\n if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'expired',\n issuer: payload.iss,\n kid: header.kid,\n durationMs,\n });\n return {\n ok: false,\n reason: 'expired',\n details: `Receipt expired at ${new Date(payload.exp * 1000).toISOString()}`,\n };\n }\n\n // Fetch JWKS\n const jwksFetchStart = performance.now();\n const { jwks, fromCache } = await getJWKS(payload.iss);\n if (!fromCache) {\n jwksFetchTime = performance.now() - jwksFetchStart;\n }\n\n // Find key by kid\n const jwk = jwks.keys.find((k) => k.kid === header.kid);\n if (!jwk) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'unknown_key',\n issuer: payload.iss,\n kid: header.kid,\n durationMs,\n });\n return {\n ok: false,\n reason: 'unknown_key',\n details: `No key found with kid=${header.kid}`,\n };\n }\n\n // Convert JWK to public key\n const publicKey = jwkToPublicKey(jwk);\n\n // Verify signature\n const result = await jwsVerify<PEACReceiptClaims>(receiptJws, publicKey);\n\n if (!result.valid) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'invalid_signature',\n issuer: payload.iss,\n kid: header.kid,\n durationMs,\n });\n return {\n ok: false,\n reason: 'invalid_signature',\n details: 'Ed25519 signature verification failed',\n };\n }\n\n // Validate subject_snapshot if provided (v0.9.17+)\n // This validates schema and logs advisory PII warning if applicable\n const validatedSnapshot = validateSubjectSnapshot(inputSnapshot);\n\n const verifyTime = performance.now() - startTime;\n\n // Emit success telemetry (fire-and-forget, guarded)\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: true,\n issuer: payload.iss,\n kid: header.kid,\n durationMs: verifyTime,\n });\n\n return {\n ok: true,\n claims: payload,\n ...(validatedSnapshot && { subject_snapshot: validatedSnapshot }),\n perf: {\n verify_ms: verifyTime,\n ...(jwksFetchTime && { jwks_fetch_ms: jwksFetchTime }),\n },\n };\n } catch (err) {\n const durationMs = performance.now() - startTime;\n fireTelemetryHook(telemetry?.onReceiptVerified, {\n receiptHash: hashReceipt(receiptJws),\n valid: false,\n reasonCode: 'verification_error',\n durationMs,\n });\n return {\n ok: false,\n reason: 'verification_error',\n details: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","/**\n * Local receipt verification with schema validation\n *\n * Use this for verifying receipts when you have the public key locally,\n * without JWKS discovery.\n */\n\nimport { verify as jwsVerify } from '@peac/crypto';\nimport {\n parseReceiptClaims,\n type ReceiptClaimsType,\n type AttestationReceiptClaims,\n} from '@peac/schema';\nimport type { PolicyBindingStatus } from './verifier-types';\n\n/**\n * Structural type for CryptoError\n * Used instead of instanceof for robustness across ESM/CJS boundaries\n */\ninterface CryptoErrorLike {\n name: 'CryptoError';\n code: string;\n message: string;\n}\n\n/**\n * Structural check for CryptoError\n * More robust than instanceof across module boundaries (ESM/CJS, duplicate packages)\n */\nfunction isCryptoError(err: unknown): err is CryptoErrorLike {\n return (\n err !== null &&\n typeof err === 'object' &&\n 'name' in err &&\n err.name === 'CryptoError' &&\n 'code' in err &&\n typeof err.code === 'string' &&\n err.code.startsWith('CRYPTO_') &&\n 'message' in err &&\n typeof err.message === 'string'\n );\n}\n\n/**\n * Canonical error codes for local verification\n *\n * These map to E_* codes in specs/kernel/errors.json\n */\nexport type VerifyLocalErrorCode =\n | 'E_INVALID_SIGNATURE'\n | 'E_INVALID_FORMAT'\n | 'E_EXPIRED'\n | 'E_NOT_YET_VALID'\n | 'E_INVALID_ISSUER'\n | 'E_INVALID_AUDIENCE'\n | 'E_INVALID_SUBJECT'\n | 'E_INVALID_RECEIPT_ID'\n | 'E_MISSING_EXP'\n | 'E_INTERNAL';\n\n/**\n * Options for local verification\n */\nexport interface VerifyLocalOptions {\n /**\n * Expected issuer URL\n *\n * If provided, verification fails if receipt.iss does not match.\n */\n issuer?: string;\n\n /**\n * Expected audience URL\n *\n * If provided, verification fails if receipt.aud does not match.\n */\n audience?: string;\n\n /**\n * Expected subject URI\n *\n * If provided, verification fails if receipt.subject.uri does not match.\n * Binds the receipt to a specific resource/interaction target.\n */\n subjectUri?: string;\n\n /**\n * Expected receipt ID (rid)\n *\n * If provided, verification fails if receipt.rid does not match.\n * Useful for idempotency checks or correlating with prior receipts.\n */\n rid?: string;\n\n /**\n * Require expiration claim\n *\n * If true, receipts without exp claim are rejected.\n * Defaults to false.\n */\n requireExp?: boolean;\n\n /**\n * Current timestamp (Unix seconds)\n *\n * Defaults to Date.now() / 1000. Override for testing.\n */\n now?: number;\n\n /**\n * Maximum clock skew tolerance (seconds)\n *\n * Allows for clock drift between issuer and verifier.\n * Defaults to 300 (5 minutes).\n */\n maxClockSkew?: number;\n}\n\n/**\n * Result of successful local verification\n *\n * Discriminated union on `variant` -- callers narrow claims type via variant check:\n * if (result.valid && result.variant === 'commerce') { result.claims.amt }\n */\nexport type VerifyLocalSuccess =\n | {\n /** Verification succeeded */\n valid: true;\n /** Receipt variant (commerce = payment receipt, attestation = non-payment) */\n variant: 'commerce';\n /** Validated commerce receipt claims */\n claims: ReceiptClaimsType;\n /** Key ID from JWS header (for logging/indexing) */\n kid: string;\n /**\n * Policy binding status (DD-49).\n *\n * Always 'unavailable' for Wire 0.1 receipts (no policy digest on wire).\n * Wire 0.2 receipts with `peac.policy.digest` will report 'verified' or 'failed'.\n */\n policy_binding: PolicyBindingStatus;\n }\n | {\n /** Verification succeeded */\n valid: true;\n /** Receipt variant (commerce = payment receipt, attestation = non-payment) */\n variant: 'attestation';\n /** Validated attestation receipt claims */\n claims: AttestationReceiptClaims;\n /** Key ID from JWS header (for logging/indexing) */\n kid: string;\n /**\n * Policy binding status (DD-49).\n *\n * Always 'unavailable' for Wire 0.1 receipts (no policy digest on wire).\n * Wire 0.2 receipts with `peac.policy.digest` will report 'verified' or 'failed'.\n */\n policy_binding: PolicyBindingStatus;\n };\n\n/**\n * Result of failed local verification\n */\nexport interface VerifyLocalFailure {\n /** Verification failed */\n valid: false;\n\n /** Canonical error code (maps to specs/kernel/errors.json) */\n code: VerifyLocalErrorCode;\n\n /** Human-readable error message */\n message: string;\n\n /** Structured details for debugging (stable error code preserved in `code`) */\n details?: {\n /** Precise parse error code from unified parser (e.g. E_PARSE_COMMERCE_INVALID) */\n parse_code?: string;\n /** Zod validation issues (bounded, stable shape -- non-normative, may change) */\n issues?: ReadonlyArray<{ path: string; message: string }>;\n };\n}\n\n/**\n * Union type for local verification result\n */\nexport type VerifyLocalResult = VerifyLocalSuccess | VerifyLocalFailure;\n\n/**\n * Crypto error codes that indicate format/validation issues\n * These are CRYPTO_* internal codes from @peac/crypto, mapped to canonical E_* codes\n */\nconst FORMAT_ERROR_CODES = new Set([\n 'CRYPTO_INVALID_JWS_FORMAT',\n 'CRYPTO_INVALID_TYP',\n 'CRYPTO_INVALID_ALG',\n 'CRYPTO_INVALID_KEY_LENGTH',\n]);\n\n/** Max parse issues to include in details (prevents log bloat) */\nconst MAX_PARSE_ISSUES = 25;\n\n/**\n * Sanitize Zod issues into a bounded, stable structure.\n * Avoids exposing raw Zod internals or unbounded arrays in the public API.\n */\nfunction sanitizeParseIssues(\n issues: unknown\n): ReadonlyArray<{ path: string; message: string }> | undefined {\n if (!Array.isArray(issues)) return undefined;\n return issues.slice(0, MAX_PARSE_ISSUES).map((issue) => ({\n path: Array.isArray(issue?.path) ? issue.path.join('.') : '',\n message: typeof issue?.message === 'string' ? issue.message : String(issue),\n }));\n}\n\n/**\n * Verify a PEAC receipt locally with a known public key\n *\n * This function:\n * 1. Verifies the Ed25519 signature and header (typ, alg)\n * 2. Validates the receipt schema with Zod\n * 3. Checks issuer/audience/subject binding (if options provided)\n * 4. Checks time validity (exp/iat with clock skew tolerance)\n *\n * Use this when you have the issuer's public key and don't need JWKS discovery.\n * For JWKS-based verification, use `verifyReceipt()` instead.\n *\n * @param jws - JWS compact serialization\n * @param publicKey - Ed25519 public key (32 bytes)\n * @param options - Optional verification options (issuer, audience, subject, clock skew)\n * @returns Typed verification result\n *\n * @example\n * ```typescript\n * const result = await verifyLocal(jws, publicKey, {\n * issuer: 'https://api.example.com',\n * audience: 'https://client.example.com',\n * subjectUri: 'https://api.example.com/inference/v1',\n * });\n * if (result.valid) {\n * console.log('Issuer:', result.claims.iss);\n * console.log('Amount:', result.claims.amt, result.claims.cur);\n * console.log('Key ID:', result.kid);\n * } else {\n * console.error('Verification failed:', result.code, result.message);\n * }\n * ```\n */\nexport async function verifyLocal(\n jws: string,\n publicKey: Uint8Array,\n options: VerifyLocalOptions = {}\n): Promise<VerifyLocalResult> {\n const { issuer, audience, subjectUri, rid, requireExp = false, maxClockSkew = 300 } = options;\n const now = options.now ?? Math.floor(Date.now() / 1000);\n\n try {\n // 1. Verify signature and header (typ, alg validated by @peac/crypto)\n const result = await jwsVerify<unknown>(jws, publicKey);\n\n if (!result.valid) {\n return {\n valid: false,\n code: 'E_INVALID_SIGNATURE',\n message: 'Ed25519 signature verification failed',\n };\n }\n\n // 2. Validate schema (unified parser supports both commerce and attestation)\n const pr = parseReceiptClaims(result.payload);\n\n if (!pr.ok) {\n return {\n valid: false,\n code: 'E_INVALID_FORMAT',\n message: `Receipt schema validation failed: ${pr.error.message}`,\n details: { parse_code: pr.error.code, issues: sanitizeParseIssues(pr.error.issues) },\n };\n }\n\n // Shared binding checks (iss, aud, rid, iat, exp exist on both receipt types)\n // 3. Check issuer binding\n if (issuer !== undefined && pr.claims.iss !== issuer) {\n return {\n valid: false,\n code: 'E_INVALID_ISSUER',\n message: `Issuer mismatch: expected \"${issuer}\", got \"${pr.claims.iss}\"`,\n };\n }\n\n // 4. Check audience binding\n if (audience !== undefined && pr.claims.aud !== audience) {\n return {\n valid: false,\n code: 'E_INVALID_AUDIENCE',\n message: `Audience mismatch: expected \"${audience}\", got \"${pr.claims.aud}\"`,\n };\n }\n\n // 5. Check receipt ID binding\n if (rid !== undefined && pr.claims.rid !== rid) {\n return {\n valid: false,\n code: 'E_INVALID_RECEIPT_ID',\n message: `Receipt ID mismatch: expected \"${rid}\", got \"${pr.claims.rid}\"`,\n };\n }\n\n // 6. Check requireExp\n if (requireExp && pr.claims.exp === undefined) {\n return {\n valid: false,\n code: 'E_MISSING_EXP',\n message: 'Receipt missing required exp claim',\n };\n }\n\n // 7. Check not-yet-valid (iat with clock skew)\n if (pr.claims.iat > now + maxClockSkew) {\n return {\n valid: false,\n code: 'E_NOT_YET_VALID',\n message: `Receipt not yet valid: issued at ${new Date(pr.claims.iat * 1000).toISOString()}, now is ${new Date(now * 1000).toISOString()}`,\n };\n }\n\n // 8. Check expiry (with clock skew tolerance)\n if (pr.claims.exp !== undefined && pr.claims.exp < now - maxClockSkew) {\n return {\n valid: false,\n code: 'E_EXPIRED',\n message: `Receipt expired at ${new Date(pr.claims.exp * 1000).toISOString()}`,\n };\n }\n\n // 9. Subject binding + typed return (variant-branched, no unsafe casts)\n if (pr.variant === 'commerce') {\n const claims = pr.claims as ReceiptClaimsType;\n if (subjectUri !== undefined && claims.subject?.uri !== subjectUri) {\n return {\n valid: false,\n code: 'E_INVALID_SUBJECT',\n message: `Subject mismatch: expected \"${subjectUri}\", got \"${claims.subject?.uri ?? 'undefined'}\"`,\n };\n }\n // Wire 0.1: no policy digest on wire, always 'unavailable' (DD-49)\n return {\n valid: true,\n variant: 'commerce',\n claims,\n kid: result.header.kid,\n policy_binding: 'unavailable',\n };\n } else {\n const claims = pr.claims as AttestationReceiptClaims;\n if (subjectUri !== undefined && claims.sub !== subjectUri) {\n return {\n valid: false,\n code: 'E_INVALID_SUBJECT',\n message: `Subject mismatch: expected \"${subjectUri}\", got \"${claims.sub ?? 'undefined'}\"`,\n };\n }\n // Wire 0.1: no policy digest on wire, always 'unavailable' (DD-49)\n return {\n valid: true,\n variant: 'attestation',\n claims,\n kid: result.header.kid,\n policy_binding: 'unavailable',\n };\n }\n } catch (err) {\n // Handle typed CryptoError from @peac/crypto\n // Use structural check instead of instanceof for robustness across ESM/CJS boundaries\n // Map internal CRYPTO_* codes to canonical E_* codes\n if (isCryptoError(err)) {\n if (FORMAT_ERROR_CODES.has(err.code)) {\n return {\n valid: false,\n code: 'E_INVALID_FORMAT',\n message: err.message,\n };\n }\n if (err.code === 'CRYPTO_INVALID_SIGNATURE') {\n return {\n valid: false,\n code: 'E_INVALID_SIGNATURE',\n message: err.message,\n };\n }\n }\n\n // Handle JSON parse errors from malformed payloads\n // Use structural check for cross-boundary robustness (consistent with isCryptoError pattern)\n if (\n err !== null &&\n typeof err === 'object' &&\n 'name' in err &&\n (err as { name: unknown }).name === 'SyntaxError'\n ) {\n const syntaxMessage =\n 'message' in err && typeof (err as { message: unknown }).message === 'string'\n ? (err as { message: string }).message\n : 'Invalid JSON';\n return {\n valid: false,\n code: 'E_INVALID_FORMAT',\n message: `Invalid receipt payload: ${syntaxMessage}`,\n };\n }\n\n // All other errors -> E_INTERNAL\n // No message parsing - code-based mapping only\n const message = err instanceof Error ? err.message : String(err);\n return {\n valid: false,\n code: 'E_INTERNAL',\n message: `Unexpected verification error: ${message}`,\n };\n }\n}\n\n/**\n * Type guard: narrows a VerifyLocalResult to a commerce success.\n *\n * Use instead of manual `result.valid && result.variant === 'commerce'` checks\n * to get proper claims narrowing to ReceiptClaimsType.\n */\nexport function isCommerceResult(\n r: VerifyLocalResult\n): r is VerifyLocalSuccess & { variant: 'commerce' } {\n return r.valid === true && r.variant === 'commerce';\n}\n\n/**\n * Type guard: narrows a VerifyLocalResult to an attestation success.\n *\n * Use instead of manual `result.valid && result.variant === 'attestation'` checks\n * to get proper claims narrowing to AttestationReceiptClaims.\n */\nexport function isAttestationResult(\n r: VerifyLocalResult\n): r is VerifyLocalSuccess & { variant: 'attestation' } {\n return r.valid === true && r.variant === 'attestation';\n}\n","/**\n * HTTP header utilities for PEAC receipts and purpose\n */\n\nimport {\n PEAC_RECEIPT_HEADER,\n PEAC_PURPOSE_HEADER,\n PEAC_PURPOSE_APPLIED_HEADER,\n PEAC_PURPOSE_REASON_HEADER,\n parsePurposeHeader,\n type PurposeToken,\n type CanonicalPurpose,\n type PurposeReason,\n} from '@peac/schema';\n\n/**\n * Set PEAC-Receipt header on a response\n *\n * @param headers - Headers object (e.g., Response.headers)\n * @param receiptJws - JWS compact serialization\n */\nexport function setReceiptHeader(headers: Headers, receiptJws: string): void {\n headers.set(PEAC_RECEIPT_HEADER, receiptJws);\n}\n\n/**\n * Get PEAC-Receipt header from a request/response\n *\n * @param headers - Headers object\n * @returns JWS compact serialization, or null if not present\n */\nexport function getReceiptHeader(headers: Headers): string | null {\n return headers.get(PEAC_RECEIPT_HEADER);\n}\n\n/**\n * Set Vary: PEAC-Receipt header for caching\n *\n * @param headers - Response headers\n */\nexport function setVaryHeader(headers: Headers): void {\n const existing = headers.get('Vary');\n if (existing) {\n // Append to existing Vary header\n const varies = existing.split(',').map((v) => v.trim());\n if (!varies.includes(PEAC_RECEIPT_HEADER)) {\n headers.set('Vary', `${existing}, ${PEAC_RECEIPT_HEADER}`);\n }\n } else {\n headers.set('Vary', PEAC_RECEIPT_HEADER);\n }\n}\n\n// -----------------------------------------------------------------------------\n// Purpose Header Utilities (v0.9.24+)\n// -----------------------------------------------------------------------------\n\n/**\n * Get PEAC-Purpose header from a request\n *\n * Parses the comma-separated purpose token list into an array.\n * Normalizes tokens (lowercase, trim whitespace), deduplicates.\n *\n * @param headers - Request headers\n * @returns Array of normalized PurposeToken values, empty if header missing\n */\nexport function getPurposeHeader(headers: Headers): PurposeToken[] {\n const value = headers.get(PEAC_PURPOSE_HEADER);\n if (!value) {\n return [];\n }\n return parsePurposeHeader(value);\n}\n\n/**\n * Set PEAC-Purpose-Applied header on a response\n *\n * Indicates which purpose(s) were enforced for this request.\n *\n * @param headers - Response headers\n * @param purpose - Single canonical purpose that was enforced\n */\nexport function setPurposeAppliedHeader(headers: Headers, purpose: CanonicalPurpose): void {\n headers.set(PEAC_PURPOSE_APPLIED_HEADER, purpose);\n}\n\n/**\n * Set PEAC-Purpose-Reason header on a response\n *\n * Explains WHY the purpose was enforced as it was (audit trail).\n *\n * @param headers - Response headers\n * @param reason - Purpose reason enum value\n */\nexport function setPurposeReasonHeader(headers: Headers, reason: PurposeReason): void {\n headers.set(PEAC_PURPOSE_REASON_HEADER, reason);\n}\n\n/**\n * Set Vary: PEAC-Purpose header for caching\n *\n * If response behavior varies by declared purpose, MUST set this header.\n *\n * @param headers - Response headers\n */\nexport function setVaryPurposeHeader(headers: Headers): void {\n const existing = headers.get('Vary');\n if (existing) {\n const varies = existing.split(',').map((v) => v.trim());\n if (!varies.includes(PEAC_PURPOSE_HEADER)) {\n headers.set('Vary', `${existing}, ${PEAC_PURPOSE_HEADER}`);\n }\n } else {\n headers.set('Vary', PEAC_PURPOSE_HEADER);\n }\n}\n","/**\n * PEAC Discovery - Issuer Configuration and Policy Manifest\n *\n * This module provides functions for:\n * - Issuer configuration discovery (/.well-known/peac-issuer.json)\n * - Policy manifest parsing (/.well-known/peac.txt)\n *\n * @see docs/specs/PEAC-ISSUER.md\n * @see docs/specs/PEAC-TXT.md\n */\n\nimport {\n PEACIssuerConfig,\n PEACPolicyManifest,\n PEACDiscovery,\n PEAC_ISSUER_CONFIG_PATH,\n PEAC_ISSUER_CONFIG_MAX_BYTES,\n PEAC_POLICY_PATH,\n PEAC_POLICY_FALLBACK_PATH,\n PEAC_POLICY_MAX_BYTES,\n} from '@peac/schema';\n\n// ============================================================================\n// Issuer Configuration (/.well-known/peac-issuer.json)\n// ============================================================================\n\n/**\n * Parse PEAC issuer configuration from JSON\n *\n * @param json - JSON string or object\n * @returns Parsed issuer configuration\n * @throws Error if validation fails\n */\nexport function parseIssuerConfig(json: string | object): PEACIssuerConfig {\n let config: unknown;\n\n if (typeof json === 'string') {\n const bytes = new TextEncoder().encode(json).length;\n if (bytes > PEAC_ISSUER_CONFIG_MAX_BYTES) {\n throw new Error(`Issuer config exceeds ${PEAC_ISSUER_CONFIG_MAX_BYTES} bytes (got ${bytes})`);\n }\n\n try {\n config = JSON.parse(json);\n } catch {\n throw new Error('Issuer config is not valid JSON');\n }\n } else {\n config = json;\n }\n\n if (typeof config !== 'object' || config === null) {\n throw new Error('Issuer config must be an object');\n }\n\n const obj = config as Record<string, unknown>;\n\n // Validate required fields\n if (typeof obj.version !== 'string' || !obj.version) {\n throw new Error('Missing required field: version');\n }\n if (typeof obj.issuer !== 'string' || !obj.issuer) {\n throw new Error('Missing required field: issuer');\n }\n if (typeof obj.jwks_uri !== 'string' || !obj.jwks_uri) {\n throw new Error('Missing required field: jwks_uri');\n }\n\n // Validate URL fields\n if (!obj.issuer.startsWith('https://')) {\n throw new Error('issuer must be an HTTPS URL');\n }\n if (!obj.jwks_uri.startsWith('https://')) {\n throw new Error('jwks_uri must be an HTTPS URL');\n }\n\n // Validate optional fields\n if (obj.verify_endpoint !== undefined) {\n if (typeof obj.verify_endpoint !== 'string') {\n throw new Error('verify_endpoint must be a string');\n }\n if (!obj.verify_endpoint.startsWith('https://')) {\n throw new Error('verify_endpoint must be an HTTPS URL');\n }\n }\n\n if (obj.receipt_versions !== undefined) {\n if (!Array.isArray(obj.receipt_versions)) {\n throw new Error('receipt_versions must be an array');\n }\n }\n\n if (obj.algorithms !== undefined) {\n if (!Array.isArray(obj.algorithms)) {\n throw new Error('algorithms must be an array');\n }\n }\n\n if (obj.payment_rails !== undefined) {\n if (!Array.isArray(obj.payment_rails)) {\n throw new Error('payment_rails must be an array');\n }\n }\n\n return {\n version: obj.version,\n issuer: obj.issuer,\n jwks_uri: obj.jwks_uri,\n verify_endpoint: obj.verify_endpoint as string | undefined,\n receipt_versions: obj.receipt_versions as string[] | undefined,\n algorithms: obj.algorithms as string[] | undefined,\n payment_rails: obj.payment_rails as string[] | undefined,\n security_contact: obj.security_contact as string | undefined,\n };\n}\n\n/**\n * Fetch PEAC issuer configuration from an issuer URL\n *\n * @param issuerUrl - Issuer URL (https://)\n * @returns Parsed issuer configuration\n * @throws Error if fetch or validation fails\n */\nexport async function fetchIssuerConfig(issuerUrl: string): Promise<PEACIssuerConfig> {\n if (!issuerUrl.startsWith('https://')) {\n throw new Error('Issuer URL must be https://');\n }\n\n // Remove trailing slash for consistent URL construction\n const baseUrl = issuerUrl.replace(/\\/$/, '');\n const configUrl = `${baseUrl}${PEAC_ISSUER_CONFIG_PATH}`;\n\n try {\n const resp = await fetch(configUrl, {\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(10000),\n });\n\n if (!resp.ok) {\n throw new Error(`Issuer config fetch failed: ${resp.status}`);\n }\n\n const text = await resp.text();\n const config = parseIssuerConfig(text);\n\n // Verify issuer matches\n const normalizedExpected = baseUrl.replace(/\\/$/, '');\n const normalizedActual = config.issuer.replace(/\\/$/, '');\n if (normalizedActual !== normalizedExpected) {\n throw new Error(`Issuer mismatch: expected ${normalizedExpected}, got ${normalizedActual}`);\n }\n\n return config;\n } catch (err) {\n throw new Error(\n `Failed to fetch issuer config from ${issuerUrl}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err }\n );\n }\n}\n\n// ============================================================================\n// Policy Manifest (/.well-known/peac.txt)\n// ============================================================================\n\n/**\n * Detect if content is JSON or YAML\n */\nfunction isJsonContent(text: string, contentType?: string): boolean {\n if (contentType?.includes('application/json')) {\n return true;\n }\n const firstChar = text.trimStart()[0];\n return firstChar === '{';\n}\n\n/**\n * Parse PEAC policy manifest from YAML or JSON\n *\n * @param text - Policy manifest text (YAML or JSON)\n * @param contentType - Optional Content-Type header value\n * @returns Parsed policy manifest\n * @throws Error if validation fails\n */\nexport function parsePolicyManifest(text: string, contentType?: string): PEACPolicyManifest {\n const bytes = new TextEncoder().encode(text).length;\n if (bytes > PEAC_POLICY_MAX_BYTES) {\n throw new Error(`Policy manifest exceeds ${PEAC_POLICY_MAX_BYTES} bytes (got ${bytes})`);\n }\n\n let manifest: Record<string, unknown>;\n\n if (isJsonContent(text, contentType)) {\n // Parse as JSON\n try {\n manifest = JSON.parse(text);\n } catch {\n throw new Error('Policy manifest is not valid JSON');\n }\n } else {\n // Parse as simple YAML (key: value format)\n manifest = parseSimpleYaml(text);\n }\n\n // Validate required fields\n if (typeof manifest.version !== 'string' || !manifest.version) {\n throw new Error('Missing required field: version');\n }\n\n // Validate version format: must be peac-policy/<major>.<minor>\n if (!manifest.version.startsWith('peac-policy/')) {\n throw new Error(\n `Invalid version format: \"${manifest.version}\". Must start with \"peac-policy/\" (e.g., \"peac-policy/0.1\")`\n );\n }\n\n if (manifest.usage !== 'open' && manifest.usage !== 'conditional') {\n throw new Error('Missing or invalid field: usage (must be \"open\" or \"conditional\")');\n }\n\n return {\n version: manifest.version,\n usage: manifest.usage as 'open' | 'conditional',\n purposes: manifest.purposes as string[] | undefined,\n receipts: manifest.receipts as 'required' | 'optional' | 'omit' | undefined,\n attribution: manifest.attribution as 'required' | 'optional' | 'none' | undefined,\n rate_limit: manifest.rate_limit as string | undefined,\n daily_limit: manifest.daily_limit as number | undefined,\n negotiate: manifest.negotiate as string | undefined,\n contact: manifest.contact as string | undefined,\n license: manifest.license as string | undefined,\n price: manifest.price as number | undefined,\n currency: manifest.currency as string | undefined,\n payment_methods: manifest.payment_methods as string[] | undefined,\n payment_endpoint: manifest.payment_endpoint as string | undefined,\n };\n}\n\n/**\n * Parse simple YAML (key: value format, no complex features)\n * Rejects YAML features that are security risks (anchors, aliases, tags)\n */\nfunction parseSimpleYaml(text: string): Record<string, unknown> {\n const lines = text.split('\\n');\n const result: Record<string, unknown> = {};\n\n // Security: reject YAML features that are dangerous\n // Check merge keys first (they contain * which would trigger anchor check)\n if (text.includes('<<:')) {\n throw new Error('YAML merge keys are not allowed');\n }\n if (text.includes('&') || text.includes('*')) {\n throw new Error('YAML anchors and aliases are not allowed');\n }\n if (/!\\w+/.test(text)) {\n throw new Error('YAML custom tags are not allowed');\n }\n\n // Count document separators\n const docSeparators = text.match(/^---$/gm);\n if (docSeparators && docSeparators.length > 1) {\n throw new Error('Multi-document YAML is not allowed');\n }\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines, comments, and document markers\n if (!trimmed || trimmed.startsWith('#') || trimmed === '---') {\n continue;\n }\n\n // Parse key: value\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = trimmed.slice(0, colonIndex).trim();\n let value: unknown = trimmed.slice(colonIndex + 1).trim();\n\n // Parse value types\n if (value === '') {\n value = undefined;\n } else if (typeof value === 'string') {\n // Remove quotes if present\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n // Parse arrays [a, b, c]\n else if (value.startsWith('[') && value.endsWith(']')) {\n const inner = value.slice(1, -1);\n value = inner\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n }\n // Parse numbers\n else if (/^-?\\d+(\\.\\d+)?$/.test(value)) {\n value = parseFloat(value);\n }\n // Parse booleans\n else if (value === 'true') {\n value = true;\n } else if (value === 'false') {\n value = false;\n }\n }\n\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Fetch PEAC policy manifest from a domain\n *\n * @param baseUrl - Base URL (https://example.com)\n * @returns Parsed policy manifest\n * @throws Error if fetch or validation fails\n */\nexport async function fetchPolicyManifest(baseUrl: string): Promise<PEACPolicyManifest> {\n if (!baseUrl.startsWith('https://') && !baseUrl.startsWith('http://localhost')) {\n throw new Error('Base URL must be https://');\n }\n\n const normalizedBase = baseUrl.replace(/\\/$/, '');\n const primaryUrl = `${normalizedBase}${PEAC_POLICY_PATH}`;\n const fallbackUrl = `${normalizedBase}${PEAC_POLICY_FALLBACK_PATH}`;\n\n // Try primary location first\n try {\n const resp = await fetch(primaryUrl, {\n headers: { Accept: 'text/plain, application/json' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (resp.ok) {\n const text = await resp.text();\n const contentType = resp.headers.get('content-type') || undefined;\n return parsePolicyManifest(text, contentType);\n }\n\n // If 404, try fallback\n if (resp.status === 404) {\n const fallbackResp = await fetch(fallbackUrl, {\n headers: { Accept: 'text/plain, application/json' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (fallbackResp.ok) {\n const text = await fallbackResp.text();\n const contentType = fallbackResp.headers.get('content-type') || undefined;\n return parsePolicyManifest(text, contentType);\n }\n\n throw new Error('Policy manifest not found at primary or fallback location');\n }\n\n throw new Error(`Policy manifest fetch failed: ${resp.status}`);\n } catch (err) {\n throw new Error(\n `Failed to fetch policy manifest from ${baseUrl}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err }\n );\n }\n}\n\n// ============================================================================\n// Deprecated Legacy API (for backward compatibility)\n// ============================================================================\n\n/**\n * @deprecated Use parseIssuerConfig instead. Will be removed in v1.0.\n *\n * Parse a PEAC discovery manifest from YAML-like text.\n * This function is maintained for backward compatibility only.\n */\nexport function parseDiscovery(text: string): PEACDiscovery {\n const bytes = new TextEncoder().encode(text).length;\n if (bytes > 2000) {\n throw new Error(`Discovery manifest exceeds 2000 bytes (got ${bytes})`);\n }\n\n const lines = text.trim().split('\\n');\n if (lines.length > 20) {\n throw new Error(`Discovery manifest exceeds 20 lines (got ${lines.length})`);\n }\n\n const discovery: Partial<PEACIssuerConfig> = {};\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n if (trimmed.includes(':')) {\n const [key, ...valueParts] = trimmed.split(':');\n const value = valueParts.join(':').trim();\n\n switch (key.trim()) {\n case 'version':\n discovery.version = value;\n break;\n case 'issuer':\n discovery.issuer = value;\n break;\n case 'verify':\n discovery.verify_endpoint = value;\n break;\n case 'jwks':\n discovery.jwks_uri = value;\n break;\n case 'security':\n discovery.security_contact = value;\n break;\n }\n }\n }\n\n // Validate required fields\n if (!discovery.version) throw new Error('Missing required field: version');\n if (!discovery.issuer) throw new Error('Missing required field: issuer');\n if (!discovery.verify_endpoint) throw new Error('Missing required field: verify');\n if (!discovery.jwks_uri) throw new Error('Missing required field: jwks');\n\n return discovery as PEACDiscovery;\n}\n\n/**\n * @deprecated Use fetchIssuerConfig instead. Will be removed in v1.0.\n *\n * Fetch and parse PEAC discovery from an issuer URL.\n * This function is maintained for backward compatibility only.\n */\nexport async function fetchDiscovery(issuerUrl: string): Promise<PEACDiscovery> {\n if (!issuerUrl.startsWith('https://')) {\n throw new Error('Issuer URL must be https://');\n }\n\n const discoveryUrl = `${issuerUrl}/.well-known/peac.txt`;\n\n try {\n const resp = await fetch(discoveryUrl, {\n headers: { Accept: 'text/plain' },\n signal: AbortSignal.timeout(5000),\n });\n\n if (!resp.ok) {\n throw new Error(`Discovery fetch failed: ${resp.status}`);\n }\n\n const text = await resp.text();\n return parseDiscovery(text);\n } catch (err) {\n throw new Error(\n `Failed to fetch discovery from ${issuerUrl}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err }\n );\n }\n}\n","/**\n * PEAC Verifier Types\n *\n * Types for verification policy, trust pinning, and verification reports\n * per VERIFIER-SECURITY-MODEL.md, TRUST-PINNING-POLICY.md, and\n * VERIFICATION-REPORT-FORMAT.md\n *\n * @packageDocumentation\n */\n\nimport {\n VERIFIER_LIMITS,\n VERIFIER_NETWORK,\n VERIFIER_POLICY_VERSION,\n VERIFICATION_REPORT_VERSION,\n} from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Policy Binding (DD-49)\n// ---------------------------------------------------------------------------\n\n/**\n * Three-state policy binding status (DD-49)\n *\n * - 'verified': Policy digest in receipt matches local policy bytes (Wire 0.2+)\n * - 'failed': Policy digest mismatch (Wire 0.2+)\n * - 'unavailable': No policy digest in receipt or no policy bytes available.\n * Always 'unavailable' for Wire 0.1 receipts.\n */\nexport type PolicyBindingStatus = 'verified' | 'failed' | 'unavailable';\n\n// ---------------------------------------------------------------------------\n// Verification Mode\n// ---------------------------------------------------------------------------\n\n/**\n * Verification mode per VERIFIER-SECURITY-MODEL.md\n */\nexport type VerificationMode = 'offline_only' | 'offline_preferred' | 'network_allowed';\n\n// ---------------------------------------------------------------------------\n// Trust Pinning\n// ---------------------------------------------------------------------------\n\n/**\n * Pinned key entry per TRUST-PINNING-POLICY.md\n *\n * Uses RFC 7638 JWK Thumbprint with base64url encoding (NOT hex).\n * SHA-256 thumbprints are 43 characters in base64url.\n *\n * For offline verification, include either `public_key` (base64url 32 bytes)\n * or the full `jwk` object. If only thumbprint is provided, the key can only\n * be pin-checked after fetching JWKS (requires network mode).\n */\nexport interface PinnedKey {\n /** Issuer origin (https://host[:port]) */\n issuer: string;\n /** Key identifier (kid from JWKS) */\n kid: string;\n /** RFC 7638 JWK Thumbprint, SHA-256, base64url-encoded (43 chars) */\n jwk_thumbprint_sha256: string;\n /**\n * Ed25519 public key bytes, base64url-encoded (43 chars for 32 bytes).\n * If provided, enables offline verification without JWKS fetch.\n */\n public_key?: string;\n /**\n * Full JWK for offline verification.\n * If provided, enables offline verification without JWKS fetch.\n * Takes precedence over public_key.\n */\n jwk?: {\n kty: 'OKP';\n crv: 'Ed25519';\n x: string;\n kid?: string;\n };\n}\n\n/**\n * Issuer allowlist entry\n *\n * Full origin format: https://host[:port]\n * The port is only included if non-standard (not 443 for HTTPS).\n */\nexport type IssuerOrigin = string;\n\n// ---------------------------------------------------------------------------\n// Verifier Limits\n// ---------------------------------------------------------------------------\n\n/**\n * Verifier security limits\n */\nexport interface VerifierLimits {\n /** Maximum receipt size in bytes */\n max_receipt_bytes: number;\n /** Maximum JWKS document size in bytes */\n max_jwks_bytes: number;\n /** Maximum number of keys in a JWKS */\n max_jwks_keys: number;\n /** Maximum redirects to follow */\n max_redirects: number;\n /** Network fetch timeout in milliseconds */\n fetch_timeout_ms: number;\n /** Maximum extension size in bytes */\n max_extension_bytes: number;\n}\n\n/**\n * Default verifier limits from VERIFIER-SECURITY-MODEL.md\n */\nexport const DEFAULT_VERIFIER_LIMITS: VerifierLimits = {\n max_receipt_bytes: VERIFIER_LIMITS.maxReceiptBytes,\n max_jwks_bytes: VERIFIER_LIMITS.maxJwksBytes,\n max_jwks_keys: VERIFIER_LIMITS.maxJwksKeys,\n max_redirects: VERIFIER_LIMITS.maxRedirects,\n fetch_timeout_ms: VERIFIER_LIMITS.fetchTimeoutMs,\n max_extension_bytes: VERIFIER_LIMITS.maxExtensionBytes,\n};\n\n// ---------------------------------------------------------------------------\n// Network Security\n// ---------------------------------------------------------------------------\n\n/**\n * Network security settings\n */\nexport interface NetworkSecurity {\n /** Only allow HTTPS URLs */\n https_only: boolean;\n /** Block requests to private IP ranges */\n block_private_ips: boolean;\n /** Allow redirects */\n allow_redirects: boolean;\n /**\n * Allow cross-origin redirects (default: true for CDN compatibility).\n * When true, redirects to different origins are allowed if they pass SSRF checks.\n * When false, only same-origin redirects are allowed.\n */\n allow_cross_origin_redirects?: boolean;\n /**\n * Behavior on DNS resolution failure (default: 'block' for security).\n * - 'block': Treat DNS failure as blocked (fail-closed, more secure)\n * - 'fail': Return fetch error (allows retry, less restrictive)\n */\n dns_failure_behavior?: 'block' | 'fail';\n}\n\n/**\n * Default network security settings from VERIFIER-SECURITY-MODEL.md\n */\nexport const DEFAULT_NETWORK_SECURITY: NetworkSecurity = {\n https_only: VERIFIER_NETWORK.httpsOnly,\n block_private_ips: VERIFIER_NETWORK.blockPrivateIps,\n allow_redirects: VERIFIER_NETWORK.allowRedirects,\n allow_cross_origin_redirects: true, // Allow for CDN compatibility\n dns_failure_behavior: 'block', // Fail-closed by default\n};\n\n// ---------------------------------------------------------------------------\n// Verifier Policy\n// ---------------------------------------------------------------------------\n\n/**\n * Verifier policy configuration\n *\n * This structure echoes the policy used for verification, making trust\n * decisions auditable per VERIFICATION-REPORT-FORMAT.md.\n */\nexport interface VerifierPolicy {\n /** Policy schema version */\n policy_version: typeof VERIFIER_POLICY_VERSION;\n /** Verification mode */\n mode: VerificationMode;\n /** Allowed issuer origins (optional, if empty all issuers allowed) */\n issuer_allowlist?: IssuerOrigin[];\n /** Pinned keys for offline verification */\n pinned_keys?: PinnedKey[];\n /** Effective security limits */\n limits: VerifierLimits;\n /** Network security settings */\n network: NetworkSecurity;\n}\n\n/**\n * Create a default verifier policy\n */\nexport function createDefaultPolicy(mode: VerificationMode): VerifierPolicy {\n return {\n policy_version: VERIFIER_POLICY_VERSION,\n mode,\n limits: { ...DEFAULT_VERIFIER_LIMITS },\n network: { ...DEFAULT_NETWORK_SECURITY },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Verification Checks\n// ---------------------------------------------------------------------------\n\n/**\n * Check status\n */\nexport type CheckStatus = 'pass' | 'fail' | 'skip';\n\n/**\n * Standard check IDs per VERIFIER-SECURITY-MODEL.md (in order).\n *\n * APPEND-ONLY CONTRACT:\n * - New checks MUST only be appended to the end of this array.\n * - Existing entries MUST NOT be removed, reordered, or renamed.\n * - Downstream consumers (conformance fixtures, report builders, dashboards)\n * depend on stable indices and the `as const` tuple type.\n * - Breaking this contract invalidates all existing verification reports\n * and conformance vectors.\n * - Enforced by prefix-pinning test in verification-report.test.ts.\n *\n * OUTPUT ORDER vs EVALUATION ORDER:\n * This array defines the report output (render) order only. Verifier\n * implementations MAY evaluate checks in any order internally (e.g.,\n * checking signature before discovery). The report builder normalizes\n * results into this canonical order regardless of evaluation sequence.\n *\n * To add a new check:\n * 1. Append the new ID to the end of this array.\n * 2. Update the conformance fixture: specs/conformance/fixtures/verifier/verification-report.json\n * 3. Update the spec: docs/specs/VERIFICATION-REPORT-FORMAT.md (Section 5.5)\n * 4. Update the spec: docs/specs/VERIFIER-SECURITY-MODEL.md (Section 6.1)\n */\nexport const CHECK_IDS = [\n 'jws.parse',\n 'limits.receipt_bytes',\n 'jws.protected_header',\n 'claims.schema_unverified',\n 'issuer.trust_policy',\n 'issuer.discovery',\n 'key.resolve',\n 'jws.signature',\n 'claims.time_window',\n 'extensions.limits',\n 'transport.profile_binding',\n 'policy.binding',\n] as const;\n\nexport type CheckId = (typeof CHECK_IDS)[number];\n\n/**\n * Single verification check result\n */\nexport interface CheckResult {\n /** Stable check identifier */\n id: CheckId;\n /** Check status */\n status: CheckStatus;\n /** Machine-readable details (optional) */\n detail?: Record<string, unknown>;\n /** Stable error code (if failed) */\n error_code?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report Input\n// ---------------------------------------------------------------------------\n\n/**\n * Input type for verification\n */\nexport type InputType = 'receipt_jws' | 'bundle_entry';\n\n/**\n * Digest object (algorithm + value)\n */\nexport interface DigestObject {\n /** Hash algorithm */\n alg: 'sha-256';\n /** Hash value in lowercase hex */\n value: string;\n}\n\n/**\n * Bundle context for bundle_entry input type\n */\nexport interface BundleContext {\n /** Digest of bundle bytes */\n bundle_digest: DigestObject;\n /** 0-based entry index */\n entry_index: number;\n /** Stable entry ID (optional) */\n entry_id?: string;\n}\n\n/**\n * Verification input descriptor\n */\nexport interface VerificationInput {\n /** Input type */\n type: InputType;\n /** Digest of receipt bytes */\n receipt_digest: DigestObject;\n /** Bundle context (if type = bundle_entry) */\n bundle?: BundleContext;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report Result\n// ---------------------------------------------------------------------------\n\n/**\n * Result severity\n */\nexport type ResultSeverity = 'info' | 'warning' | 'error';\n\n/**\n * Reason codes per VERIFIER-SECURITY-MODEL.md\n */\nexport type ReasonCode =\n | 'ok'\n | 'receipt_too_large'\n | 'malformed_receipt'\n | 'signature_invalid'\n | 'issuer_not_allowed'\n | 'key_not_found'\n | 'key_fetch_blocked'\n | 'key_fetch_failed'\n | 'key_fetch_timeout'\n | 'pointer_fetch_blocked'\n | 'pointer_fetch_failed'\n | 'pointer_fetch_timeout'\n | 'pointer_fetch_too_large'\n | 'pointer_digest_mismatch'\n | 'jwks_too_large'\n | 'jwks_too_many_keys'\n | 'expired'\n | 'not_yet_valid'\n | 'audience_mismatch'\n | 'schema_invalid'\n | 'policy_violation'\n | 'extension_too_large'\n | 'invalid_transport';\n\n/**\n * High-level verification result\n */\nexport interface VerificationResult {\n /** Overall verification result */\n valid: boolean;\n /** Stable reason code */\n reason: ReasonCode;\n /** Result severity */\n severity: ResultSeverity;\n /** Receipt wire format (e.g., peac-receipt/0.1) */\n receipt_type: string;\n /** Normalized issuer origin (optional) */\n issuer?: string;\n /** Key ID used for verification (optional) */\n kid?: string;\n /**\n * Policy binding status (DD-49).\n *\n * Always 'unavailable' for Wire 0.1 receipts.\n * Wire 0.2+ receipts with `peac.policy.digest` will report 'verified' or 'failed'.\n *\n * This field is ALWAYS present (never undefined). Consumers can rely on it\n * without null checks.\n */\n policy_binding: PolicyBindingStatus;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report Artifacts\n// ---------------------------------------------------------------------------\n\n/**\n * Pointer resolution details\n */\nexport interface PointerArtifact {\n /** Pointer URL */\n url: string;\n /** Expected digest from header */\n expected_digest: DigestObject;\n /** Actual digest of fetched content */\n actual_digest?: DigestObject;\n /** Whether digests matched */\n digest_matched?: boolean;\n}\n\n/**\n * Key source for enterprise debuggability\n */\nexport type KeySource = 'pinned' | 'jwks_fetch';\n\n/**\n * Additional verification artifacts\n *\n * Artifacts are divided into two categories:\n *\n * **Deterministic artifacts** (same inputs and policy -> same values):\n * - `issuer_key_source`: Always determined by policy and receipt\n * - `issuer_key_thumbprint`: Computed from the signing key\n * - `normalized_claims_digest`: Computed from the claims\n * - `receipt_pointer`: Derived from the input pointer header\n *\n * **Non-deterministic artifacts** (may vary based on runtime state):\n * - `issuer_jwks_digest`: Only present when JWKS is fetched fresh (not from cache)\n *\n * Use `buildDeterministic()` to exclude non-deterministic artifacts for\n * reproducible report generation.\n */\nexport interface VerificationArtifacts {\n /**\n * Digest of JWKS used for verification.\n *\n * NON-DETERMINISTIC: Only present when JWKS is fetched fresh (not from cache).\n * Excluded by `buildDeterministic()`.\n */\n issuer_jwks_digest?: DigestObject;\n /** Source of the signing key used for verification (DETERMINISTIC) */\n issuer_key_source?: KeySource;\n /** RFC 7638 JWK Thumbprint (SHA-256, base64url) of the key used (DETERMINISTIC) */\n issuer_key_thumbprint?: string;\n /** Digest of canonicalized claims (DETERMINISTIC) */\n normalized_claims_digest?: DigestObject;\n /** Pointer resolution details (DETERMINISTIC) */\n receipt_pointer?: PointerArtifact;\n}\n\n/**\n * Keys of artifacts that are non-deterministic (depend on runtime state)\n */\nexport const NON_DETERMINISTIC_ARTIFACT_KEYS: (keyof VerificationArtifacts)[] = [\n 'issuer_jwks_digest',\n];\n\n// ---------------------------------------------------------------------------\n// Verification Report Meta\n// ---------------------------------------------------------------------------\n\n/**\n * Verifier implementation info\n */\nexport interface VerifierInfo {\n /** Verifier name */\n name: string;\n /** Verifier version */\n version: string;\n}\n\n/**\n * Non-deterministic metadata (MUST be excluded from report hashes)\n */\nexport interface VerificationMeta {\n /** RFC 3339 timestamp when report was generated */\n generated_at?: string;\n /** Verifier implementation info */\n verifier?: VerifierInfo;\n}\n\n// ---------------------------------------------------------------------------\n// Verification Report\n// ---------------------------------------------------------------------------\n\n/**\n * PEAC Verification Report per VERIFICATION-REPORT-FORMAT.md\n *\n * This report is designed to be:\n * - Portable: shareable across organizations\n * - Deterministic: reproducible given same inputs\n * - Safe: bounded resource usage\n * - Policy-aware: trust decisions are explicit\n */\nexport interface VerificationReport {\n /** Format version identifier (REQUIRED) */\n report_version: typeof VERIFICATION_REPORT_VERSION;\n /** What was verified (REQUIRED) */\n input: VerificationInput;\n /** Policy used for verification (REQUIRED) */\n policy: VerifierPolicy;\n /** High-level outcome (REQUIRED) */\n result: VerificationResult;\n /** Ordered list of checks (REQUIRED) */\n checks: CheckResult[];\n /** Additional outputs (OPTIONAL) */\n artifacts?: VerificationArtifacts;\n /** Non-deterministic fields (OPTIONAL, excluded from hashes) */\n meta?: VerificationMeta;\n}\n\n// ---------------------------------------------------------------------------\n// Report Builder Utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Create a digest object from a hex string\n */\nexport function createDigest(hexValue: string): DigestObject {\n return {\n alg: 'sha-256',\n value: hexValue.toLowerCase(),\n };\n}\n\n/**\n * Create an empty verification report structure\n */\nexport function createEmptyReport(\n policy: VerifierPolicy\n): Omit<VerificationReport, 'input' | 'result' | 'checks'> {\n return {\n report_version: VERIFICATION_REPORT_VERSION,\n policy,\n };\n}\n\n/**\n * Map SSRF fetch error reason to verification reason code\n */\nexport function ssrfErrorToReasonCode(\n ssrfReason: string,\n fetchType: 'key' | 'pointer'\n): ReasonCode {\n const prefix = fetchType === 'key' ? 'key_fetch' : 'pointer_fetch';\n\n switch (ssrfReason) {\n case 'not_https':\n case 'private_ip':\n case 'loopback':\n case 'link_local':\n case 'cross_origin_redirect':\n case 'dns_failure':\n return `${prefix}_blocked` as ReasonCode;\n case 'timeout':\n return `${prefix}_timeout` as ReasonCode;\n case 'response_too_large':\n return fetchType === 'pointer' ? 'pointer_fetch_too_large' : 'jwks_too_large';\n case 'jwks_too_many_keys':\n return 'jwks_too_many_keys';\n case 'too_many_redirects':\n case 'scheme_downgrade':\n case 'network_error':\n case 'invalid_url':\n default:\n return `${prefix}_failed` as ReasonCode;\n }\n}\n\n/**\n * Map reason code to severity\n */\nexport function reasonCodeToSeverity(reason: ReasonCode): ResultSeverity {\n if (reason === 'ok') return 'info';\n return 'error';\n}\n\n/**\n * Map reason code to error code\n */\nexport function reasonCodeToErrorCode(reason: ReasonCode): string {\n const mapping: Record<ReasonCode, string> = {\n ok: '',\n receipt_too_large: 'E_VERIFY_RECEIPT_TOO_LARGE',\n malformed_receipt: 'E_VERIFY_MALFORMED_RECEIPT',\n signature_invalid: 'E_VERIFY_SIGNATURE_INVALID',\n issuer_not_allowed: 'E_VERIFY_ISSUER_NOT_ALLOWED',\n key_not_found: 'E_VERIFY_KEY_NOT_FOUND',\n key_fetch_blocked: 'E_VERIFY_KEY_FETCH_BLOCKED',\n key_fetch_failed: 'E_VERIFY_KEY_FETCH_FAILED',\n key_fetch_timeout: 'E_VERIFY_KEY_FETCH_TIMEOUT',\n pointer_fetch_blocked: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n pointer_fetch_failed: 'E_VERIFY_POINTER_FETCH_FAILED',\n pointer_fetch_timeout: 'E_VERIFY_POINTER_FETCH_TIMEOUT',\n pointer_fetch_too_large: 'E_VERIFY_POINTER_FETCH_TOO_LARGE',\n pointer_digest_mismatch: 'E_VERIFY_POINTER_DIGEST_MISMATCH',\n jwks_too_large: 'E_VERIFY_JWKS_TOO_LARGE',\n jwks_too_many_keys: 'E_VERIFY_JWKS_TOO_MANY_KEYS',\n expired: 'E_VERIFY_EXPIRED',\n not_yet_valid: 'E_VERIFY_NOT_YET_VALID',\n audience_mismatch: 'E_VERIFY_AUDIENCE_MISMATCH',\n schema_invalid: 'E_VERIFY_SCHEMA_INVALID',\n policy_violation: 'E_VERIFY_POLICY_VIOLATION',\n extension_too_large: 'E_VERIFY_EXTENSION_TOO_LARGE',\n invalid_transport: 'E_VERIFY_INVALID_TRANSPORT',\n };\n return mapping[reason] || 'E_VERIFY_POLICY_VIOLATION';\n}\n","/**\n * SSRF-safe fetch utility for PEAC verifiers\n *\n * Implements SSRF protection per VERIFIER-SECURITY-MODEL.md:\n * - HTTPS only\n * - Block private IP ranges (RFC 1918)\n * - Block link-local addresses\n * - Block loopback addresses\n * - Redirect limits and scheme downgrade protection\n *\n * ## Security Model: Best-Effort Protection\n *\n * **IMPORTANT**: SSRF protection is BEST-EFFORT, not a guarantee. The level of\n * protection depends on the runtime environment's capabilities. In environments\n * without DNS pre-resolution (browsers, edge workers), protection is limited to\n * URL scheme validation and response limits. Defense-in-depth: combine with\n * network-level controls (firewalls, egress filtering) in production.\n *\n * ## Hard Invariants (ALWAYS Enforced)\n *\n * These protections are enforced in ALL runtimes:\n *\n * | Invariant | Enforcement |\n * |-----------|-------------|\n * | HTTPS only | URL scheme validation before fetch |\n * | No redirects (pointer fetch) | `redirect: 'manual'` + policy check |\n * | Response size cap | Streaming with byte counter, abort on limit |\n * | Timeout | AbortController with configurable timeout |\n * | No scheme downgrade | Redirect target scheme validation |\n *\n * ## Runtime-Dependent Protections\n *\n * These protections require DNS pre-resolution capability:\n *\n * | Protection | Requires |\n * |------------|----------|\n * | Private IP blocking (RFC 1918) | DNS pre-resolution |\n * | Loopback blocking (127.0.0.0/8) | DNS pre-resolution |\n * | Link-local blocking (169.254.0.0/16) | DNS pre-resolution |\n *\n * ## Runtime Capability Model\n *\n * SSRF protection capabilities vary by runtime environment:\n *\n * | Runtime | DNS Pre-Resolution | IP Blocking | Notes |\n * |-------------------|-------------------|-------------|-------|\n * | Node.js | YES | YES | Full protection via dns module |\n * | Browser | NO | NO | Relies on server-side validation |\n * | Cloudflare Workers| NO | NO | No DNS access, relies on CF network |\n * | Deno | NO | NO | dns module not available by default |\n * | Bun | YES | YES | Compatible with Node.js dns module |\n *\n * Use `getSSRFCapabilities()` to detect runtime capabilities.\n *\n * @packageDocumentation\n */\n\nimport { VERIFIER_LIMITS, VERIFIER_NETWORK } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// SSRF Capability Model\n// ---------------------------------------------------------------------------\n\n/**\n * Runtime environment where SSRF protection is running\n */\nexport type SSRFRuntime =\n | 'node'\n | 'bun'\n | 'deno'\n | 'browser'\n | 'cloudflare-workers'\n | 'edge-generic'\n | 'unknown';\n\n/**\n * SSRF protection capabilities available in the current runtime\n *\n * These capabilities determine what security measures can be applied:\n * - `dnsPreResolution`: Can resolve hostnames to IPs before connecting\n * - `ipBlocking`: Can inspect and block connections based on resolved IPs\n * - `networkIsolation`: Runtime provides network-level isolation (e.g., CF Workers)\n *\n * When `dnsPreResolution` is false, SSRF protection is limited to:\n * - URL scheme validation (HTTPS only)\n * - Hostname pattern matching (if configured)\n * - Response size limits\n * - Timeout enforcement\n *\n * This is a defense-in-depth model: even without DNS pre-resolution,\n * multiple layers of protection remain active.\n */\nexport interface SSRFCapabilities {\n /** Detected runtime environment */\n runtime: SSRFRuntime;\n /** Can resolve DNS before making HTTP connection */\n dnsPreResolution: boolean;\n /** Can block connections based on resolved IP addresses */\n ipBlocking: boolean;\n /** Runtime provides network-level isolation */\n networkIsolation: boolean;\n /** Human-readable description of protection level */\n protectionLevel: 'full' | 'partial' | 'minimal';\n /** Advisory notes for operators */\n notes: string[];\n}\n\n/**\n * Cached capabilities (detected once per process)\n */\nlet cachedCapabilities: SSRFCapabilities | null = null;\n\n/**\n * Detect SSRF protection capabilities for the current runtime\n *\n * This function performs runtime detection and returns a capability object\n * that describes what SSRF protections are available.\n *\n * @returns SSRF capabilities for the current runtime\n *\n * @example\n * ```typescript\n * const caps = getSSRFCapabilities();\n * if (!caps.dnsPreResolution) {\n * console.warn('Running without DNS pre-resolution; SSRF protection is limited');\n * }\n * ```\n */\nexport function getSSRFCapabilities(): SSRFCapabilities {\n if (cachedCapabilities) {\n return cachedCapabilities;\n }\n\n cachedCapabilities = detectCapabilities();\n return cachedCapabilities;\n}\n\n/**\n * Internal: Detect runtime capabilities\n */\nfunction detectCapabilities(): SSRFCapabilities {\n // Check for Node.js\n if (typeof process !== 'undefined' && process.versions?.node) {\n return {\n runtime: 'node',\n dnsPreResolution: true,\n ipBlocking: true,\n networkIsolation: false,\n protectionLevel: 'full',\n notes: [\n 'Full SSRF protection available via Node.js dns module',\n 'DNS resolution checked before HTTP connection',\n 'All RFC 1918 private ranges blocked',\n ],\n };\n }\n\n // Check for Bun\n if (typeof process !== 'undefined' && process.versions?.bun) {\n return {\n runtime: 'bun',\n dnsPreResolution: true,\n ipBlocking: true,\n networkIsolation: false,\n protectionLevel: 'full',\n notes: [\n 'Full SSRF protection available via Bun dns compatibility',\n 'DNS resolution checked before HTTP connection',\n ],\n };\n }\n\n // Check for Deno\n if (typeof globalThis !== 'undefined' && 'Deno' in globalThis) {\n return {\n runtime: 'deno',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: false,\n protectionLevel: 'partial',\n notes: [\n 'DNS pre-resolution not available in Deno by default',\n 'SSRF protection limited to URL validation and response limits',\n 'Consider using Deno.connect with hostname resolution for enhanced protection',\n ],\n };\n }\n\n // Check for Cloudflare Workers\n if (\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as Record<string, unknown>).caches !== 'undefined' &&\n typeof (globalThis as Record<string, unknown>).HTMLRewriter !== 'undefined'\n ) {\n return {\n runtime: 'cloudflare-workers',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: true,\n protectionLevel: 'partial',\n notes: [\n 'Cloudflare Workers provide network-level isolation',\n 'DNS pre-resolution not available in Workers runtime',\n 'CF network blocks many SSRF vectors at infrastructure level',\n 'SSRF protection supplemented by URL validation and response limits',\n ],\n };\n }\n\n // Check for browser environment\n // Use globalThis to avoid DOM type references\n const g = globalThis as Record<string, unknown>;\n if (typeof g.window !== 'undefined' || typeof g.document !== 'undefined') {\n return {\n runtime: 'browser',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: false,\n protectionLevel: 'minimal',\n notes: [\n 'Browser environment detected; DNS pre-resolution not available',\n 'SSRF protection limited to URL scheme validation',\n 'Consider validating URLs server-side before browser fetch',\n 'Same-origin policy provides some protection against SSRF',\n ],\n };\n }\n\n // Generic edge runtime\n return {\n runtime: 'edge-generic',\n dnsPreResolution: false,\n ipBlocking: false,\n networkIsolation: false,\n protectionLevel: 'partial',\n notes: [\n 'Edge runtime detected; DNS pre-resolution may not be available',\n 'SSRF protection limited to URL validation and response limits',\n 'Verify runtime provides additional network-level protections',\n ],\n };\n}\n\n/**\n * Reset cached capabilities (for testing)\n * @internal\n */\nexport function resetSSRFCapabilitiesCache(): void {\n cachedCapabilities = null;\n}\n\n/**\n * SSRF fetch options\n */\nexport interface SSRFFetchOptions {\n /** Timeout in milliseconds (default: VERIFIER_LIMITS.fetchTimeoutMs) */\n timeoutMs?: number;\n /** Maximum response size in bytes (default: VERIFIER_LIMITS.maxResponseBytes) */\n maxBytes?: number;\n /** Maximum redirects to follow (default: 0 for SSRF safety) */\n maxRedirects?: number;\n /** Allow redirects (default: VERIFIER_NETWORK.allowRedirects) */\n allowRedirects?: boolean;\n /**\n * Allow cross-origin redirects (default: true for CDN compatibility).\n * When true, redirects to different origins are allowed if the target passes SSRF checks.\n * When false, redirects must stay within the same origin.\n */\n allowCrossOriginRedirects?: boolean;\n /**\n * How to handle DNS resolution failures (default: 'block' for fail-closed security).\n * - 'block': Treat DNS failure as blocked (fail-closed, recommended)\n * - 'fail': Return network_error and allow caller to decide\n */\n dnsFailureBehavior?: 'block' | 'fail';\n /** Custom headers to include */\n headers?: Record<string, string>;\n}\n\n/**\n * SSRF fetch result\n */\nexport interface SSRFFetchResult {\n /** Whether the fetch succeeded */\n ok: true;\n /** Response status code */\n status: number;\n /** Response body as string */\n body: string;\n /**\n * Raw response bytes for digest computation.\n * Use this for computing digests to avoid encoding round-trip issues.\n */\n rawBytes: Uint8Array;\n /** Response content type */\n contentType?: string;\n}\n\n/**\n * SSRF fetch error\n */\nexport interface SSRFFetchError {\n /** Fetch failed */\n ok: false;\n /** Error reason code */\n reason:\n | 'invalid_url'\n | 'not_https'\n | 'private_ip'\n | 'loopback'\n | 'link_local'\n | 'dns_failure'\n | 'too_many_redirects'\n | 'scheme_downgrade'\n | 'cross_origin_redirect'\n | 'timeout'\n | 'response_too_large'\n | 'jwks_too_many_keys'\n | 'network_error';\n /** Human-readable error message */\n message: string;\n /** Blocked URL (if applicable) */\n blockedUrl?: string;\n}\n\n/**\n * IPv4 address parsed into components\n */\ninterface IPv4Address {\n octets: [number, number, number, number];\n}\n\n/**\n * Parse an IPv4 address string into octets\n */\nfunction parseIPv4(ip: string): IPv4Address | null {\n const parts = ip.split('.');\n if (parts.length !== 4) return null;\n\n const octets: number[] = [];\n for (const part of parts) {\n const num = parseInt(part, 10);\n if (isNaN(num) || num < 0 || num > 255) return null;\n octets.push(num);\n }\n\n return { octets: octets as [number, number, number, number] };\n}\n\n/**\n * Check if an IPv4 address is in a CIDR range\n */\nfunction isInCIDR(ip: IPv4Address, cidr: string): boolean {\n const [rangeStr, maskStr] = cidr.split('/');\n const range = parseIPv4(rangeStr);\n if (!range) return false;\n\n const maskBits = parseInt(maskStr, 10);\n if (isNaN(maskBits) || maskBits < 0 || maskBits > 32) return false;\n\n // Convert to 32-bit integers\n const ipNum = (ip.octets[0] << 24) | (ip.octets[1] << 16) | (ip.octets[2] << 8) | ip.octets[3];\n const rangeNum =\n (range.octets[0] << 24) | (range.octets[1] << 16) | (range.octets[2] << 8) | range.octets[3];\n\n // Create mask\n const mask = maskBits === 0 ? 0 : ~((1 << (32 - maskBits)) - 1);\n\n return (ipNum & mask) === (rangeNum & mask);\n}\n\n/**\n * Check if an IPv6 address is loopback (::1)\n */\nfunction isIPv6Loopback(ip: string): boolean {\n const normalized = ip.toLowerCase().replace(/^::ffff:/, '');\n return normalized === '::1' || normalized === '0:0:0:0:0:0:0:1';\n}\n\n/**\n * Check if an IPv6 address is link-local (fe80::/10)\n */\nfunction isIPv6LinkLocal(ip: string): boolean {\n const normalized = ip.toLowerCase();\n return (\n normalized.startsWith('fe8') ||\n normalized.startsWith('fe9') ||\n normalized.startsWith('fea') ||\n normalized.startsWith('feb')\n );\n}\n\n/**\n * Check if an IP address is private/blocked\n */\nexport function isBlockedIP(\n ip: string\n): { blocked: true; reason: 'private_ip' | 'loopback' | 'link_local' } | { blocked: false } {\n // Handle IPv4-mapped IPv6 addresses\n const ipv4Match = ip.match(/^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/i);\n const effectiveIP = ipv4Match ? ipv4Match[1] : ip;\n\n // Check IPv4\n const ipv4 = parseIPv4(effectiveIP);\n if (ipv4) {\n // RFC 1918 private ranges\n if (\n isInCIDR(ipv4, '10.0.0.0/8') ||\n isInCIDR(ipv4, '172.16.0.0/12') ||\n isInCIDR(ipv4, '192.168.0.0/16')\n ) {\n return { blocked: true, reason: 'private_ip' };\n }\n\n // Loopback\n if (isInCIDR(ipv4, '127.0.0.0/8')) {\n return { blocked: true, reason: 'loopback' };\n }\n\n // Link-local\n if (isInCIDR(ipv4, '169.254.0.0/16')) {\n return { blocked: true, reason: 'link_local' };\n }\n\n return { blocked: false };\n }\n\n // Check IPv6\n if (isIPv6Loopback(ip)) {\n return { blocked: true, reason: 'loopback' };\n }\n if (isIPv6LinkLocal(ip)) {\n return { blocked: true, reason: 'link_local' };\n }\n\n return { blocked: false };\n}\n\n/**\n * DNS resolution result\n */\ninterface DNSResolutionResult {\n /** Whether resolution succeeded */\n ok: true;\n /** Resolved IP addresses */\n ips: string[];\n /** Whether this is a browser environment (no pre-resolution possible) */\n browser: boolean;\n}\n\n/**\n * DNS resolution failure\n */\ninterface DNSResolutionFailure {\n /** Resolution failed */\n ok: false;\n /** Error message */\n message: string;\n}\n\n/**\n * Resolve hostname to IP addresses (platform-specific)\n *\n * In Node.js environments, this uses dns.resolve.\n * In browser environments, we cannot check IPs before fetch.\n */\nasync function resolveHostname(\n hostname: string\n): Promise<DNSResolutionResult | DNSResolutionFailure> {\n // Node.js environment detection\n if (typeof process !== 'undefined' && process.versions?.node) {\n try {\n const dns = await import('dns');\n const { promisify } = await import('util');\n const resolve4 = promisify(dns.resolve4);\n const resolve6 = promisify(dns.resolve6);\n\n const results: string[] = [];\n let ipv4Error: Error | null = null;\n let ipv6Error: Error | null = null;\n\n try {\n const ipv4 = await resolve4(hostname);\n results.push(...ipv4);\n } catch (err) {\n ipv4Error = err as Error;\n }\n\n try {\n const ipv6 = await resolve6(hostname);\n results.push(...ipv6);\n } catch (err) {\n ipv6Error = err as Error;\n }\n\n // If we got at least one result, resolution succeeded\n if (results.length > 0) {\n return { ok: true, ips: results, browser: false };\n }\n\n // Both failed - this is a DNS failure\n if (ipv4Error && ipv6Error) {\n return {\n ok: false,\n message: `DNS resolution failed for ${hostname}: ${ipv4Error.message}`,\n };\n }\n\n // No results but no errors either (unlikely)\n return { ok: true, ips: [], browser: false };\n } catch (err) {\n // DNS module import failed or other error\n return {\n ok: false,\n message: `DNS resolution error: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n\n // Browser environment: cannot pre-resolve, return empty\n // SSRF check will rely on server-side validation\n return { ok: true, ips: [], browser: true };\n}\n\n/**\n * Perform an SSRF-safe fetch\n *\n * This function implements the SSRF protection algorithm from VERIFIER-SECURITY-MODEL.md:\n * 1. Parse URL; reject if not https://\n * 2. Resolve hostname to IP(s)\n * 3. For each IP: reject if private, link-local, or loopback\n * 4. Perform fetch with timeout\n * 5. On redirect: increment counter, reject if > max, apply checks to redirect URL\n * 6. Validate response size\n *\n * @param url - URL to fetch (must be https://)\n * @param options - Fetch options\n * @returns Fetch result or error\n */\nexport async function ssrfSafeFetch(\n url: string,\n options: SSRFFetchOptions = {}\n): Promise<SSRFFetchResult | SSRFFetchError> {\n const {\n timeoutMs = VERIFIER_LIMITS.fetchTimeoutMs,\n maxBytes = VERIFIER_LIMITS.maxResponseBytes,\n maxRedirects = 0,\n allowRedirects = VERIFIER_NETWORK.allowRedirects,\n allowCrossOriginRedirects = true, // Default: allow for CDN compatibility\n dnsFailureBehavior = 'block', // Default: fail-closed for security\n headers = {},\n } = options;\n\n // Step 1: Parse and validate URL\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(url);\n } catch {\n return {\n ok: false,\n reason: 'invalid_url',\n message: `Invalid URL: ${url}`,\n blockedUrl: url,\n };\n }\n\n // Step 1b: Require HTTPS\n if (parsedUrl.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'not_https',\n message: `URL must use HTTPS: ${url}`,\n blockedUrl: url,\n };\n }\n\n // Step 2: Resolve hostname to IPs\n const dnsResult = await resolveHostname(parsedUrl.hostname);\n\n // Step 2b: Handle DNS resolution failure (fail-closed by default)\n if (!dnsResult.ok) {\n if (dnsFailureBehavior === 'block') {\n return {\n ok: false,\n reason: 'dns_failure',\n message: `DNS resolution blocked: ${dnsResult.message}`,\n blockedUrl: url,\n };\n }\n // dnsFailureBehavior === 'fail': return network_error\n return {\n ok: false,\n reason: 'network_error',\n message: dnsResult.message,\n blockedUrl: url,\n };\n }\n\n // Step 3: Check each resolved IP (if not browser environment)\n if (!dnsResult.browser) {\n for (const ip of dnsResult.ips) {\n const blockResult = isBlockedIP(ip);\n if (blockResult.blocked) {\n return {\n ok: false,\n reason: blockResult.reason,\n message: `Blocked ${blockResult.reason} address: ${ip} for ${url}`,\n blockedUrl: url,\n };\n }\n }\n }\n\n // Step 4: Perform fetch with timeout\n let redirectCount = 0;\n let currentUrl = url;\n const originalOrigin = parsedUrl.origin;\n\n while (true) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n const response = await fetch(currentUrl, {\n headers: {\n Accept: 'application/json, text/plain',\n ...headers,\n },\n signal: controller.signal,\n redirect: 'manual', // Handle redirects manually for security\n });\n\n clearTimeout(timeoutId);\n\n // Step 5: Handle redirects\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location');\n\n if (!location) {\n return {\n ok: false,\n reason: 'network_error',\n message: `Redirect without Location header from ${currentUrl}`,\n };\n }\n\n // Check redirect policy\n if (!allowRedirects) {\n return {\n ok: false,\n reason: 'too_many_redirects',\n message: `Redirects not allowed: ${currentUrl} -> ${location}`,\n blockedUrl: location,\n };\n }\n\n // Increment redirect counter\n redirectCount++;\n if (redirectCount > maxRedirects) {\n return {\n ok: false,\n reason: 'too_many_redirects',\n message: `Too many redirects (${redirectCount} > ${maxRedirects})`,\n blockedUrl: location,\n };\n }\n\n // Resolve redirect URL\n let redirectUrl: URL;\n try {\n redirectUrl = new URL(location, currentUrl);\n } catch {\n return {\n ok: false,\n reason: 'invalid_url',\n message: `Invalid redirect URL: ${location}`,\n blockedUrl: location,\n };\n }\n\n // Check for scheme downgrade (https -> http)\n if (redirectUrl.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'scheme_downgrade',\n message: `HTTPS to HTTP downgrade not allowed: ${currentUrl} -> ${redirectUrl.href}`,\n blockedUrl: redirectUrl.href,\n };\n }\n\n // Check for cross-origin redirects (configurable for CDN compatibility)\n if (redirectUrl.origin !== originalOrigin && !allowCrossOriginRedirects) {\n return {\n ok: false,\n reason: 'cross_origin_redirect',\n message: `Cross-origin redirect not allowed: ${originalOrigin} -> ${redirectUrl.origin}`,\n blockedUrl: redirectUrl.href,\n };\n }\n\n // Check redirect target IPs (DNS resolution + SSRF checks)\n const redirectDnsResult = await resolveHostname(redirectUrl.hostname);\n\n // Handle DNS failure for redirect target\n if (!redirectDnsResult.ok) {\n if (dnsFailureBehavior === 'block') {\n return {\n ok: false,\n reason: 'dns_failure',\n message: `Redirect DNS resolution blocked: ${redirectDnsResult.message}`,\n blockedUrl: redirectUrl.href,\n };\n }\n return {\n ok: false,\n reason: 'network_error',\n message: redirectDnsResult.message,\n blockedUrl: redirectUrl.href,\n };\n }\n\n // Check redirect target IPs for SSRF (if not browser environment)\n if (!redirectDnsResult.browser) {\n for (const ip of redirectDnsResult.ips) {\n const blockResult = isBlockedIP(ip);\n if (blockResult.blocked) {\n return {\n ok: false,\n reason: blockResult.reason,\n message: `Redirect to blocked ${blockResult.reason} address: ${ip}`,\n blockedUrl: redirectUrl.href,\n };\n }\n }\n }\n\n currentUrl = redirectUrl.href;\n continue;\n }\n\n // Step 6: Validate response size\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > maxBytes) {\n return {\n ok: false,\n reason: 'response_too_large',\n message: `Response too large: ${contentLength} bytes > ${maxBytes} max`,\n };\n }\n\n // Read response body with size limit\n const reader = response.body?.getReader();\n if (!reader) {\n const body = await response.text();\n if (body.length > maxBytes) {\n return {\n ok: false,\n reason: 'response_too_large',\n message: `Response too large: ${body.length} bytes > ${maxBytes} max`,\n };\n }\n // Convert body back to bytes for rawBytes (fallback path)\n const rawBytes = new TextEncoder().encode(body);\n return {\n ok: true,\n status: response.status,\n body,\n rawBytes,\n contentType: response.headers.get('content-type') ?? undefined,\n };\n }\n\n // Stream with size limit\n const chunks: Uint8Array[] = [];\n let totalSize = 0;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalSize += value.length;\n if (totalSize > maxBytes) {\n reader.cancel();\n return {\n ok: false,\n reason: 'response_too_large',\n message: `Response too large: ${totalSize} bytes > ${maxBytes} max`,\n };\n }\n\n chunks.push(value);\n }\n\n // Concatenate chunks into raw bytes (preserve original bytes for digest)\n const rawBytes = chunks.reduce((acc, chunk) => {\n const result = new Uint8Array(acc.length + chunk.length);\n result.set(acc);\n result.set(chunk, acc.length);\n return result;\n }, new Uint8Array());\n\n // Decode to string for body\n const body = new TextDecoder().decode(rawBytes);\n\n return {\n ok: true,\n status: response.status,\n body,\n rawBytes,\n contentType: response.headers.get('content-type') ?? undefined,\n };\n } catch (err) {\n if (err instanceof Error) {\n if (err.name === 'AbortError' || err.message.includes('timeout')) {\n return {\n ok: false,\n reason: 'timeout',\n message: `Fetch timeout after ${timeoutMs}ms: ${currentUrl}`,\n };\n }\n }\n\n return {\n ok: false,\n reason: 'network_error',\n message: `Network error: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n}\n\n/**\n * Convenience function to fetch JWKS with SSRF protection\n */\nexport async function fetchJWKSSafe(\n jwksUrl: string,\n options?: Omit<SSRFFetchOptions, 'maxBytes'>\n): Promise<SSRFFetchResult | SSRFFetchError> {\n return ssrfSafeFetch(jwksUrl, {\n ...options,\n maxBytes: VERIFIER_LIMITS.maxJwksBytes,\n headers: {\n Accept: 'application/json',\n ...options?.headers,\n },\n });\n}\n\n/**\n * Convenience function to fetch pointer target with SSRF protection\n */\nexport async function fetchPointerSafe(\n pointerUrl: string,\n options?: Omit<SSRFFetchOptions, 'maxBytes'>\n): Promise<SSRFFetchResult | SSRFFetchError> {\n return ssrfSafeFetch(pointerUrl, {\n ...options,\n maxBytes: VERIFIER_LIMITS.maxReceiptBytes,\n headers: {\n Accept: 'application/jose, application/json',\n ...options?.headers,\n },\n });\n}\n","/**\n * PEAC Verification Report Builder\n *\n * Constructs deterministic verification reports per VERIFICATION-REPORT-FORMAT.md.\n * Reports are designed to be portable, deterministic, safe, and policy-aware.\n *\n * @packageDocumentation\n */\n\nimport { sha256Hex } from '@peac/crypto';\nimport { VERIFICATION_REPORT_VERSION, WIRE_TYPE } from '@peac/kernel';\nimport type {\n CheckId,\n CheckResult,\n CheckStatus,\n DigestObject,\n ReasonCode,\n VerificationArtifacts,\n VerificationInput,\n VerificationMeta,\n VerificationReport,\n VerificationResult,\n VerifierPolicy,\n} from './verifier-types.js';\nimport {\n CHECK_IDS,\n createDigest,\n NON_DETERMINISTIC_ARTIFACT_KEYS,\n reasonCodeToErrorCode,\n reasonCodeToSeverity,\n} from './verifier-types.js';\n\n/**\n * Report builder state\n */\ninterface ReportBuilderState {\n input?: VerificationInput;\n receiptDigestHex?: string;\n policy: VerifierPolicy;\n checks: Map<CheckId, CheckResult>;\n result?: VerificationResult;\n artifacts?: Record<string, unknown>;\n meta?: VerificationMeta;\n shortCircuited: boolean;\n failedAtCheck?: CheckId;\n}\n\n/**\n * Verification Report Builder\n *\n * Builds verification reports with proper check ordering and short-circuit behavior.\n * Ensures reports conform to VERIFICATION-REPORT-FORMAT.md requirements.\n *\n * Shape-stable: Always emits all checks with pass/fail/skip status.\n */\nexport class VerificationReportBuilder {\n private state: ReportBuilderState;\n\n constructor(policy: VerifierPolicy) {\n this.state = {\n policy,\n checks: new Map(),\n shortCircuited: false,\n };\n }\n\n /**\n * Set the input descriptor with pre-computed digest\n *\n * Use this when you've already computed the SHA-256 hash.\n *\n * @param digestHex - SHA-256 digest as lowercase hex (64 chars)\n * @param type - Input type\n */\n setInputWithDigest(\n digestHex: string,\n type: 'receipt_jws' | 'bundle_entry' = 'receipt_jws'\n ): this {\n this.state.receiptDigestHex = digestHex;\n this.state.input = {\n type,\n receipt_digest: createDigest(digestHex),\n };\n return this;\n }\n\n /**\n * Set the input descriptor (async - computes SHA-256)\n *\n * @param receiptBytes - Raw receipt bytes\n * @param type - Input type\n */\n async setInputAsync(\n receiptBytes: Uint8Array,\n type: 'receipt_jws' | 'bundle_entry' = 'receipt_jws'\n ): Promise<this> {\n const digestHex = await sha256Hex(receiptBytes);\n return this.setInputWithDigest(digestHex, type);\n }\n\n /**\n * Add a check result\n *\n * Checks can be added in any order; they will be sorted in build().\n * If a previous check failed, subsequent checks should be marked as skip.\n */\n addCheck(\n id: CheckId,\n status: CheckStatus,\n detail?: Record<string, unknown>,\n errorCode?: string\n ): this {\n const check: CheckResult = { id, status };\n if (detail && Object.keys(detail).length > 0) {\n check.detail = detail;\n }\n if (errorCode) {\n check.error_code = errorCode;\n }\n\n this.state.checks.set(id, check);\n\n // Track short-circuit on failure\n if (status === 'fail' && !this.state.shortCircuited) {\n this.state.shortCircuited = true;\n this.state.failedAtCheck = id;\n }\n\n return this;\n }\n\n /**\n * Add a passing check\n */\n pass(id: CheckId, detail?: Record<string, unknown>): this {\n return this.addCheck(id, 'pass', detail);\n }\n\n /**\n * Add a failing check\n */\n fail(id: CheckId, errorCode: string, detail?: Record<string, unknown>): this {\n return this.addCheck(id, 'fail', detail, errorCode);\n }\n\n /**\n * Add a skipped check\n */\n skip(id: CheckId, detail?: Record<string, unknown>): this {\n return this.addCheck(id, 'skip', detail);\n }\n\n /**\n * Set the final result\n */\n setResult(\n valid: boolean,\n reason: ReasonCode,\n options?: {\n issuer?: string;\n kid?: string;\n receiptType?: string;\n }\n ): this {\n this.state.result = {\n valid,\n reason,\n severity: reasonCodeToSeverity(reason),\n receipt_type: options?.receiptType ?? WIRE_TYPE,\n // Wire 0.1: always 'unavailable' (DD-49). Wire 0.2 will set this via options.\n policy_binding: 'unavailable',\n ...(options?.issuer && { issuer: options.issuer }),\n ...(options?.kid && { kid: options.kid }),\n };\n return this;\n }\n\n /**\n * Set success result\n */\n success(issuer: string, kid: string): this {\n return this.setResult(true, 'ok', { issuer, kid });\n }\n\n /**\n * Set failure result\n */\n failure(reason: ReasonCode, issuer?: string, kid?: string): this {\n return this.setResult(false, reason, { issuer, kid });\n }\n\n /**\n * Add artifacts\n */\n addArtifact(key: string, value: unknown): this {\n if (!this.state.artifacts) {\n this.state.artifacts = {};\n }\n this.state.artifacts[key] = value;\n return this;\n }\n\n /**\n * Set metadata (non-deterministic fields)\n */\n setMeta(meta: VerificationMeta): this {\n this.state.meta = meta;\n return this;\n }\n\n /**\n * Add current timestamp to meta\n */\n addTimestamp(): this {\n if (!this.state.meta) {\n this.state.meta = {};\n }\n this.state.meta.generated_at = new Date().toISOString();\n return this;\n }\n\n /**\n * Build the final report\n *\n * Ensures all checks are present (shape-stable).\n * Missing checks after a failure are marked as 'skip'.\n * Missing checks before a failure (or in success) are marked as 'pass'.\n */\n build(): VerificationReport {\n // Validate required fields\n if (!this.state.input) {\n throw new Error('Input is required. Call setInputWithDigest() or setInputAsync() first.');\n }\n if (!this.state.result) {\n throw new Error('Result is required. Call setResult() or success()/failure() first.');\n }\n\n // Build shape-stable checks array\n const checks: CheckResult[] = [];\n const failedIndex = this.state.failedAtCheck ? CHECK_IDS.indexOf(this.state.failedAtCheck) : -1;\n\n for (let i = 0; i < CHECK_IDS.length; i++) {\n const checkId = CHECK_IDS[i];\n const existing = this.state.checks.get(checkId);\n\n if (existing) {\n checks.push(existing);\n } else if (this.state.shortCircuited && i > failedIndex) {\n // After failure, missing checks are skipped\n checks.push({ id: checkId, status: 'skip', detail: { reason: 'short_circuit' } });\n } else {\n // Before failure or in success, missing checks get default status\n // For optional/deferred checks, mark as skip with appropriate reason\n if (checkId === 'transport.profile_binding') {\n checks.push({ id: checkId, status: 'skip', detail: { reason: 'not_applicable' } });\n } else if (checkId === 'policy.binding') {\n // Wire 0.1: always skip (DD-49). Wire 0.2 will produce pass/fail.\n checks.push({\n id: checkId,\n status: 'skip',\n detail: { reason: 'wire_01_no_policy_digest' },\n });\n } else {\n // This shouldn't happen in well-formed builds - indicates a bug\n checks.push({ id: checkId, status: 'skip', detail: { reason: 'not_executed' } });\n }\n }\n }\n\n const report: VerificationReport = {\n report_version: VERIFICATION_REPORT_VERSION,\n input: this.state.input,\n policy: this.state.policy,\n result: this.state.result,\n checks,\n };\n\n if (this.state.artifacts && Object.keys(this.state.artifacts).length > 0) {\n report.artifacts = this.state.artifacts as VerificationReport['artifacts'];\n }\n\n if (this.state.meta) {\n report.meta = this.state.meta;\n }\n\n return report;\n }\n\n /**\n * Build in deterministic mode (excludes meta and non-deterministic artifacts)\n *\n * Deterministic mode ensures that the same inputs and policy always produce\n * the same report output, regardless of cache state or timing.\n *\n * Excludes:\n * - `meta`: Contains timestamps and verifier info\n * - Non-deterministic artifacts: `issuer_jwks_digest` (depends on cache state)\n *\n * @returns Report without meta and with only deterministic artifacts\n */\n buildDeterministic(): Omit<VerificationReport, 'meta'> {\n const report = this.build();\n const { meta: _meta, ...deterministic } = report;\n\n // Filter out non-deterministic artifacts\n if (deterministic.artifacts) {\n const filteredArtifacts: Partial<VerificationArtifacts> = { ...deterministic.artifacts };\n for (const key of NON_DETERMINISTIC_ARTIFACT_KEYS) {\n delete filteredArtifacts[key];\n }\n\n // Remove artifacts object if empty after filtering\n if (Object.keys(filteredArtifacts).length === 0) {\n delete deterministic.artifacts;\n } else {\n deterministic.artifacts = filteredArtifacts as VerificationArtifacts;\n }\n }\n\n return deterministic;\n }\n}\n\n/**\n * Create a new report builder\n */\nexport function createReportBuilder(policy: VerifierPolicy): VerificationReportBuilder {\n return new VerificationReportBuilder(policy);\n}\n\n/**\n * Compute receipt digest for report input\n *\n * @param receiptBytes - Raw receipt bytes (JWS string as UTF-8)\n * @returns SHA-256 digest as lowercase hex (64 chars)\n */\nexport async function computeReceiptDigest(receiptBytes: Uint8Array | string): Promise<string> {\n const bytes =\n typeof receiptBytes === 'string' ? new TextEncoder().encode(receiptBytes) : receiptBytes;\n return sha256Hex(bytes);\n}\n\n/**\n * Build a quick failure report without going through all checks\n *\n * Useful for early failures like receipt_too_large or malformed_receipt\n * where most checks are skipped.\n */\nexport async function buildFailureReport(\n policy: VerifierPolicy,\n receiptBytes: Uint8Array | string,\n reason: ReasonCode,\n failedCheckId: CheckId,\n errorCode?: string,\n detail?: Record<string, unknown>,\n options?: {\n issuer?: string;\n kid?: string;\n meta?: VerificationMeta;\n }\n): Promise<VerificationReport> {\n const bytes =\n typeof receiptBytes === 'string' ? new TextEncoder().encode(receiptBytes) : receiptBytes;\n const digestHex = await sha256Hex(bytes);\n\n const builder = createReportBuilder(policy)\n .setInputWithDigest(digestHex)\n .failure(reason, options?.issuer, options?.kid);\n\n // Add passing checks up to the failure point\n const failedIndex = CHECK_IDS.indexOf(failedCheckId);\n for (let i = 0; i < CHECK_IDS.length; i++) {\n const checkId = CHECK_IDS[i];\n if (i < failedIndex) {\n builder.pass(checkId);\n } else if (i === failedIndex) {\n builder.fail(checkId, errorCode ?? reasonCodeToErrorCode(reason), detail);\n }\n // Remaining checks will be auto-skipped by build()\n }\n\n if (options?.meta) {\n builder.setMeta(options.meta);\n }\n\n return builder.build();\n}\n\n/**\n * Build a success report\n */\nexport async function buildSuccessReport(\n policy: VerifierPolicy,\n receiptBytes: Uint8Array | string,\n issuer: string,\n kid: string,\n checkDetails?: Partial<Record<CheckId, Record<string, unknown>>>,\n options?: {\n artifacts?: VerificationReport['artifacts'];\n meta?: VerificationMeta;\n }\n): Promise<VerificationReport> {\n const bytes =\n typeof receiptBytes === 'string' ? new TextEncoder().encode(receiptBytes) : receiptBytes;\n const digestHex = await sha256Hex(bytes);\n\n const builder = createReportBuilder(policy).setInputWithDigest(digestHex).success(issuer, kid);\n\n // Add all checks as passing (except optional ones)\n for (const checkId of CHECK_IDS) {\n // Skip issuer.discovery for offline mode\n if (checkId === 'issuer.discovery' && policy.mode === 'offline_only') {\n builder.skip(checkId, { reason: 'offline_mode' });\n continue;\n }\n\n // transport.profile_binding is optional\n if (checkId === 'transport.profile_binding') {\n if (checkDetails?.[checkId]) {\n builder.pass(checkId, checkDetails[checkId]);\n }\n // Will be marked as skip by build() if not added\n continue;\n }\n\n // policy.binding: Wire 0.1 always skip (DD-49)\n if (checkId === 'policy.binding') {\n // Will be marked as skip with wire_01_no_policy_digest by build()\n continue;\n }\n\n builder.pass(checkId, checkDetails?.[checkId]);\n }\n\n if (options?.artifacts) {\n for (const [key, value] of Object.entries(options.artifacts)) {\n builder.addArtifact(key, value);\n }\n }\n\n if (options?.meta) {\n builder.setMeta(options.meta);\n }\n\n return builder.build();\n}\n","/**\n * PEAC Verifier Core\n *\n * Implements the verification flow per VERIFIER-SECURITY-MODEL.md with:\n * - Ordered checks with short-circuit behavior\n * - Trust pinning (issuer allowlist + RFC 7638 thumbprints)\n * - SSRF-safe network fetches\n * - Deterministic verification reports\n *\n * @packageDocumentation\n */\n\nimport {\n base64urlDecode,\n computeJwkThumbprint,\n decode,\n jwkToPublicKeyBytes,\n sha256Hex,\n verify as jwsVerify,\n} from '@peac/crypto';\nimport { VERIFIER_LIMITS, WIRE_TYPE } from '@peac/kernel';\nimport { PEACReceiptClaims, ReceiptClaims } from '@peac/schema';\nimport type { SSRFFetchError } from './ssrf-safe-fetch.js';\nimport { fetchJWKSSafe, ssrfSafeFetch } from './ssrf-safe-fetch.js';\nimport { createReportBuilder } from './verification-report.js';\nimport type { PinnedKey, VerificationReport, VerifierPolicy } from './verifier-types.js';\nimport {\n createDefaultPolicy,\n createDigest,\n reasonCodeToErrorCode,\n ssrfErrorToReasonCode,\n} from './verifier-types.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * JWK structure for Ed25519 keys\n */\ninterface JWK {\n kty: string;\n crv: string;\n x: string;\n kid: string;\n}\n\n/**\n * JWKS document\n */\ninterface JWKS {\n keys: JWK[];\n}\n\n/**\n * Issuer configuration document (/.well-known/peac-issuer.json)\n */\ninterface IssuerConfig {\n issuer: string;\n jwks_uri: string;\n}\n\n/**\n * Verification options for verifier-core\n */\nexport interface VerifyCoreOptions {\n /** Receipt JWS (compact serialization) or raw bytes */\n receipt: string | Uint8Array;\n /** Verification policy */\n policy?: VerifierPolicy;\n /** Reference time for deterministic verification (seconds since epoch) */\n referenceTime?: number;\n /** Include non-deterministic metadata in report */\n includeMeta?: boolean;\n}\n\n/**\n * Verification result\n */\nexport interface VerifyCoreResult {\n /** Whether verification succeeded */\n valid: boolean;\n /** Verification report */\n report: VerificationReport;\n /** Parsed claims (if valid) */\n claims?: PEACReceiptClaims;\n}\n\n// ---------------------------------------------------------------------------\n// Internal State\n// ---------------------------------------------------------------------------\n\n/**\n * JWKS cache entry\n */\ninterface JWKSCacheEntry {\n jwks: JWKS;\n expiresAt: number;\n}\n\n/**\n * In-memory JWKS cache (5 minute TTL)\n */\nconst jwksCache = new Map<string, JWKSCacheEntry>();\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\n// ---------------------------------------------------------------------------\n// Helper Functions\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize issuer to origin format (https://host[:port])\n */\nfunction normalizeIssuer(issuer: string): string {\n try {\n const url = new URL(issuer);\n // Include port only if non-standard for HTTPS\n if (url.port && url.port !== '443') {\n return `${url.protocol}//${url.hostname}:${url.port}`;\n }\n return `${url.protocol}//${url.hostname}`;\n } catch {\n return issuer;\n }\n}\n\n/**\n * Check if issuer is in the allowlist\n */\nfunction isIssuerAllowed(issuer: string, allowlist?: string[]): boolean {\n if (!allowlist || allowlist.length === 0) {\n // No allowlist means all issuers are allowed\n return true;\n }\n\n const normalized = normalizeIssuer(issuer);\n return allowlist.some((allowed) => normalizeIssuer(allowed) === normalized);\n}\n\n/**\n * Find pinned key for issuer and kid\n */\nfunction findPinnedKey(\n issuer: string,\n kid: string,\n pinnedKeys?: PinnedKey[]\n): PinnedKey | undefined {\n if (!pinnedKeys || pinnedKeys.length === 0) {\n return undefined;\n }\n\n const normalizedIssuer = normalizeIssuer(issuer);\n return pinnedKeys.find((pk) => normalizeIssuer(pk.issuer) === normalizedIssuer && pk.kid === kid);\n}\n\n/**\n * Fetch issuer configuration\n */\nasync function fetchIssuerConfig(issuerOrigin: string): Promise<IssuerConfig | null> {\n const configUrl = `${issuerOrigin}/.well-known/peac-issuer.json`;\n\n const result = await ssrfSafeFetch(configUrl, {\n maxBytes: 65536, // 64 KB\n headers: { Accept: 'application/json' },\n });\n\n if (!result.ok) {\n return null;\n }\n\n try {\n return JSON.parse(result.body) as IssuerConfig;\n } catch {\n return null;\n }\n}\n\n/**\n * JWKS fetch result (success case)\n */\ninterface JWKSFetchSuccess {\n jwks: JWKS;\n fromCache: boolean;\n /** Raw JWKS bytes for digest computation (only present when not from cache) */\n rawBytes?: Uint8Array;\n}\n\n/**\n * Fetch JWKS from issuer\n */\nasync function fetchIssuerJWKS(\n issuerOrigin: string\n): Promise<JWKSFetchSuccess | { error: SSRFFetchError }> {\n const now = Date.now();\n\n // Check cache\n const cached = jwksCache.get(issuerOrigin);\n if (cached && cached.expiresAt > now) {\n return { jwks: cached.jwks, fromCache: true };\n }\n\n // Fetch issuer config first\n const config = await fetchIssuerConfig(issuerOrigin);\n if (!config?.jwks_uri) {\n // Fallback to well-known JWKS path\n const fallbackUrl = `${issuerOrigin}/.well-known/jwks.json`;\n const result = await fetchJWKSSafe(fallbackUrl);\n\n if (!result.ok) {\n return { error: result };\n }\n\n try {\n const jwks = JSON.parse(result.body) as JWKS;\n jwksCache.set(issuerOrigin, { jwks, expiresAt: now + CACHE_TTL_MS });\n return { jwks, fromCache: false, rawBytes: result.rawBytes };\n } catch {\n return {\n error: {\n ok: false,\n reason: 'network_error',\n message: 'Invalid JWKS JSON',\n } as SSRFFetchError,\n };\n }\n }\n\n // Fetch JWKS from discovered URI\n const result = await fetchJWKSSafe(config.jwks_uri);\n\n if (!result.ok) {\n return { error: result };\n }\n\n try {\n const jwks = JSON.parse(result.body) as JWKS;\n\n // Validate JWKS limits\n if (jwks.keys.length > VERIFIER_LIMITS.maxJwksKeys) {\n return {\n error: {\n ok: false,\n reason: 'jwks_too_many_keys',\n message: `JWKS has too many keys: ${jwks.keys.length} > ${VERIFIER_LIMITS.maxJwksKeys}`,\n } as SSRFFetchError,\n };\n }\n\n jwksCache.set(issuerOrigin, { jwks, expiresAt: now + CACHE_TTL_MS });\n return { jwks, fromCache: false, rawBytes: result.rawBytes };\n } catch {\n return {\n error: {\n ok: false,\n reason: 'network_error',\n message: 'Invalid JWKS JSON',\n } as SSRFFetchError,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main Verification Function\n// ---------------------------------------------------------------------------\n\n/**\n * Verify a PEAC receipt with full security checks and report emission\n *\n * Implements the verification flow per VERIFIER-SECURITY-MODEL.md:\n * 1. jws.parse - Parse JWS structure\n * 2. limits.receipt_bytes - Check receipt size\n * 3. jws.protected_header - Validate protected header\n * 4. claims.schema_unverified - Pre-signature schema check\n * 5. issuer.trust_policy - Check issuer allowlist/pins\n * 6. issuer.discovery - Fetch JWKS (if network mode)\n * 7. key.resolve - Resolve signing key by kid\n * 8. jws.signature - Verify signature\n * 9. claims.time_window - Check iat/exp\n * 10. extensions.limits - Check extension sizes\n */\nexport async function verifyReceiptCore(options: VerifyCoreOptions): Promise<VerifyCoreResult> {\n const {\n receipt,\n policy = createDefaultPolicy('offline_preferred'),\n referenceTime,\n includeMeta = false,\n } = options;\n\n // Convert receipt to string if needed\n const receiptJws = typeof receipt === 'string' ? receipt : new TextDecoder().decode(receipt);\n const receiptBytes = typeof receipt === 'string' ? new TextEncoder().encode(receipt) : receipt;\n\n // Compute receipt digest for report\n const receiptDigestHex = await sha256Hex(receiptBytes);\n\n // Start building report\n const builder = createReportBuilder(policy);\n builder.setInputWithDigest(receiptDigestHex);\n\n // Current time (or reference time for deterministic verification)\n const nowSeconds = referenceTime ?? Math.floor(Date.now() / 1000);\n\n // Track issuer and kid for result\n let issuer: string | undefined;\n let kid: string | undefined;\n let parsedClaims: PEACReceiptClaims | undefined;\n\n // ---------------------------------------------------------------------------\n // Check 1: jws.parse - Parse JWS structure\n // ---------------------------------------------------------------------------\n let header: { alg: string; typ: string; kid: string };\n let payload: PEACReceiptClaims;\n\n try {\n const decoded = decode<PEACReceiptClaims>(receiptJws);\n header = decoded.header;\n payload = decoded.payload;\n builder.pass('jws.parse');\n } catch (err) {\n builder.fail('jws.parse', 'E_VERIFY_MALFORMED_RECEIPT', {\n error: err instanceof Error ? err.message : String(err),\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // ---------------------------------------------------------------------------\n // Check 2: limits.receipt_bytes - Check receipt size\n // ---------------------------------------------------------------------------\n if (receiptBytes.length > policy.limits.max_receipt_bytes) {\n builder.fail('limits.receipt_bytes', 'E_VERIFY_RECEIPT_TOO_LARGE', {\n size: receiptBytes.length,\n limit: policy.limits.max_receipt_bytes,\n });\n builder.failure('receipt_too_large');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n builder.pass('limits.receipt_bytes', { size: receiptBytes.length });\n\n // ---------------------------------------------------------------------------\n // Check 3: jws.protected_header - Validate protected header\n // ---------------------------------------------------------------------------\n if (header.alg !== 'EdDSA') {\n builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {\n expected_alg: 'EdDSA',\n actual_alg: header.alg,\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n if (header.typ !== WIRE_TYPE) {\n builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {\n expected_typ: WIRE_TYPE,\n actual_typ: header.typ,\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n if (!header.kid) {\n builder.fail('jws.protected_header', 'E_VERIFY_MALFORMED_RECEIPT', {\n error: 'Missing kid in protected header',\n });\n builder.failure('malformed_receipt');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n kid = header.kid;\n builder.pass('jws.protected_header', { alg: header.alg, typ: header.typ, kid: header.kid });\n\n // ---------------------------------------------------------------------------\n // Check 4: claims.schema_unverified - Pre-signature schema check\n // ---------------------------------------------------------------------------\n try {\n ReceiptClaims.parse(payload);\n issuer = payload.iss;\n builder.pass('claims.schema_unverified');\n } catch (err) {\n builder.fail('claims.schema_unverified', 'E_VERIFY_SCHEMA_INVALID', {\n error: err instanceof Error ? err.message : String(err),\n });\n builder.failure('schema_invalid');\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // ---------------------------------------------------------------------------\n // Check 5: issuer.trust_policy - Check issuer allowlist/pins\n // ---------------------------------------------------------------------------\n const normalizedIssuer = normalizeIssuer(issuer!);\n\n if (!isIssuerAllowed(issuer!, policy.issuer_allowlist)) {\n builder.fail('issuer.trust_policy', 'E_VERIFY_ISSUER_NOT_ALLOWED', {\n issuer: normalizedIssuer,\n allowlist: policy.issuer_allowlist,\n });\n builder.failure('issuer_not_allowed', normalizedIssuer, kid);\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n builder.pass('issuer.trust_policy', { issuer: normalizedIssuer });\n\n // ---------------------------------------------------------------------------\n // Check 6: issuer.discovery - Fetch JWKS (if network mode)\n // Check 7: key.resolve - Resolve signing key by kid\n // ---------------------------------------------------------------------------\n let publicKey: Uint8Array;\n let keySource: 'pinned_keys' | 'jwks_discovery';\n let keyThumbprint: string | undefined;\n let jwksRawBytes: Uint8Array | undefined;\n\n // Check for pinned key first\n const pinnedKey = findPinnedKey(issuer!, kid!, policy.pinned_keys);\n\n if (pinnedKey) {\n // Use pinned key - skip discovery\n builder.skip('issuer.discovery', { reason: 'pinned_key_available' });\n\n // Check if pinned key has key material for offline verification\n if (pinnedKey.jwk) {\n // Full JWK provided - verify thumbprint and use directly\n const actualThumbprint = await computeJwkThumbprint(pinnedKey.jwk);\n if (actualThumbprint !== pinnedKey.jwk_thumbprint_sha256) {\n builder.fail('key.resolve', 'E_VERIFY_POLICY_VIOLATION', {\n error: 'Pinned JWK thumbprint does not match declared thumbprint',\n expected: pinnedKey.jwk_thumbprint_sha256,\n actual: actualThumbprint,\n });\n builder.failure('policy_violation', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n publicKey = jwkToPublicKeyBytes(pinnedKey.jwk);\n keySource = 'pinned_keys';\n keyThumbprint = actualThumbprint;\n builder.pass('key.resolve', {\n source: keySource,\n kid,\n thumbprint_verified: true,\n offline: true,\n });\n } else if (pinnedKey.public_key) {\n // Raw public key bytes provided (base64url, 32 bytes for Ed25519)\n try {\n publicKey = base64urlDecode(pinnedKey.public_key);\n if (publicKey.length !== 32) {\n throw new Error(`Expected 32 bytes, got ${publicKey.length}`);\n }\n keySource = 'pinned_keys';\n // Note: We can't compute thumbprint from raw key bytes alone\n // The thumbprint is computed from canonical JWK JSON\n // Use the declared thumbprint from the pinned key entry\n keyThumbprint = pinnedKey.jwk_thumbprint_sha256;\n builder.pass('key.resolve', {\n source: keySource,\n kid,\n offline: true,\n thumbprint_verified: false,\n });\n } catch (err) {\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n error: `Invalid pinned public_key: ${err instanceof Error ? err.message : String(err)}`,\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n } else if (policy.mode === 'offline_only') {\n // Offline mode but pinned key has no key material - fail\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n error: 'Offline mode requires key material (jwk or public_key) in pinned_keys',\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n } else {\n // Network mode - fetch JWKS and verify thumbprint\n const jwksResult = await fetchIssuerJWKS(normalizedIssuer);\n\n if ('error' in jwksResult) {\n const reason = ssrfErrorToReasonCode(jwksResult.error.reason, 'key');\n builder.fail('issuer.discovery', reasonCodeToErrorCode(reason), {\n error: jwksResult.error.message,\n url: jwksResult.error.blockedUrl,\n });\n builder.failure(reason, normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n // Store raw bytes for digest computation (only when not from cache)\n if (jwksResult.rawBytes) {\n jwksRawBytes = jwksResult.rawBytes;\n }\n\n builder.pass('issuer.discovery', {\n from_cache: jwksResult.fromCache,\n keys_count: jwksResult.jwks.keys.length,\n });\n\n // Find the key\n const jwk = jwksResult.jwks.keys.find((k) => k.kid === kid);\n if (!jwk) {\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n kid,\n available_kids: jwksResult.jwks.keys.map((k) => k.kid),\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n // Verify thumbprint matches\n const actualThumbprint = await computeJwkThumbprint(jwk);\n if (actualThumbprint !== pinnedKey.jwk_thumbprint_sha256) {\n builder.fail('key.resolve', 'E_VERIFY_POLICY_VIOLATION', {\n error: 'JWK thumbprint does not match pinned key',\n expected: pinnedKey.jwk_thumbprint_sha256,\n actual: actualThumbprint,\n });\n builder.failure('policy_violation', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n publicKey = jwkToPublicKeyBytes(jwk);\n keySource = 'pinned_keys';\n keyThumbprint = actualThumbprint;\n builder.pass('key.resolve', { source: keySource, kid, thumbprint_verified: true });\n }\n } else {\n // No pinned key - need to discover\n if (policy.mode === 'offline_only') {\n builder.fail('issuer.discovery', 'E_VERIFY_KEY_NOT_FOUND', {\n error: 'Offline mode requires pinned keys',\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n const jwksResult = await fetchIssuerJWKS(normalizedIssuer);\n\n if ('error' in jwksResult) {\n const reason = ssrfErrorToReasonCode(jwksResult.error.reason, 'key');\n builder.fail('issuer.discovery', reasonCodeToErrorCode(reason), {\n error: jwksResult.error.message,\n url: jwksResult.error.blockedUrl,\n });\n builder.failure(reason, normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n // Store raw bytes for digest computation (only when not from cache)\n if (jwksResult.rawBytes) {\n jwksRawBytes = jwksResult.rawBytes;\n }\n\n builder.pass('issuer.discovery', {\n from_cache: jwksResult.fromCache,\n keys_count: jwksResult.jwks.keys.length,\n });\n\n // Find the key\n const jwk = jwksResult.jwks.keys.find((k) => k.kid === kid);\n if (!jwk) {\n builder.fail('key.resolve', 'E_VERIFY_KEY_NOT_FOUND', {\n kid,\n available_kids: jwksResult.jwks.keys.map((k) => k.kid),\n });\n builder.failure('key_not_found', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n publicKey = jwkToPublicKeyBytes(jwk);\n keySource = 'jwks_discovery';\n keyThumbprint = await computeJwkThumbprint(jwk);\n builder.pass('key.resolve', { source: keySource, kid, thumbprint: keyThumbprint });\n }\n\n // ---------------------------------------------------------------------------\n // Check 8: jws.signature - Verify signature\n // ---------------------------------------------------------------------------\n try {\n const result = await jwsVerify<PEACReceiptClaims>(receiptJws, publicKey);\n\n if (!result.valid) {\n builder.fail('jws.signature', 'E_VERIFY_SIGNATURE_INVALID', {\n error: 'Ed25519 signature verification failed',\n });\n builder.failure('signature_invalid', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n\n parsedClaims = result.payload;\n builder.pass('jws.signature');\n } catch (err) {\n builder.fail('jws.signature', 'E_VERIFY_SIGNATURE_INVALID', {\n error: err instanceof Error ? err.message : String(err),\n });\n builder.failure('signature_invalid', normalizedIssuer, kid);\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // ---------------------------------------------------------------------------\n // Check 9: claims.time_window - Check iat/exp\n // ---------------------------------------------------------------------------\n const iatTolerance = 60; // 60 seconds tolerance for future iat\n\n // Check iat (issued at) - required field per schema\n if (parsedClaims!.iat > nowSeconds + iatTolerance) {\n builder.fail('claims.time_window', 'E_VERIFY_NOT_YET_VALID', {\n error: 'Receipt issued in the future',\n iat: parsedClaims!.iat,\n now: nowSeconds,\n tolerance: iatTolerance,\n });\n builder.failure('not_yet_valid', normalizedIssuer, kid);\n return { valid: false, report: includeMeta ? builder.addTimestamp().build() : builder.build() };\n }\n\n // Check exp (expiration) - no tolerance\n if (parsedClaims!.exp) {\n if (parsedClaims!.exp < nowSeconds) {\n builder.fail('claims.time_window', 'E_VERIFY_EXPIRED', {\n error: 'Receipt expired',\n exp: parsedClaims!.exp,\n now: nowSeconds,\n });\n builder.failure('expired', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n }\n\n builder.pass('claims.time_window', {\n iat: parsedClaims!.iat,\n exp: parsedClaims!.exp,\n now: nowSeconds,\n });\n\n // ---------------------------------------------------------------------------\n // Check 10: extensions.limits - Check extension sizes\n // ---------------------------------------------------------------------------\n // Check for oversized extensions in ext object\n if (parsedClaims!.ext) {\n for (const [extKey, extValue] of Object.entries(parsedClaims!.ext)) {\n if (extValue !== undefined) {\n const extJson = JSON.stringify(extValue);\n if (extJson.length > policy.limits.max_extension_bytes) {\n builder.fail('extensions.limits', 'E_VERIFY_EXTENSION_TOO_LARGE', {\n extension: extKey,\n size: extJson.length,\n limit: policy.limits.max_extension_bytes,\n });\n builder.failure('extension_too_large', normalizedIssuer, kid);\n return {\n valid: false,\n report: includeMeta ? builder.addTimestamp().build() : builder.build(),\n };\n }\n }\n }\n }\n\n builder.pass('extensions.limits');\n\n // ---------------------------------------------------------------------------\n // Success!\n // ---------------------------------------------------------------------------\n builder.success(normalizedIssuer, kid!);\n\n // Add JWKS artifacts for enterprise debuggability\n // Map internal key source to artifact format\n const artifactKeySource = keySource === 'pinned_keys' ? 'pinned' : 'jwks_fetch';\n builder.addArtifact('issuer_key_source', artifactKeySource);\n\n if (keyThumbprint) {\n builder.addArtifact('issuer_key_thumbprint', keyThumbprint);\n }\n\n // Add JWKS digest when fetched (not from cache)\n // Computed over raw bytes to avoid encoding round-trip issues\n if (jwksRawBytes) {\n const jwksDigestHex = await sha256Hex(jwksRawBytes);\n builder.addArtifact('issuer_jwks_digest', createDigest(jwksDigestHex));\n }\n\n const report = includeMeta ? builder.addTimestamp().build() : builder.build();\n\n return {\n valid: true,\n report,\n claims: parsedClaims,\n };\n}\n\n/**\n * Clear the JWKS cache\n */\nexport function clearJWKSCache(): void {\n jwksCache.clear();\n}\n\n/**\n * Get JWKS cache size (for testing)\n */\nexport function getJWKSCacheSize(): number {\n return jwksCache.size;\n}\n","/**\n * PEAC Transport Profile Parsers\n *\n * Implements parsing for transport profiles per TRANSPORT-PROFILES.md:\n * - Header profile (PEAC-Receipt header)\n * - Pointer profile (PEAC-Receipt-Pointer header)\n * - Body profile (peac_receipt/peac_receipts in JSON body)\n *\n * @packageDocumentation\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Transport profile type\n */\nexport type TransportProfile = 'header' | 'pointer' | 'body';\n\n/**\n * Result of parsing a header transport profile\n */\nexport interface HeaderProfileResult {\n profile: 'header';\n receipt: string;\n}\n\n/**\n * Result of parsing a pointer transport profile\n */\nexport interface PointerProfileResult {\n profile: 'pointer';\n digestAlg: 'sha256';\n digestValue: string;\n url: string;\n /**\n * Extension parameters (keys starting with ext_).\n * Stored separately from normative fields for forward-compatibility.\n * Consumers SHOULD NOT rely on extension keys for core verification logic.\n */\n extensions?: Record<string, string>;\n}\n\n/**\n * Result of parsing a body transport profile\n */\nexport interface BodyProfileResult {\n profile: 'body';\n receipts: string[];\n}\n\n/**\n * Parsed transport profile (discriminated union)\n */\nexport type ParsedTransportProfile = HeaderProfileResult | PointerProfileResult | BodyProfileResult;\n\n/**\n * Transport profile parse error\n */\nexport interface TransportProfileError {\n ok: false;\n reason: 'invalid_transport' | 'malformed_receipt' | 'pointer_fetch_blocked';\n errorCode: string;\n message: string;\n}\n\n/**\n * Transport profile parse success\n */\nexport interface TransportProfileSuccess<\n T extends ParsedTransportProfile = ParsedTransportProfile,\n> {\n ok: true;\n result: T;\n}\n\n/**\n * Transport profile parse result\n */\nexport type TransportProfileParseResult<T extends ParsedTransportProfile = ParsedTransportProfile> =\n | TransportProfileSuccess<T>\n | TransportProfileError;\n\n// ---------------------------------------------------------------------------\n// Header Profile Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse PEAC-Receipt header\n *\n * Per TRANSPORT-PROFILES.md:\n * - Multiple headers MUST be rejected\n * - Comma-separated values MUST be rejected\n * - Value MUST be JWS compact serialization (three dot-separated segments)\n *\n * @param headerValue - PEAC-Receipt header value (string or array if multiple)\n * @returns Parse result\n */\nexport function parseHeaderProfile(\n headerValue: string | string[] | undefined\n): TransportProfileParseResult<HeaderProfileResult> {\n // Check for missing header\n if (headerValue === undefined || headerValue === '') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt header is missing',\n };\n }\n\n // Check for multiple headers (array)\n if (Array.isArray(headerValue)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Multiple PEAC-Receipt headers are not allowed',\n };\n }\n\n // Check for comma-separated values (HTTP header list syntax)\n if (headerValue.includes(',')) {\n // Could be comma in base64url, but JWS compact has exactly 2 periods\n // If there are commas between periods, it's likely multiple values\n const parts = headerValue.split('.');\n if (parts.length !== 3 || parts.some((p) => p.includes(','))) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Comma-separated PEAC-Receipt values are not allowed',\n };\n }\n }\n\n // Validate JWS compact serialization structure (three segments)\n const segments = headerValue.split('.');\n if (segments.length !== 3) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: `Invalid JWS compact serialization: expected 3 segments, got ${segments.length}`,\n };\n }\n\n // All segments must be non-empty base64url strings\n const base64urlRegex = /^[A-Za-z0-9_-]*$/;\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment.length === 0) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: `Invalid JWS compact serialization: segment ${i + 1} is empty`,\n };\n }\n if (!base64urlRegex.test(segment)) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: `Invalid JWS compact serialization: segment ${i + 1} contains invalid characters`,\n };\n }\n }\n\n return {\n ok: true,\n result: {\n profile: 'header',\n receipt: headerValue,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Pointer Profile Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse PEAC-Receipt-Pointer header\n *\n * Per TRANSPORT-PROFILES.md:\n * - Format: RFC 9651 dictionary with sha256 and url parameters\n * - Multiple headers MUST be rejected\n * - URL MUST be HTTPS\n *\n * Example: sha256=\"7d8f...\", url=\"https://receipts.example.com/abc123\"\n *\n * @param headerValue - PEAC-Receipt-Pointer header value (string or array if multiple)\n * @returns Parse result\n */\nexport function parsePointerProfile(\n headerValue: string | string[] | undefined\n): TransportProfileParseResult<PointerProfileResult> {\n // Check for missing header\n if (headerValue === undefined || headerValue === '') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer header is missing',\n };\n }\n\n // Check for multiple headers (array)\n if (Array.isArray(headerValue)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Multiple PEAC-Receipt-Pointer headers are not allowed',\n };\n }\n\n // Parse RFC 9651 dictionary format\n // Format: sha256=\"<hex>\", url=\"<url>\"\n // We use a simple parser here instead of a full RFC 9651 implementation\n\n const parseResult = parseSimpleDictionary(headerValue);\n\n // Strict: Reject duplicate parameters\n if (parseResult.duplicates.length > 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: `PEAC-Receipt-Pointer has duplicate parameter: ${parseResult.duplicates[0]}`,\n };\n }\n\n // Strict: Reject unknown parameters (only sha256, url, and ext_* are valid)\n // Extension keys (ext_*) are allowed for forward-compatibility\n const ALLOWED_KEYS = new Set(['sha256', 'url']);\n const unknownKeys = parseResult.keys.filter((k) => !ALLOWED_KEYS.has(k) && !k.startsWith('ext_'));\n if (unknownKeys.length > 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: `PEAC-Receipt-Pointer has unknown parameter: ${unknownKeys[0]}`,\n };\n }\n\n const params = parseResult.params;\n\n if (!params.sha256) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer missing sha256 parameter',\n };\n }\n\n if (!params.url) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer missing url parameter',\n };\n }\n\n // Validate digest is lowercase hex\n const hexRegex = /^[0-9a-f]{64}$/;\n if (!hexRegex.test(params.sha256)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer sha256 must be 64 lowercase hex characters',\n };\n }\n\n // Validate URL is HTTPS\n try {\n const url = new URL(params.url);\n if (url.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'pointer_fetch_blocked',\n errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n message: 'Pointer URL must use HTTPS',\n };\n }\n } catch {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'PEAC-Receipt-Pointer url is not a valid URL',\n };\n }\n\n // Extract extension keys (ext_*) for forward-compatibility\n const extensions: Record<string, string> = {};\n for (const key of parseResult.keys) {\n if (key.startsWith('ext_')) {\n extensions[key] = params[key];\n }\n }\n\n return {\n ok: true,\n result: {\n profile: 'pointer',\n digestAlg: 'sha256',\n digestValue: params.sha256,\n url: params.url,\n ...(Object.keys(extensions).length > 0 && { extensions }),\n },\n };\n}\n\n/**\n * Simple RFC 9651-like dictionary parser result\n */\ninterface DictionaryParseResult {\n /** Parsed key-value pairs */\n params: Record<string, string>;\n /** Duplicate keys found (strict mode violation) */\n duplicates: string[];\n /** All keys found (for unknown key detection) */\n keys: string[];\n}\n\n/**\n * Simple RFC 9651-like dictionary parser (ReDoS-safe)\n *\n * Parses: key1=\"value1\", key2=\"value2\"\n * Returns map of key -> value (unquoted) plus metadata for strict validation\n *\n * Uses explicit character-by-character parsing to avoid ReDoS vulnerabilities\n * from regex alternation patterns.\n */\nfunction parseSimpleDictionary(input: string): DictionaryParseResult {\n const params: Record<string, string> = {};\n const duplicates: string[] = [];\n const keys: string[] = [];\n\n let i = 0;\n const len = input.length;\n\n while (i < len) {\n // Skip whitespace and commas\n while (i < len && (input[i] === ' ' || input[i] === ',' || input[i] === '\\t')) {\n i++;\n }\n if (i >= len) break;\n\n // Parse key (word characters only)\n const keyStart = i;\n while (i < len && /\\w/.test(input[i])) {\n i++;\n }\n const key = input.slice(keyStart, i);\n if (!key) break;\n\n // Skip whitespace before '='\n while (i < len && input[i] === ' ') i++;\n\n // Expect '='\n if (i >= len || input[i] !== '=') break;\n i++; // skip '='\n\n // Skip whitespace after '='\n while (i < len && input[i] === ' ') i++;\n\n // Parse value (quoted or unquoted)\n let value: string;\n if (input[i] === '\"') {\n // Quoted value - find closing quote\n i++; // skip opening quote\n const valueStart = i;\n while (i < len && input[i] !== '\"') {\n i++;\n }\n value = input.slice(valueStart, i);\n if (i < len) i++; // skip closing quote\n } else {\n // Unquoted value - read until comma or whitespace\n const valueStart = i;\n while (i < len && input[i] !== ',' && input[i] !== ' ' && input[i] !== '\\t') {\n i++;\n }\n value = input.slice(valueStart, i);\n }\n\n keys.push(key);\n\n // Track duplicates\n if (key in params) {\n duplicates.push(key);\n }\n\n params[key] = value;\n }\n\n return { params, duplicates, keys };\n}\n\n// ---------------------------------------------------------------------------\n// Body Profile Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Parse body profile (JSON body with peac_receipt or peac_receipts)\n *\n * Per TRANSPORT-PROFILES.md:\n * - peac_receipt: single receipt (string)\n * - peac_receipts: multiple receipts (array of strings)\n *\n * @param body - Parsed JSON body object\n * @returns Parse result\n */\nexport function parseBodyProfile(body: unknown): TransportProfileParseResult<BodyProfileResult> {\n if (body === null || typeof body !== 'object') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Body must be a JSON object',\n };\n }\n\n const obj = body as Record<string, unknown>;\n\n // Check for peac_receipts (array, takes precedence)\n if ('peac_receipts' in obj) {\n if (!Array.isArray(obj.peac_receipts)) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipts must be an array',\n };\n }\n\n const receipts: string[] = [];\n for (let i = 0; i < obj.peac_receipts.length; i++) {\n const receipt = obj.peac_receipts[i];\n if (typeof receipt !== 'string') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: `peac_receipts[${i}] must be a string`,\n };\n }\n receipts.push(receipt);\n }\n\n if (receipts.length === 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipts array is empty',\n };\n }\n\n return {\n ok: true,\n result: {\n profile: 'body',\n receipts,\n },\n };\n }\n\n // Check for peac_receipt (single)\n if ('peac_receipt' in obj) {\n if (typeof obj.peac_receipt !== 'string') {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipt must be a string',\n };\n }\n\n if (obj.peac_receipt.length === 0) {\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'peac_receipt is empty',\n };\n }\n\n return {\n ok: true,\n result: {\n profile: 'body',\n receipts: [obj.peac_receipt],\n },\n };\n }\n\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message: 'Body must contain peac_receipt or peac_receipts',\n };\n}\n\n// ---------------------------------------------------------------------------\n// Auto-detect Parser\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect and parse transport profile from request context\n *\n * @param context - Request context with headers and optional body\n * @returns Parse result\n */\nexport function parseTransportProfile(context: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n}): TransportProfileParseResult {\n const peacReceipt = context.headers['peac-receipt'] ?? context.headers['PEAC-Receipt'];\n const peacPointer =\n context.headers['peac-receipt-pointer'] ?? context.headers['PEAC-Receipt-Pointer'];\n\n // Header profile takes precedence\n if (peacReceipt !== undefined) {\n return parseHeaderProfile(peacReceipt);\n }\n\n // Pointer profile second\n if (peacPointer !== undefined) {\n return parsePointerProfile(peacPointer);\n }\n\n // Body profile last (if body provided)\n if (context.body !== undefined) {\n return parseBodyProfile(context.body);\n }\n\n return {\n ok: false,\n reason: 'invalid_transport',\n errorCode: 'E_VERIFY_INVALID_TRANSPORT',\n message:\n 'No transport profile detected (missing PEAC-Receipt, PEAC-Receipt-Pointer, or body receipt)',\n };\n}\n","/**\n * PEAC Pointer Fetch with Digest Verification\n *\n * Implements secure receipt fetching via pointers per TRANSPORT-PROFILES.md:\n * - SSRF-safe fetch\n * - SHA-256 digest verification\n * - Size limits\n *\n * @packageDocumentation\n */\n\nimport { sha256Hex } from '@peac/crypto';\nimport { VERIFIER_LIMITS } from '@peac/kernel';\nimport { ssrfSafeFetch, type SSRFFetchOptions, type SSRFFetchError } from './ssrf-safe-fetch.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Pointer fetch options\n */\nexport interface PointerFetchOptions {\n /** URL to fetch the receipt from */\n url: string;\n /** Expected SHA-256 digest (lowercase hex, 64 chars) */\n expectedDigest: string;\n /** Optional SSRF fetch options */\n fetchOptions?: Omit<SSRFFetchOptions, 'maxBytes'>;\n}\n\n/**\n * Successful pointer fetch result\n */\nexport interface PointerFetchSuccess {\n ok: true;\n /** Fetched receipt (JWS compact serialization) */\n receipt: string;\n /** Actual SHA-256 digest of fetched content */\n actualDigest: string;\n /** Whether digest matched expected */\n digestMatched: true;\n /** Content-Type header (if present) */\n contentType?: string;\n /**\n * Warning about unexpected Content-Type.\n * Present when Content-Type is not application/jose, application/json, or text/plain.\n * Does not cause rejection (for interoperability) but callers may want to log.\n */\n contentTypeWarning?: string;\n}\n\n/**\n * Failed pointer fetch result\n */\nexport interface PointerFetchError {\n ok: false;\n /** Error reason */\n reason:\n | 'pointer_fetch_blocked'\n | 'pointer_fetch_failed'\n | 'pointer_fetch_timeout'\n | 'pointer_fetch_too_large'\n | 'pointer_digest_mismatch'\n | 'malformed_receipt';\n /** Error code for reports */\n errorCode: string;\n /** Human-readable error message */\n message: string;\n /** Actual digest if computed (for mismatch errors) */\n actualDigest?: string;\n /** Expected digest */\n expectedDigest?: string;\n}\n\n/**\n * Pointer fetch result\n */\nexport type PointerFetchResult = PointerFetchSuccess | PointerFetchError;\n\n// ---------------------------------------------------------------------------\n// Error Mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Map SSRF error reason to pointer error reason\n */\nfunction mapSsrfError(ssrfError: SSRFFetchError): PointerFetchError {\n const reason = ssrfError.reason;\n\n switch (reason) {\n case 'not_https':\n case 'private_ip':\n case 'loopback':\n case 'link_local':\n case 'dns_failure':\n case 'cross_origin_redirect':\n return {\n ok: false,\n reason: 'pointer_fetch_blocked',\n errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n message: ssrfError.message,\n };\n\n case 'timeout':\n return {\n ok: false,\n reason: 'pointer_fetch_timeout',\n errorCode: 'E_VERIFY_POINTER_FETCH_TIMEOUT',\n message: ssrfError.message,\n };\n\n case 'response_too_large':\n return {\n ok: false,\n reason: 'pointer_fetch_too_large',\n errorCode: 'E_VERIFY_POINTER_FETCH_TOO_LARGE',\n message: ssrfError.message,\n };\n\n default:\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: ssrfError.message,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pointer Fetch\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch a receipt via pointer with digest verification\n *\n * Per TRANSPORT-PROFILES.md:\n * - Fetch the URL using SSRF-safe fetch\n * - Compute SHA-256 digest of response\n * - Verify digest matches expected value from header\n * - Return receipt only if digest matches\n *\n * @param options - Pointer fetch options\n * @returns Fetch result\n */\nexport async function fetchPointerWithDigest(\n options: PointerFetchOptions\n): Promise<PointerFetchResult> {\n const { url, expectedDigest, fetchOptions = {} } = options;\n\n // Validate expected digest format\n const hexRegex = /^[0-9a-f]{64}$/;\n if (!hexRegex.test(expectedDigest)) {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'Invalid expected digest: must be 64 lowercase hex characters',\n };\n }\n\n // Validate URL is HTTPS (pre-check before fetch)\n try {\n const parsedUrl = new URL(url);\n if (parsedUrl.protocol !== 'https:') {\n return {\n ok: false,\n reason: 'pointer_fetch_blocked',\n errorCode: 'E_VERIFY_POINTER_FETCH_BLOCKED',\n message: 'Pointer URL must use HTTPS',\n };\n }\n } catch {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'Invalid pointer URL',\n };\n }\n\n // Fetch with SSRF protection and DoS bounds\n // - Size cap: maxReceiptBytes (prevents memory exhaustion)\n // - No redirects: prevents redirect-based SSRF (pointer URL must be direct)\n // - Timeout: prevents slow-loris style attacks\n const fetchResult = await ssrfSafeFetch(url, {\n ...fetchOptions,\n maxBytes: VERIFIER_LIMITS.maxReceiptBytes,\n allowRedirects: false, // Pointer URL must be direct - no redirects\n timeoutMs: fetchOptions?.timeoutMs ?? VERIFIER_LIMITS.fetchTimeoutMs,\n headers: {\n Accept: 'application/jose, application/json, text/plain',\n ...fetchOptions.headers,\n },\n });\n\n if (!fetchResult.ok) {\n return mapSsrfError(fetchResult);\n }\n\n const receipt = fetchResult.body;\n\n // Validate Content-Type if present (warn but don't reject for interoperability)\n // Expected: application/jose, application/json, or text/plain\n const contentType = fetchResult.contentType;\n const expectedContentTypes = ['application/jose', 'application/json', 'text/plain'];\n const contentTypeWarning =\n contentType && !expectedContentTypes.some((expected) => contentType.startsWith(expected))\n ? `Unexpected Content-Type: ${contentType}; expected application/jose, application/json, or text/plain`\n : undefined;\n\n // Validate: reject empty body\n if (!receipt || receipt.trim().length === 0) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: 'Pointer target returned empty content',\n };\n }\n\n // Validate: content must look like JWS compact serialization (3 dot-separated segments)\n const jwsValidation = validateJwsCompactStructure(receipt);\n if (!jwsValidation.valid) {\n return {\n ok: false,\n reason: 'malformed_receipt',\n errorCode: 'E_VERIFY_MALFORMED_RECEIPT',\n message: jwsValidation.message,\n };\n }\n\n // Compute digest of fetched content (hash the raw string bytes)\n const actualDigest = await sha256Hex(receipt);\n\n // Verify digest matches\n if (actualDigest !== expectedDigest) {\n return {\n ok: false,\n reason: 'pointer_digest_mismatch',\n errorCode: 'E_VERIFY_POINTER_DIGEST_MISMATCH',\n message: 'Fetched receipt digest does not match expected digest',\n actualDigest,\n expectedDigest,\n };\n }\n\n return {\n ok: true,\n receipt,\n actualDigest,\n digestMatched: true,\n contentType: fetchResult.contentType,\n ...(contentTypeWarning && { contentTypeWarning }),\n };\n}\n\n/**\n * Validate that a string looks like JWS compact serialization\n *\n * A valid JWS compact has exactly 3 dot-separated base64url segments.\n *\n * @param value - String to validate\n * @returns Validation result\n */\nfunction validateJwsCompactStructure(\n value: string\n): { valid: true } | { valid: false; message: string } {\n const segments = value.split('.');\n\n if (segments.length !== 3) {\n return {\n valid: false,\n message: `Invalid JWS compact serialization: expected 3 segments, got ${segments.length}`,\n };\n }\n\n // All segments must be non-empty and contain only base64url characters\n const base64urlRegex = /^[A-Za-z0-9_-]+$/;\n\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (segment.length === 0) {\n return {\n valid: false,\n message: `Invalid JWS compact serialization: segment ${i + 1} is empty`,\n };\n }\n if (!base64urlRegex.test(segment)) {\n return {\n valid: false,\n message: `Invalid JWS compact serialization: segment ${i + 1} contains invalid characters`,\n };\n }\n }\n\n return { valid: true };\n}\n\n/**\n * Parse pointer header key=value pairs (ReDoS-safe)\n *\n * Handles both quoted and unquoted values without complex regex alternation.\n */\nfunction parsePointerHeader(input: string): Record<string, string> {\n const params: Record<string, string> = {};\n let i = 0;\n const len = input.length;\n\n while (i < len) {\n // Skip whitespace and commas\n while (i < len && (input[i] === ' ' || input[i] === ',' || input[i] === '\\t')) {\n i++;\n }\n if (i >= len) break;\n\n // Parse key (word characters only)\n const keyStart = i;\n while (i < len && /\\w/.test(input[i])) {\n i++;\n }\n const key = input.slice(keyStart, i);\n if (!key) break;\n\n // Skip whitespace before '='\n while (i < len && input[i] === ' ') i++;\n\n // Expect '='\n if (i >= len || input[i] !== '=') break;\n i++; // skip '='\n\n // Skip whitespace after '='\n while (i < len && input[i] === ' ') i++;\n\n // Parse value (quoted or unquoted)\n let value: string;\n if (input[i] === '\"') {\n // Quoted value - find closing quote\n i++; // skip opening quote\n const valueStart = i;\n while (i < len && input[i] !== '\"') {\n i++;\n }\n value = input.slice(valueStart, i);\n if (i < len) i++; // skip closing quote\n } else {\n // Unquoted value - read until comma or whitespace\n const valueStart = i;\n while (i < len && input[i] !== ',' && input[i] !== ' ' && input[i] !== '\\t') {\n i++;\n }\n value = input.slice(valueStart, i);\n }\n\n params[key] = value;\n }\n\n return params;\n}\n\n/**\n * Verify a pointer header and fetch the receipt\n *\n * Combines parsing and fetching in a single operation.\n *\n * @param pointerHeader - PEAC-Receipt-Pointer header value\n * @param fetchOptions - Optional SSRF fetch options\n * @returns Fetch result\n */\nexport async function verifyAndFetchPointer(\n pointerHeader: string,\n fetchOptions?: Omit<SSRFFetchOptions, 'maxBytes'>\n): Promise<PointerFetchResult> {\n // Parse pointer header (RFC 9651 dictionary format)\n // Format: sha256=\"<hex>\", url=\"<url>\"\n // Using explicit parsing to avoid ReDoS in regex alternation\n const params = parsePointerHeader(pointerHeader);\n\n if (!params.sha256) {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'PEAC-Receipt-Pointer missing sha256 parameter',\n };\n }\n\n if (!params.url) {\n return {\n ok: false,\n reason: 'pointer_fetch_failed',\n errorCode: 'E_VERIFY_POINTER_FETCH_FAILED',\n message: 'PEAC-Receipt-Pointer missing url parameter',\n };\n }\n\n return fetchPointerWithDigest({\n url: params.url,\n expectedDigest: params.sha256,\n fetchOptions,\n });\n}\n"]}
|