@nextera.one/axis-server-sdk 2.3.5 → 2.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cce/cce.types.ts","../../src/cce/cce-derivation.service.ts","../../src/cce/cce-crypto.ts","../../src/cce/cce-response.service.ts","../../src/cce/cce-witness.observer.ts","../../src/sensor/axis-sensor.ts","../../src/cce/cce-pipeline.ts","../../src/cce/sensors/cce-envelope-validation.sensor.ts","../../src/cce/sensors/cce-client-signature.sensor.ts","../../src/cce/sensors/cce-capsule-verification.sensor.ts","../../src/cce/sensors/cce-tps-window.sensor.ts","../../src/cce/sensors/cce-audience-intent-binding.sensor.ts","../../src/cce/sensors/cce-replay-protection.sensor.ts","../../src/cce/sensors/cce-payload-decryption.sensor.ts"],"sourcesContent":["/**\n * Capsule-Carried Encryption (CCE) Types — v1\n *\n * Defines the core types for the CCE protocol where:\n * - TickAuth issues capsules (authority)\n * - AXIS verifies capsules, decrypts payloads, derives execution context\n * - Payload confidentiality uses hybrid encryption (AES-GCM + AXIS public key)\n */\n\n// ============================================================================\n// CCE Protocol Constants\n// ============================================================================\n\nexport const CCE_PROTOCOL_VERSION = \"cce-v1\" as const;\n\n/** Derivation context prefixes for HKDF */\nexport const CCE_DERIVATION = {\n /** Request execution context */\n REQUEST: \"axis:cce:req:v1\",\n /** Response execution context */\n RESPONSE: \"axis:cce:resp:v1\",\n /** Witness binding context */\n WITNESS: \"axis:cce:witness:v1\",\n} as const;\n\n/** Supported encryption algorithms */\nexport type CceAlgorithm = \"AES-256-GCM\";\n/** Supported key encapsulation algorithms */\nexport type CceKemAlgorithm = \"X25519\" | \"RSA-OAEP-256\";\n/** Supported KDF algorithms */\nexport type CceKdfAlgorithm = \"HKDF-SHA256\";\n\nexport const CCE_AES_KEY_BYTES = 32; // 256-bit AES key\nexport const CCE_IV_BYTES = 12; // 96-bit GCM nonce\nexport const CCE_TAG_BYTES = 16; // 128-bit GCM auth tag\nexport const CCE_NONCE_BYTES = 32; // 256-bit request/response nonce\n\n// ============================================================================\n// CCE Capsule Claims (extends TickAuth capsule for AXIS binding)\n// ============================================================================\n\n/**\n * CCE-specific claims that extend the TickAuth capsule.\n * These claims bind the capsule to a specific AXIS audience and intent.\n */\nexport interface CceCapsuleClaims {\n /** Capsule identifier (content-addressed) */\n capsule_id: string;\n /** Protocol version */\n ver: typeof CCE_PROTOCOL_VERSION;\n /** Subject / actor identity */\n sub: string;\n /** Client key identifier */\n kid: string;\n /** Bound intent */\n intent: string;\n /** AXIS audience (service identity) */\n aud: string;\n /** TPS window start (Unix ms or TPS index) */\n tps_from: number;\n /** TPS window end (Unix ms or TPS index) */\n tps_to: number;\n /** Capsule nonce (hex, from challenge) */\n capsule_nonce: string;\n /** Reference to originating challenge */\n challenge_id: string;\n /** Content hash of the validated proof used to issue this capsule */\n proof_hash?: string;\n /** Policy hash (hex) — Digital Fabric Law binding */\n policy_hash?: string;\n /** Issued-at timestamp (Unix seconds) */\n iat: number;\n /** Expires-at timestamp (Unix seconds) */\n exp: number;\n /** Capsule usage mode */\n mode: \"SINGLE_USE\" | \"SESSION\";\n /** Scope capabilities */\n scope?: string[];\n /** Constraints */\n constraints?: CceConstraints;\n /** TickAuth issuer signature over claims */\n issuer_sig: CceSignature;\n}\n\nexport interface CceConstraints {\n max_payload_bytes?: number;\n ip_allow?: string[];\n device_allow?: string[];\n country_allow?: string[];\n}\n\nexport interface CceSignature {\n alg: \"EdDSA\" | \"ES256\";\n kid: string;\n value: string; // base64url or hex\n}\n\n// ============================================================================\n// CCE Request Envelope\n// ============================================================================\n\n/**\n * The encrypted request envelope sent from Client → AXIS.\n *\n * The client:\n * 1. Generates ephemeral AES-256 key\n * 2. Encrypts payload with AES-256-GCM\n * 3. Encrypts AES key with AXIS public key (X25519 or RSA-OAEP)\n * 4. Signs the envelope with client private key\n * 5. Attaches capsule\n */\nexport interface CceRequestEnvelope {\n /** Protocol version */\n ver: typeof CCE_PROTOCOL_VERSION;\n /** Unique request identifier */\n request_id: string;\n /** Correlation identifier (for request/response binding) */\n correlation_id: string;\n /** Client key identifier */\n client_kid: string;\n /** The capsule claims (signed by TickAuth) */\n capsule: CceCapsuleClaims;\n /** Encrypted transport key (AXIS public key encrypted) */\n encrypted_key: CceEncryptedKey;\n /** Encrypted payload */\n encrypted_payload: CceEncryptedPayload;\n /** Request nonce (hex, 32 bytes) */\n request_nonce: string;\n /** Client signature over canonical envelope */\n client_sig: CceSignature;\n /** Content type of the plaintext payload */\n content_type: string;\n /** Algorithm descriptors */\n algorithms: CceAlgorithmDescriptor;\n /** Additional authenticated data descriptor */\n aad_descriptor?: string;\n}\n\n/**\n * Encrypted symmetric key wrapped by AXIS public key.\n */\nexport interface CceEncryptedKey {\n /** Key encapsulation algorithm */\n alg: CceKemAlgorithm;\n /** AXIS key identifier used for encapsulation */\n axis_kid: string;\n /** Encrypted key bytes (base64url) */\n ciphertext: string;\n /** Ephemeral public key (for X25519 ECDH, base64url) */\n ephemeral_pk?: string;\n}\n\n/**\n * Encrypted payload with AEAD metadata.\n */\nexport interface CceEncryptedPayload {\n /** Encryption algorithm */\n alg: CceAlgorithm;\n /** Initialization vector / nonce (base64url, 12 bytes) */\n iv: string;\n /** Ciphertext (base64url) */\n ciphertext: string;\n /** Authentication tag (base64url, 16 bytes) */\n tag: string;\n}\n\n/**\n * Algorithm descriptor for the envelope.\n */\nexport interface CceAlgorithmDescriptor {\n /** Key encapsulation */\n kem: CceKemAlgorithm;\n /** Symmetric encryption */\n enc: CceAlgorithm;\n /** Key derivation (for execution context) */\n kdf: CceKdfAlgorithm;\n /** Signature algorithm */\n sig: \"EdDSA\" | \"ES256\";\n}\n\n// ============================================================================\n// CCE Response Envelope\n// ============================================================================\n\n/**\n * The encrypted response envelope sent from AXIS → Client.\n */\nexport interface CceResponseEnvelope {\n /** Protocol version */\n ver: typeof CCE_PROTOCOL_VERSION;\n /** Response identifier */\n response_id: string;\n /** Request identifier (binding) */\n request_id: string;\n /** Correlation identifier */\n correlation_id: string;\n /** Capsule identifier of the originating request */\n capsule_id: string;\n /** Encrypted transport key (Client public key encrypted) */\n encrypted_key: CceEncryptedKey;\n /** Encrypted response payload */\n encrypted_payload: CceEncryptedPayload;\n /** Response nonce (hex, 32 bytes) */\n response_nonce: string;\n /** AXIS signature over canonical response */\n axis_sig: CceSignature;\n /** Witness reference */\n witness_ref?: string;\n /** Algorithm descriptors */\n algorithms: CceAlgorithmDescriptor;\n /** Response status (plaintext, allowed on error) */\n status: CceResponseStatus;\n}\n\nexport type CceResponseStatus =\n | \"SUCCESS\"\n | \"DENIED\"\n | \"PARTIAL\"\n | \"FAILED\"\n | \"ERROR\";\n\n// ============================================================================\n// CCE Execution Context (derived inside AXIS)\n// ============================================================================\n\n/**\n * Execution context derived from capsule claims + AXIS local secret.\n * Proves that the request was not only decrypted but legally executable.\n */\nexport interface CceExecutionContext {\n /** Derived execution key (used for witness binding, never exposed) */\n execution_key_hash: string;\n /** Request identifier */\n request_id: string;\n /** Capsule identifier */\n capsule_id: string;\n /** Subject identity */\n sub: string;\n /** Client key identifier */\n kid: string;\n /** Intent */\n intent: string;\n /** Audience */\n aud: string;\n /** TPS window */\n tps_from: number;\n tps_to: number;\n /** Policy hash (if bound) */\n policy_hash?: string;\n /** Timestamp of context derivation */\n derived_at: number;\n /** Whether this context is valid */\n valid: boolean;\n}\n\n// ============================================================================\n// CCE Witness Record\n// ============================================================================\n\n/**\n * Witness record for the CCE request/response lifecycle.\n */\nexport interface CceWitnessRecord {\n /** Witness identifier */\n witness_id: string;\n /** Request identifier */\n request_id: string;\n /** Capsule identifier */\n capsule_id: string;\n /** Subject identity */\n sub: string;\n /** Intent */\n intent: string;\n /** Audience */\n aud: string;\n /** TPS window */\n tps_from: number;\n tps_to: number;\n /** Timestamp */\n timestamp: number;\n\n /** Verification results */\n verification: {\n client_sig: boolean;\n capsule_sig: boolean;\n tps_valid: boolean;\n audience_match: boolean;\n intent_match: boolean;\n replay_clean: boolean;\n nonce_unique: boolean;\n decryption_ok: boolean;\n };\n\n /** Handler execution result */\n execution: {\n status: CceResponseStatus;\n handler_duration_ms: number;\n effect?: string;\n };\n\n /** Response encryption result */\n response_encrypted: boolean;\n\n /** Execution context hash (proves legal execution) */\n execution_context_hash: string;\n\n /** Payload hash (redacted, never raw content) */\n request_payload_hash?: string;\n response_payload_hash?: string;\n}\n\n// ============================================================================\n// CCE Error Codes\n// ============================================================================\n\nexport const CCE_ERROR = {\n // Envelope errors\n INVALID_ENVELOPE: \"CCE_INVALID_ENVELOPE\",\n UNSUPPORTED_VERSION: \"CCE_UNSUPPORTED_VERSION\",\n MISSING_CAPSULE: \"CCE_MISSING_CAPSULE\",\n MISSING_ENCRYPTED_KEY: \"CCE_MISSING_ENCRYPTED_KEY\",\n\n // Signature errors\n CLIENT_SIG_INVALID: \"CCE_CLIENT_SIG_INVALID\",\n CLIENT_KEY_NOT_FOUND: \"CCE_CLIENT_KEY_NOT_FOUND\",\n\n // Capsule errors\n CAPSULE_SIG_INVALID: \"CCE_CAPSULE_SIG_INVALID\",\n CAPSULE_EXPIRED: \"CCE_CAPSULE_EXPIRED\",\n CAPSULE_NOT_YET_VALID: \"CCE_CAPSULE_NOT_YET_VALID\",\n CAPSULE_REVOKED: \"CCE_CAPSULE_REVOKED\",\n CAPSULE_CONSUMED: \"CCE_CAPSULE_CONSUMED\",\n CAPSULE_NOT_VERIFIED: \"CCE_CAPSULE_NOT_VERIFIED\",\n // Binding errors\n AUDIENCE_MISMATCH: \"CCE_AUDIENCE_MISMATCH\",\n INTENT_MISMATCH: \"CCE_INTENT_MISMATCH\",\n TPS_WINDOW_EXPIRED: \"CCE_TPS_WINDOW_EXPIRED\",\n TPS_WINDOW_FUTURE: \"CCE_TPS_WINDOW_FUTURE\",\n\n // Replay / nonce errors\n REPLAY_DETECTED: \"CCE_REPLAY_DETECTED\",\n NONCE_REUSED: \"CCE_NONCE_REUSED\",\n\n // Decryption errors\n DECRYPTION_FAILED: \"CCE_DECRYPTION_FAILED\",\n KEY_UNWRAP_FAILED: \"CCE_KEY_UNWRAP_FAILED\",\n AEAD_TAG_MISMATCH: \"CCE_AEAD_TAG_MISMATCH\",\n PAYLOAD_TOO_LARGE: \"CCE_PAYLOAD_TOO_LARGE\",\n\n // Schema / validation errors\n PAYLOAD_SCHEMA_INVALID: \"CCE_PAYLOAD_SCHEMA_INVALID\",\n INTENT_SCHEMA_MISMATCH: \"CCE_INTENT_SCHEMA_MISMATCH\",\n\n // Policy errors\n POLICY_DENIED: \"CCE_POLICY_DENIED\",\n CONSTRAINT_VIOLATED: \"CCE_CONSTRAINT_VIOLATED\",\n\n // Handler errors\n HANDLER_NOT_FOUND: \"CCE_HANDLER_NOT_FOUND\",\n HANDLER_EXECUTION_FAILED: \"CCE_HANDLER_EXECUTION_FAILED\",\n HANDLER_TIMEOUT: \"CCE_HANDLER_TIMEOUT\",\n\n // Response errors\n RESPONSE_ENCRYPTION_FAILED: \"CCE_RESPONSE_ENCRYPTION_FAILED\",\n} as const;\n\nexport type CceErrorCode = (typeof CCE_ERROR)[keyof typeof CCE_ERROR];\n\n/**\n * Structured CCE error.\n */\nexport class CceError extends Error {\n constructor(\n public readonly code: CceErrorCode,\n message: string,\n public readonly metadata?: Record<string, unknown>,\n ) {\n super(`[${code}] ${message}`);\n this.name = \"CceError\";\n }\n\n /** Whether this error is safe to expose to the client */\n get clientSafe(): boolean {\n // Never expose internal decryption/handler details\n const internal: CceErrorCode[] = [\n CCE_ERROR.DECRYPTION_FAILED,\n CCE_ERROR.KEY_UNWRAP_FAILED,\n CCE_ERROR.AEAD_TAG_MISMATCH,\n CCE_ERROR.HANDLER_EXECUTION_FAILED,\n CCE_ERROR.RESPONSE_ENCRYPTION_FAILED,\n ];\n return !internal.includes(this.code);\n }\n\n /** Get client-safe representation */\n toClientError(): { code: CceErrorCode; message: string } {\n if (this.clientSafe) {\n return { code: this.code, message: this.message };\n }\n return {\n code: CCE_ERROR.DECRYPTION_FAILED,\n message: \"Request processing failed\",\n };\n }\n}\n","import { bytesToHex, hexToBytes } from \"@noble/hashes/utils.js\";\n/**\n * CCE Key Derivation Service\n *\n * Implements HKDF-based key derivation for the Capsule-Carried Encryption protocol.\n * Keys are never placed in capsules — they are derived from:\n * - AXIS local secret (IKM)\n * - Capsule claims (salt + info)\n * - Request/response nonce (direction binding)\n * - Protocol version (upgrade protection)\n *\n * Uses @noble/hashes HKDF (RFC 5869) with SHA-256.\n */\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nimport { CCE_AES_KEY_BYTES, CCE_DERIVATION, CCE_NONCE_BYTES, type CceCapsuleClaims, type CceExecutionContext } from \"./cce.types\";\n\n/**\n * Input parameters for key derivation.\n */\nexport interface CceDerivationInput {\n /** AXIS local secret (hex, must be kept private) */\n axisLocalSecret: string;\n /** Capsule claims from the request */\n capsule: CceCapsuleClaims;\n /** Request nonce (hex) */\n requestNonce: string;\n /** Response nonce (hex, only for response derivation) */\n responseNonce?: string;\n}\n\n/**\n * Build the salt for HKDF from capsule + nonce.\n *\n * salt = SHA-256(capsule_id || capsule_nonce || request_nonce)\n */\nfunction buildSalt(\n capsuleId: string,\n capsuleNonce: string,\n requestNonce: string,\n): Uint8Array {\n const encoder = new TextEncoder();\n const data = encoder.encode(\n capsuleId + \"|\" + capsuleNonce + \"|\" + requestNonce,\n );\n return sha256(data);\n}\n\n/**\n * Build the info string for HKDF.\n * Binds the derived key to all authority dimensions.\n *\n * info = context_prefix | sub | kid | intent | aud | tps_from | tps_to | policy_hash | ver\n */\nfunction buildInfo(\n contextPrefix: string,\n capsule: CceCapsuleClaims,\n extraNonce?: string,\n): Uint8Array {\n const encoder = new TextEncoder();\n const parts = [\n contextPrefix,\n capsule.sub,\n capsule.kid,\n capsule.intent,\n capsule.aud,\n String(capsule.tps_from),\n String(capsule.tps_to),\n capsule.policy_hash ?? \"\",\n capsule.ver,\n ];\n if (extraNonce) {\n parts.push(extraNonce);\n }\n return encoder.encode(parts.join(\"|\"));\n}\n\n/**\n * Derive the request execution key.\n *\n * This key is used internally by AXIS to prove that:\n * 1. The request arrived with a valid capsule\n * 2. The capsule was bound to this specific intent/audience/subject\n * 3. AXIS possessed the local secret at derivation time\n *\n * The key itself is NEVER exposed — only its hash appears in witness records.\n */\nexport function deriveRequestExecutionKey(\n input: CceDerivationInput,\n): Uint8Array {\n const ikm = hexToBytes(input.axisLocalSecret);\n const salt = buildSalt(\n input.capsule.capsule_id,\n input.capsule.capsule_nonce,\n input.requestNonce,\n );\n const info = buildInfo(CCE_DERIVATION.REQUEST, input.capsule);\n\n return hkdf(sha256, ikm, salt, info, CCE_AES_KEY_BYTES);\n}\n\n/**\n * Derive the response execution key.\n * Uses a different context prefix and includes the response nonce,\n * ensuring request and response keys are always distinct.\n */\nexport function deriveResponseExecutionKey(\n input: CceDerivationInput & { responseNonce: string },\n): Uint8Array {\n const ikm = hexToBytes(input.axisLocalSecret);\n\n // Response salt uses a different construction\n const encoder = new TextEncoder();\n const saltData = encoder.encode(\n input.capsule.capsule_id +\n \"|\" +\n input.capsule.capsule_nonce +\n \"|\" +\n input.requestNonce +\n \"|\" +\n input.responseNonce,\n );\n const salt = sha256(saltData);\n\n const info = buildInfo(\n CCE_DERIVATION.RESPONSE,\n input.capsule,\n input.responseNonce,\n );\n\n return hkdf(sha256, ikm, salt, info, CCE_AES_KEY_BYTES);\n}\n\n/**\n * Derive the witness binding key.\n * Used to create tamper-evident witness records.\n */\nexport function deriveWitnessKey(input: CceDerivationInput): Uint8Array {\n const ikm = hexToBytes(input.axisLocalSecret);\n const salt = buildSalt(\n input.capsule.capsule_id,\n input.capsule.capsule_nonce,\n input.requestNonce,\n );\n const info = buildInfo(CCE_DERIVATION.WITNESS, input.capsule);\n\n return hkdf(sha256, ikm, salt, info, CCE_AES_KEY_BYTES);\n}\n\n/**\n * Build a complete execution context from capsule claims and derivation.\n * The execution key is derived but only its hash is stored.\n */\nexport function buildExecutionContext(\n input: CceDerivationInput,\n requestId: string,\n): CceExecutionContext {\n const executionKey = deriveRequestExecutionKey(input);\n const keyHash = bytesToHex(sha256(executionKey));\n\n // Clear the raw key from memory (best effort)\n executionKey.fill(0);\n\n return {\n execution_key_hash: keyHash,\n request_id: requestId,\n capsule_id: input.capsule.capsule_id,\n sub: input.capsule.sub,\n kid: input.capsule.kid,\n intent: input.capsule.intent,\n aud: input.capsule.aud,\n tps_from: input.capsule.tps_from,\n tps_to: input.capsule.tps_to,\n policy_hash: input.capsule.policy_hash,\n derived_at: Math.floor(Date.now() / 1000),\n valid: true,\n };\n}\n\n/**\n * Generate a cryptographically secure nonce for CCE requests/responses.\n */\nexport function generateCceNonce(): string {\n const bytes = new Uint8Array(CCE_NONCE_BYTES);\n crypto.getRandomValues(bytes);\n return bytesToHex(bytes);\n}\n","import { bytesToHex } from \"@noble/hashes/utils.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n/**\n * CCE Crypto Primitives\n *\n * AES-256-GCM encryption/decryption and X25519 key exchange\n * for the Capsule-Carried Encryption protocol.\n *\n * Uses Node.js native crypto for AES-GCM (performant and FIPS-capable).\n */\nimport { createCipheriv, createDecipheriv, randomBytes } from \"crypto\";\n\nimport { CCE_AES_KEY_BYTES, CCE_IV_BYTES, CCE_TAG_BYTES } from \"./cce.types\";\n\n// ============================================================================\n// AES-256-GCM\n// ============================================================================\n\n/**\n * Encrypt plaintext with AES-256-GCM.\n */\nexport function aesGcmEncrypt(\n key: Uint8Array,\n plaintext: Uint8Array,\n aad?: Uint8Array,\n): { iv: Uint8Array; ciphertext: Uint8Array; tag: Uint8Array } {\n if (key.length !== CCE_AES_KEY_BYTES) {\n throw new Error(`AES key must be ${CCE_AES_KEY_BYTES} bytes`);\n }\n\n const iv = randomBytes(CCE_IV_BYTES);\n const cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n\n if (aad) {\n cipher.setAAD(aad);\n }\n\n const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n const tag = cipher.getAuthTag();\n\n return {\n iv: new Uint8Array(iv),\n ciphertext: new Uint8Array(encrypted),\n tag: new Uint8Array(tag),\n };\n}\n\n/**\n * Decrypt ciphertext with AES-256-GCM.\n * Returns null if AEAD tag verification fails.\n */\nexport function aesGcmDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n aad?: Uint8Array,\n): Uint8Array | null {\n if (key.length !== CCE_AES_KEY_BYTES) {\n throw new Error(`AES key must be ${CCE_AES_KEY_BYTES} bytes`);\n }\n if (iv.length !== CCE_IV_BYTES) {\n throw new Error(`IV must be ${CCE_IV_BYTES} bytes`);\n }\n if (tag.length !== CCE_TAG_BYTES) {\n throw new Error(`Tag must be ${CCE_TAG_BYTES} bytes`);\n }\n\n try {\n const decipher = createDecipheriv(\"aes-256-gcm\", key, iv);\n decipher.setAuthTag(tag);\n\n if (aad) {\n decipher.setAAD(aad);\n }\n\n const decrypted = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]);\n return new Uint8Array(decrypted);\n } catch {\n // AEAD tag mismatch or other decryption failure\n return null;\n }\n}\n\n/**\n * Generate an ephemeral AES-256 key.\n */\nexport function generateAesKey(): Uint8Array {\n return new Uint8Array(randomBytes(CCE_AES_KEY_BYTES));\n}\n\n/**\n * Generate a random IV for AES-GCM.\n */\nexport function generateIv(): Uint8Array {\n return new Uint8Array(randomBytes(CCE_IV_BYTES));\n}\n\n// ============================================================================\n// Base64url helpers\n// ============================================================================\n\nexport function base64UrlEncode(bytes: Uint8Array): string {\n return Buffer.from(bytes)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport function base64UrlDecode(input: string): Uint8Array {\n const base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = \"=\".repeat((4 - (base64.length % 4)) % 4);\n return new Uint8Array(Buffer.from(base64 + padding, \"base64\"));\n}\n\n// ============================================================================\n// Payload hashing (for witness records)\n// ============================================================================\n\n/**\n * Hash a payload for witness records (never store raw plaintext).\n */\nexport function hashPayload(payload: Uint8Array): string {\n return bytesToHex(sha256(payload));\n}\n\n// ============================================================================\n// Default AES-GCM Provider (for sensor injection)\n// ============================================================================\n\nimport type { CceAesGcmProvider } from \"./sensors/cce-payload-decryption.sensor\";\n\n/**\n * Node.js native AES-GCM provider.\n */\nexport const nodeAesGcmProvider: CceAesGcmProvider = {\n async decrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n aad?: Uint8Array,\n ): Promise<Uint8Array | null> {\n return aesGcmDecrypt(key, iv, ciphertext, tag, aad);\n },\n};\n","import { bytesToHex } from \"@noble/hashes/utils.js\";\n/**\n * CCE Response Encryption Service\n *\n * Encrypts AXIS response payloads back to the client.\n *\n * v1 model:\n * - Generate ephemeral AES-256 key\n * - Encrypt response body with AES-GCM\n * - Encrypt AES key with client public key\n * - Sign response envelope with AXIS private key\n */\nimport { randomBytes } from \"crypto\";\n\nimport { aesGcmEncrypt, base64UrlEncode, generateAesKey, hashPayload } from \"./cce-crypto\";\nimport { CCE_NONCE_BYTES, CCE_PROTOCOL_VERSION, type CceAlgorithmDescriptor, type CceCapsuleClaims, type CceEncryptedKey, type CceEncryptedPayload, type CceRequestEnvelope, type CceResponseEnvelope, type CceResponseStatus, type CceSignature } from \"./cce.types\";\n\n/**\n * Client public key encryptor — wraps AES key with client's public key.\n */\nexport interface CceClientKeyEncryptor {\n wrapKey(\n aesKey: Uint8Array,\n clientKid: string,\n clientPublicKeyHex: string,\n ): Promise<CceEncryptedKey>;\n}\n\n/**\n * AXIS signing provider — signs response envelopes.\n */\nexport interface CceAxisSigner {\n sign(payload: Uint8Array): Promise<CceSignature>;\n}\n\n/**\n * Options for building a CCE response.\n */\nexport interface CceResponseOptions {\n /** Original request envelope */\n request: CceRequestEnvelope;\n /** Verified capsule claims */\n capsule: CceCapsuleClaims;\n /** Response status */\n status: CceResponseStatus;\n /** Response body (plaintext) */\n body: Uint8Array;\n /** Client public key (hex) for response encryption */\n clientPublicKeyHex: string;\n /** Witness reference */\n witnessRef?: string;\n}\n\n/**\n * Build and encrypt a CCE response envelope.\n */\nexport async function buildCceResponse(\n options: CceResponseOptions,\n clientKeyEncryptor: CceClientKeyEncryptor,\n axisSigner: CceAxisSigner,\n): Promise<{ envelope: CceResponseEnvelope; responsePayloadHash: string }> {\n const { request, capsule, status, body, clientPublicKeyHex, witnessRef } =\n options;\n\n // Generate response nonce\n const responseNonce = bytesToHex(\n new Uint8Array(randomBytes(CCE_NONCE_BYTES)),\n );\n\n // Generate response ID\n const responseId = generateResponseId();\n\n // Generate ephemeral AES key for response\n const aesKey = generateAesKey();\n\n // Build AAD for response (binds ciphertext to response context)\n const aad = buildResponseAad(\n request.request_id,\n responseId,\n request.correlation_id,\n capsule.capsule_id,\n responseNonce,\n );\n\n // Encrypt response body\n const { iv, ciphertext, tag } = aesGcmEncrypt(aesKey, body, aad);\n\n // Wrap AES key with client public key\n const encryptedKey = await clientKeyEncryptor.wrapKey(\n aesKey,\n request.client_kid,\n clientPublicKeyHex,\n );\n\n // Clear the raw AES key\n aesKey.fill(0);\n\n const encryptedPayload: CceEncryptedPayload = {\n alg: \"AES-256-GCM\",\n iv: base64UrlEncode(iv),\n ciphertext: base64UrlEncode(ciphertext),\n tag: base64UrlEncode(tag),\n };\n\n const algorithms: CceAlgorithmDescriptor = {\n kem: encryptedKey.alg,\n enc: \"AES-256-GCM\",\n kdf: \"HKDF-SHA256\",\n sig: \"EdDSA\",\n };\n\n // Build unsigned response\n const unsignedResponse: Omit<CceResponseEnvelope, \"axis_sig\"> = {\n ver: CCE_PROTOCOL_VERSION,\n response_id: responseId,\n request_id: request.request_id,\n correlation_id: request.correlation_id,\n capsule_id: capsule.capsule_id,\n encrypted_key: encryptedKey,\n encrypted_payload: encryptedPayload,\n response_nonce: responseNonce,\n algorithms,\n status,\n ...(witnessRef ? { witness_ref: witnessRef } : {}),\n };\n\n // Sign the response\n const signPayload = new TextEncoder().encode(canonicalize(unsignedResponse));\n const axisSig = await axisSigner.sign(signPayload);\n\n const envelope: CceResponseEnvelope = {\n ...unsignedResponse,\n axis_sig: axisSig,\n };\n\n return {\n envelope,\n responsePayloadHash: hashPayload(body),\n };\n}\n\n/**\n * Build a plaintext (unencrypted) error response for cases where\n * encryption is impossible (e.g., before capsule verification).\n */\nexport function buildCceErrorResponse(\n requestId: string,\n correlationId: string,\n status: CceResponseStatus,\n errorCode: string,\n message: string,\n): {\n ver: string;\n request_id: string;\n correlation_id: string;\n status: CceResponseStatus;\n error: { code: string; message: string };\n} {\n return {\n ver: CCE_PROTOCOL_VERSION,\n request_id: requestId,\n correlation_id: correlationId,\n status,\n error: { code: errorCode, message },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction generateResponseId(): string {\n const bytes = randomBytes(16);\n return \"resp_\" + bytesToHex(new Uint8Array(bytes)).slice(0, 24);\n}\n\nfunction buildResponseAad(\n requestId: string,\n responseId: string,\n correlationId: string,\n capsuleId: string,\n responseNonce: string,\n): Uint8Array {\n const parts = [\n requestId,\n responseId,\n correlationId,\n capsuleId,\n responseNonce,\n ];\n return new TextEncoder().encode(parts.join(\"|\"));\n}\n\nfunction canonicalize(obj: unknown): string {\n if (Array.isArray(obj)) {\n return \"[\" + obj.map(canonicalize).join(\",\") + \"]\";\n }\n if (obj !== null && typeof obj === \"object\") {\n const sorted = Object.keys(obj as object)\n .sort()\n .map(\n (k) =>\n JSON.stringify(k) +\n \":\" +\n canonicalize((obj as Record<string, unknown>)[k]),\n );\n return \"{\" + sorted.join(\",\") + \"}\";\n }\n return JSON.stringify(obj);\n}\n","import { bytesToHex } from \"@noble/hashes/utils.js\";\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n/**\n * CCE Witness Observer\n *\n * Records tamper-evident witness logs for every CCE request/response lifecycle.\n *\n * Redaction rules:\n * - Never store raw plaintext payloads (only hashes)\n * - Never store raw encryption keys\n * - Store verification outcomes, not raw crypto material\n */\nimport { randomBytes } from \"crypto\";\n\nimport { hashPayload } from \"./cce-crypto\";\nimport { CCE_DERIVATION, type CceCapsuleClaims, type CceRequestEnvelope, type CceResponseStatus, type CceWitnessRecord } from \"./cce.types\";\n\n/**\n * Witness store interface — implementations persist witness records.\n */\nexport interface CceWitnessStore {\n record(witness: CceWitnessRecord): Promise<void>;\n}\n\n/**\n * In-memory witness store for development/testing.\n */\nexport class InMemoryCceWitnessStore implements CceWitnessStore {\n readonly records: CceWitnessRecord[] = [];\n\n async record(witness: CceWitnessRecord): Promise<void> {\n this.records.push(witness);\n }\n\n getByRequestId(requestId: string): CceWitnessRecord | undefined {\n return this.records.find((w) => w.request_id === requestId);\n }\n\n getByCapsuleId(capsuleId: string): CceWitnessRecord[] {\n return this.records.filter((w) => w.capsule_id === capsuleId);\n }\n}\n\n/**\n * Verification state accumulated during sensor chain execution.\n */\nexport interface CceVerificationState {\n clientSigVerified: boolean;\n capsuleSigVerified: boolean;\n tpsValid: boolean;\n audienceMatch: boolean;\n intentMatch: boolean;\n replayClean: boolean;\n nonceUnique: boolean;\n decryptionOk: boolean;\n}\n\n/**\n * Build a witness record from verification state and execution result.\n */\nexport function buildWitnessRecord(\n envelope: CceRequestEnvelope,\n capsule: CceCapsuleClaims,\n verification: CceVerificationState,\n execution: {\n status: CceResponseStatus;\n handlerDurationMs: number;\n effect?: string;\n },\n options: {\n axisLocalSecret: string;\n requestPayload?: Uint8Array;\n responsePayload?: Uint8Array;\n responseEncrypted: boolean;\n },\n): CceWitnessRecord {\n // Generate witness ID\n const witnessId = generateWitnessId(envelope.request_id, capsule.capsule_id);\n\n // Compute execution context hash using HKDF witness derivation\n const executionContextHash = computeExecutionContextHash(\n options.axisLocalSecret,\n capsule,\n envelope.request_nonce,\n );\n\n return {\n witness_id: witnessId,\n request_id: envelope.request_id,\n capsule_id: capsule.capsule_id,\n sub: capsule.sub,\n intent: capsule.intent,\n aud: capsule.aud,\n tps_from: capsule.tps_from,\n tps_to: capsule.tps_to,\n timestamp: Math.floor(Date.now() / 1000),\n verification: {\n client_sig: verification.clientSigVerified,\n capsule_sig: verification.capsuleSigVerified,\n tps_valid: verification.tpsValid,\n audience_match: verification.audienceMatch,\n intent_match: verification.intentMatch,\n replay_clean: verification.replayClean,\n nonce_unique: verification.nonceUnique,\n decryption_ok: verification.decryptionOk,\n },\n execution: {\n status: execution.status,\n handler_duration_ms: execution.handlerDurationMs,\n ...(execution.effect ? { effect: execution.effect } : {}),\n },\n response_encrypted: options.responseEncrypted,\n execution_context_hash: executionContextHash,\n ...(options.requestPayload\n ? { request_payload_hash: hashPayload(options.requestPayload) }\n : {}),\n ...(options.responsePayload\n ? { response_payload_hash: hashPayload(options.responsePayload) }\n : {}),\n };\n}\n\n/**\n * Extract verification state from sensor chain metadata.\n */\nexport function extractVerificationState(\n metadata: Record<string, any>,\n): CceVerificationState {\n return {\n clientSigVerified: metadata.cceClientSigVerified === true,\n capsuleSigVerified: metadata.cceCapsuleVerified === true,\n tpsValid: metadata.cceTpsValid === true,\n audienceMatch: metadata.cceBindingVerified === true,\n intentMatch: metadata.cceBindingVerified === true,\n replayClean: metadata.cceReplayClean === true,\n nonceUnique: metadata.cceReplayClean === true,\n decryptionOk: metadata.cceDecryptionOk === true,\n };\n}\n\n// ============================================================================\n// Internal\n// ============================================================================\n\nfunction generateWitnessId(requestId: string, capsuleId: string): string {\n const input = `witness:${requestId}:${capsuleId}:${Date.now()}`;\n const hash = sha256(new TextEncoder().encode(input));\n return \"wit_\" + bytesToHex(hash).slice(0, 24);\n}\n\nfunction computeExecutionContextHash(\n axisLocalSecret: string,\n capsule: CceCapsuleClaims,\n requestNonce: string,\n): string {\n const encoder = new TextEncoder();\n\n // Use HKDF to derive witness key\n const ikm = hexToBytes(axisLocalSecret);\n const salt = sha256(\n encoder.encode(\n capsule.capsule_id + \"|\" + capsule.capsule_nonce + \"|\" + requestNonce,\n ),\n );\n const info = encoder.encode(\n [\n CCE_DERIVATION.WITNESS,\n capsule.sub,\n capsule.kid,\n capsule.intent,\n capsule.aud,\n String(capsule.tps_from),\n String(capsule.tps_to),\n capsule.policy_hash ?? \"\",\n capsule.ver,\n ].join(\"|\"),\n );\n\n const witnessKey = hkdf(sha256, ikm, salt, info, 32);\n const hash = bytesToHex(sha256(witnessKey));\n\n // Clear sensitive material\n witnessKey.fill(0);\n\n return hash;\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n","import type { AxisObservedContext } from \"../types/axis-frame.types\";\n\n/**\n * Sensor Phase Metadata\n *\n * Metadata describing which phase(s) a sensor executes in.\n * Used for validation and optimization.\n *\n * @interface SensorPhaseMetadata\n */\nexport interface SensorPhaseMetadata {\n /** Execution phase: pre-decode (middleware) or post-decode (controller) */\n phase: \"PRE_DECODE\" | \"POST_DECODE\";\n\n /** Other sensors that must run before this one */\n dependencies?: string[];\n\n /** Whether this sensor can perform async I/O */\n asyncOk?: boolean;\n\n /** Whether this sensor can use cryptographic operations */\n cryptoOk?: boolean;\n\n /** Human-readable description of sensor purpose */\n description?: string;\n}\n\n/**\n * AXIS Sensor Interface\n *\n * Core interface for all security sensors in the AXIS pipeline.\n */\nexport interface AxisSensor {\n readonly name: string;\n readonly order?: number; // Lower runs first\n /** Execution phase hint */\n phase?: SensorPhaseMetadata | \"PRE_DECODE\" | \"POST_DECODE\";\n supports?(input: SensorInput): Promise<SensorDecision>;\n run(input: SensorInput): Promise<SensorDecision>;\n}\n\n// Optional lifecycle hook for frameworks that support module initialization.\nexport interface AxisSensorInit extends AxisSensor {\n onModuleInit?(): void | Promise<void>;\n}\n\n/**\n * Sensors that run before frame decoding/deserialization.\n * They should be fast, avoid I/O, and fail fast on malformed traffic.\n */\nexport interface AxisPreSensor extends AxisSensor {\n phase: \"PRE_DECODE\";\n}\n\n/**\n * Sensors that run after a frame is fully decoded and parsed.\n * They may use full context (intent, actor, proofs) and can perform I/O.\n */\nexport interface AxisPostSensor extends AxisSensor {\n phase: \"POST_DECODE\";\n}\n\n/**\n * Sensor Input\n *\n * Represents the structured data passed to a security sensor for evaluation.\n * Depending on the execution phase, different fields may be populated.\n *\n * **Flow:**\n * - **Phase 1 (Pre-decode):** `rawBytes`, `ip`, `path`, and `peek` are typically available.\n * - **Phase 2/3 (Post-decode):** `intent`, `contentLength`, and `metadata` are populated after frame parsing.\n *\n * @interface SensorInput\n */\nexport interface SensorInput {\n /** The full raw binary frame from the wire (if available) */\n rawBytes?: Buffer | Uint8Array;\n\n /** The AXIS intent string extracted from the frame header (e.g., 'system.info') */\n intent?: string;\n\n /** IPv4/IPv6 address of the edge client */\n ip?: string;\n\n /** The HTTP or transport path being accessed */\n path?: string;\n\n /** Total size of the frame body in bytes */\n contentLength?: number;\n\n /** A small slice of the beginning of the body for early pattern matching */\n peek?: Uint8Array;\n\n /** Geolocation country code (if resolved by upstream middleware) */\n country?: string;\n\n /** Client identifier from the transport layer (e.g., Capsule ID or Socket ID) */\n clientId?: string;\n\n /** Whether the request is coming via a WebSocket connection */\n isWs?: boolean;\n\n /** Extensible metadata for cross-sensor communication */\n metadata?: Record<string, any>;\n\n /** Actor ID from frame or request */\n actorId?: string;\n\n /** Operation code */\n opcode?: string;\n\n /** Audience field */\n aud?: string;\n\n /** Observed context from frame parsing */\n observed?: AxisObservedContext;\n\n /** Parsed frame body */\n frameBody?: any;\n\n /** Device identifier */\n deviceId?: string;\n\n /** Session identifier */\n sessionId?: string;\n\n /** Parsed packet data */\n packet?: Record<string, any>;\n\n /** Dynamic field access for sensor-specific data */\n [key: string]: any;\n}\n\nexport enum Decision {\n ALLOW = \"ALLOW\",\n DENY = \"DENY\",\n THROTTLE = \"THROTTLE\",\n FLAG = \"FLAG\",\n}\n/**\n * Sensor Decision\n *\n * Represents the outcome of an individual sensor's evaluation.\n * Supports two formats for backward compatibility:\n *\n * 1. Modern format (preferred): Uses decision/allow/riskScore/reasons\n * 2. Legacy format: Uses action/code/reason (deprecated, will be removed)\n */\nexport type SensorDecision =\n // Modern format (preferred)\n | {\n /** Final decision outcome (optional for backward compatibility) */\n decision?: Decision;\n /** Whether the request may continue immediately */\n allow: boolean;\n /** Risk score from 0–100 (0 = safe, 100 = blocked) */\n riskScore: number;\n /** Human & machine traceable reasons */\n reasons: string[];\n /** Machine-readable error or control code */\n code?: string;\n /** Throttle hint (only relevant for THROTTLE) */\n retryAfterMs?: number;\n /** Optional delta applied to rolling risk/anomaly state */\n scoreDelta?: number;\n /** Extra signals for audit, observability, forensics */\n tags?: Record<string, any>;\n /** Optional capsule / verification metadata */\n meta?: any;\n /** Optional constraint tightening instructions */\n tighten?: {\n expSecondsMax?: number;\n constraintsPatch?: Record<string, any>;\n };\n }\n // Legacy action-based format (deprecated)\n | { action: \"ALLOW\"; meta?: any }\n | {\n action: \"DENY\";\n code: string;\n reason?: string;\n retryAfterMs?: number;\n meta?: any;\n }\n | { action: \"THROTTLE\"; retryAfterMs: number; meta?: any }\n | { action: \"FLAG\"; scoreDelta: number; reasons: string[]; meta?: any };\n\nexport type SensorMinifiedDecision = {\n allow: boolean;\n riskScore: number;\n reasons: string[];\n tags?: Record<string, any>;\n meta?: any;\n tighten?: { expSecondsMax?: number; constraintsPatch?: Record<string, any> };\n /** Legacy fields for compatibility */\n retryAfterMs?: number;\n};\n\n/**\n * Helper to normalize SensorDecision (handles both legacy and modern formats)\n */\nexport function normalizeSensorDecision(\n sensorDecision: SensorDecision,\n): SensorMinifiedDecision {\n // Check if it's a legacy action-based format\n if (\"action\" in sensorDecision) {\n // Convert legacy format to modern\n switch (sensorDecision.action) {\n case \"ALLOW\":\n return {\n allow: true,\n riskScore: 0,\n reasons: [],\n meta: sensorDecision.meta,\n };\n case \"DENY\":\n return {\n allow: false,\n riskScore: 100,\n reasons: [sensorDecision.code, sensorDecision.reason].filter(\n Boolean,\n ) as string[],\n meta: sensorDecision.meta,\n retryAfterMs: sensorDecision.retryAfterMs,\n };\n case \"THROTTLE\":\n return {\n allow: false,\n riskScore: 50,\n reasons: [\"RATE_LIMIT\"],\n retryAfterMs: sensorDecision.retryAfterMs,\n meta: sensorDecision.meta,\n };\n case \"FLAG\":\n return {\n allow: true,\n riskScore: sensorDecision.scoreDelta,\n reasons: sensorDecision.reasons,\n meta: sensorDecision.meta,\n };\n }\n }\n\n // Modern format - already has the required fields\n return {\n allow: sensorDecision.allow,\n riskScore: sensorDecision.riskScore,\n reasons: sensorDecision.reasons,\n tags: sensorDecision.tags,\n meta: sensorDecision.meta,\n tighten: sensorDecision.tighten,\n retryAfterMs: sensorDecision.retryAfterMs,\n };\n}\n\n/**\n * Helper factories for creating SensorDecision objects\n */\nexport const SensorDecisions = {\n allow(meta?: any, tags?: Record<string, any>): SensorDecision {\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n tags,\n meta,\n };\n },\n\n deny(code: string, reason?: string, meta?: any): SensorDecision {\n return {\n decision: Decision.DENY,\n allow: false,\n riskScore: 100,\n code,\n reasons: [code, reason].filter(Boolean) as string[],\n meta,\n };\n },\n\n throttle(retryAfterMs: number, meta?: any): SensorDecision {\n return {\n decision: Decision.THROTTLE,\n allow: false,\n riskScore: 50,\n retryAfterMs,\n code: \"RATE_LIMIT\",\n reasons: [\"RATE_LIMIT\"],\n meta,\n };\n },\n\n flag(scoreDelta: number, reasons: string[], meta?: any): SensorDecision {\n return {\n decision: Decision.FLAG,\n allow: true,\n riskScore: scoreDelta,\n scoreDelta,\n reasons,\n meta,\n };\n },\n};\n","import { buildExecutionContext, type CceDerivationInput } from \"./cce-derivation.service\";\nimport { buildCceErrorResponse, buildCceResponse, type CceAxisSigner, type CceClientKeyEncryptor } from \"./cce-response.service\";\nimport { buildWitnessRecord, type CceWitnessStore, extractVerificationState } from \"./cce-witness.observer\";\nimport type { AxisSensor, SensorDecision, SensorInput } from \"../sensor/axis-sensor\";\nimport { normalizeSensorDecision } from \"../sensor/axis-sensor\";\n/**\n * CCE Pipeline Orchestrator\n *\n * Orchestrates the full CCE request/response lifecycle within AXIS:\n *\n * Request path:\n * 1. Parse envelope\n * 2. Run sensor chain (7 CCE sensors in order)\n * 3. Derive execution context\n * 4. Route to handler\n * 5. Execute handler\n *\n * Response path:\n * 6. Encrypt response\n * 7. Sign response\n * 8. Record witness\n * 9. Return response\n *\n * This orchestrator can be integrated into IntentRouter or used standalone.\n */\nimport { CCE_ERROR, CCE_PROTOCOL_VERSION, type CceCapsuleClaims, CceError, type CceExecutionContext, type CceRequestEnvelope, type CceResponseEnvelope, type CceResponseStatus } from \"./cce.types\";\n\n/**\n * CCE handler function — receives decrypted payload and execution context.\n */\nexport type CceHandler = (\n payload: Uint8Array,\n context: CceHandlerContext,\n) => Promise<CceHandlerResult>;\n\nexport interface CceHandlerContext {\n /** Verified capsule claims */\n capsule: CceCapsuleClaims;\n /** Derived execution context */\n executionContext: CceExecutionContext;\n /** Original request envelope */\n envelope: CceRequestEnvelope;\n /** Client's verified public key */\n clientPublicKeyHex: string;\n /** Request intent */\n intent: string;\n /** Actor identity */\n sub: string;\n}\n\nexport interface CceHandlerResult {\n status: CceResponseStatus;\n body: Uint8Array;\n effect?: string;\n}\n\nexport interface CcePolicyContext {\n envelope: CceRequestEnvelope;\n capsule: CceCapsuleClaims;\n executionContext: CceExecutionContext;\n decryptedPayload: Uint8Array;\n clientPublicKeyHex: string;\n}\n\nexport interface CcePolicyDecision {\n allow: boolean;\n code?: string;\n message?: string;\n}\n\nexport interface CcePolicyEvaluator {\n evaluate(context: CcePolicyContext): Promise<CcePolicyDecision>;\n}\n\n/**\n * CCE Pipeline Configuration\n */\nexport interface CcePipelineConfig {\n /** AXIS local secret for key derivation (hex) */\n axisLocalSecret: string;\n /** AXIS audience identifier */\n axisAudience: string;\n /** CCE sensors (will be sorted by order) */\n sensors: AxisSensor[];\n /** Intent → handler mapping */\n handlers: Map<string, CceHandler>;\n /** Witness store */\n witnessStore: CceWitnessStore;\n /** Client key encryptor (for response encryption) */\n clientKeyEncryptor: CceClientKeyEncryptor;\n /** AXIS response signer */\n axisSigner: CceAxisSigner;\n /** Optional policy/law evaluator run after decryption and before handler execution */\n policyEvaluator?: CcePolicyEvaluator;\n}\n\n/**\n * Result of CCE pipeline execution.\n */\nexport type CcePipelineResult =\n | { ok: true; response: CceResponseEnvelope; witnessId: string }\n | {\n ok: false;\n error: { code: string; message: string };\n status: CceResponseStatus;\n };\n\n/**\n * Execute the full CCE pipeline.\n */\nexport async function executeCcePipeline(\n envelope: CceRequestEnvelope,\n config: CcePipelineConfig,\n): Promise<CcePipelineResult> {\n const startTime = Date.now();\n\n // Validate protocol version\n if (envelope.ver !== CCE_PROTOCOL_VERSION) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.UNSUPPORTED_VERSION,\n message: `Unsupported version: ${envelope.ver}`,\n },\n status: \"ERROR\",\n };\n }\n\n // Build sensor input\n const sensorInput: SensorInput = {\n intent: envelope.capsule.intent,\n metadata: {\n cce: true,\n cceEnvelope: envelope,\n contentType: \"application/axis-cce\",\n },\n };\n\n // Run sensor chain in order\n const sortedSensors = [...config.sensors].sort(\n (a, b) => (a.order ?? 999) - (b.order ?? 999),\n );\n\n for (const sensor of sortedSensors) {\n if (sensor.supports && !sensor.supports(sensorInput)) {\n continue;\n }\n\n let decision: SensorDecision;\n try {\n decision = await sensor.run(sensorInput);\n } catch (err) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.DECRYPTION_FAILED,\n message: `Sensor ${sensor.name} failed`,\n },\n status: \"ERROR\",\n };\n }\n\n const normalized = normalizeSensorDecision(decision);\n if (!normalized.allow) {\n const code =\n normalized.reasons[0]?.split(\":\")[0] ?? CCE_ERROR.DECRYPTION_FAILED;\n return {\n ok: false,\n error: { code, message: normalized.reasons.join(\"; \") },\n status: \"DENIED\",\n };\n }\n }\n\n // Extract verified state\n const capsule = sensorInput.metadata?.cceCapsule as CceCapsuleClaims;\n const decryptedPayload = sensorInput.metadata\n ?.cceDecryptedPayload as Uint8Array;\n const clientKey = sensorInput.metadata?.cceClientKey as {\n publicKeyHex: string;\n };\n\n if (!capsule || !decryptedPayload || !clientKey) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.DECRYPTION_FAILED,\n message: \"Sensor chain did not produce required outputs\",\n },\n status: \"ERROR\",\n };\n }\n\n // Derive execution context\n const derivationInput: CceDerivationInput = {\n axisLocalSecret: config.axisLocalSecret,\n capsule,\n requestNonce: envelope.request_nonce,\n };\n const executionContext = buildExecutionContext(\n derivationInput,\n envelope.request_id,\n );\n\n if (config.policyEvaluator) {\n try {\n const policyDecision = await config.policyEvaluator.evaluate({\n envelope,\n capsule,\n executionContext,\n decryptedPayload,\n clientPublicKeyHex: clientKey.publicKeyHex,\n });\n if (!policyDecision.allow) {\n const verification = extractVerificationState(sensorInput.metadata ?? {});\n const witness = buildWitnessRecord(\n envelope,\n capsule,\n verification,\n {\n status: \"DENIED\",\n handlerDurationMs: 0,\n effect: \"policy_denied\",\n },\n {\n axisLocalSecret: config.axisLocalSecret,\n requestPayload: decryptedPayload,\n responseEncrypted: false,\n },\n );\n await config.witnessStore.record(witness);\n\n return {\n ok: false,\n error: {\n code: policyDecision.code ?? CCE_ERROR.POLICY_DENIED,\n message:\n policyDecision.message ?? \"Request denied by policy evaluator\",\n },\n status: \"DENIED\",\n };\n }\n } catch (err) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.POLICY_DENIED,\n message: \"Policy evaluator failed\",\n },\n status: \"ERROR\",\n };\n }\n }\n\n // Route to handler\n const handler = config.handlers.get(capsule.intent);\n if (!handler) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.HANDLER_NOT_FOUND,\n message: `No handler for intent: ${capsule.intent}`,\n },\n status: \"ERROR\",\n };\n }\n\n // Execute handler\n const handlerContext: CceHandlerContext = {\n capsule,\n executionContext,\n envelope,\n clientPublicKeyHex: clientKey.publicKeyHex,\n intent: capsule.intent,\n sub: capsule.sub,\n };\n\n let result: CceHandlerResult;\n const handlerStart = Date.now();\n try {\n result = await handler(decryptedPayload, handlerContext);\n } catch (err) {\n const handlerDuration = Date.now() - handlerStart;\n\n // Record failure witness\n const verification = extractVerificationState(sensorInput.metadata ?? {});\n const witness = buildWitnessRecord(\n envelope,\n capsule,\n verification,\n { status: \"FAILED\", handlerDurationMs: handlerDuration },\n {\n axisLocalSecret: config.axisLocalSecret,\n requestPayload: decryptedPayload,\n responseEncrypted: false,\n },\n );\n await config.witnessStore.record(witness);\n\n return {\n ok: false,\n error: {\n code: CCE_ERROR.HANDLER_EXECUTION_FAILED,\n message: \"Handler execution failed\",\n },\n status: \"FAILED\",\n };\n }\n const handlerDuration = Date.now() - handlerStart;\n\n // Encrypt response\n let responseEnvelope: CceResponseEnvelope;\n let responsePayloadHash: string;\n\n try {\n const responseResult = await buildCceResponse(\n {\n request: envelope,\n capsule,\n status: result.status,\n body: result.body,\n clientPublicKeyHex: clientKey.publicKeyHex,\n },\n config.clientKeyEncryptor,\n config.axisSigner,\n );\n responseEnvelope = responseResult.envelope;\n responsePayloadHash = responseResult.responsePayloadHash;\n } catch (err) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.RESPONSE_ENCRYPTION_FAILED,\n message: \"Response encryption failed\",\n },\n status: \"ERROR\",\n };\n }\n\n // Record witness\n const verification = extractVerificationState(sensorInput.metadata ?? {});\n const witness = buildWitnessRecord(\n envelope,\n capsule,\n verification,\n {\n status: result.status,\n handlerDurationMs: handlerDuration,\n effect: result.effect,\n },\n {\n axisLocalSecret: config.axisLocalSecret,\n requestPayload: decryptedPayload,\n responsePayload: result.body,\n responseEncrypted: true,\n },\n );\n await config.witnessStore.record(witness);\n\n return {\n ok: true,\n response: responseEnvelope,\n witnessId: witness.witness_id,\n };\n}\n","/**\n * CCE Envelope Validation Sensor\n *\n * Band: WIRE (order: 5)\n * Phase: PRE_DECODE\n *\n * Step 1-2 from CCE verification order:\n * 1. Validate envelope schema\n * 2. Check protocol version\n *\n * Fast-fails malformed CCE requests before any crypto work.\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n CCE_NONCE_BYTES,\n CCE_PROTOCOL_VERSION,\n type CceRequestEnvelope,\n} from \"../cce.types\";\n\nconst REQUIRED_FIELDS: (keyof CceRequestEnvelope)[] = [\n \"ver\",\n \"request_id\",\n \"correlation_id\",\n \"client_kid\",\n \"capsule\",\n \"encrypted_key\",\n \"encrypted_payload\",\n \"request_nonce\",\n \"client_sig\",\n \"content_type\",\n \"algorithms\",\n];\n\nexport class CceEnvelopeValidationSensor implements AxisSensor {\n readonly name = \"cce.envelope.validation\";\n readonly order = 5;\n readonly phase = \"PRE_DECODE\" as const;\n\n async supports(input: SensorInput): Promise<SensorDecision> {\n // Only process CCE envelopes (detected by metadata flag or content type)\n return input.metadata?.cce === true ||\n input.metadata?.contentType === \"application/axis-cce\"\n ? { action: \"ALLOW\" }\n : {\n action: \"DENY\",\n code: \"SENSOR_NOT_APPLICABLE\",\n reason: \"Not a CCE envelope\",\n };\n }\n\n async run(input: SensorInput): Promise<SensorDecision> {\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.INVALID_ENVELOPE],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Check required fields\n for (const field of REQUIRED_FIELDS) {\n if (envelope[field] === undefined || envelope[field] === null) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.INVALID_ENVELOPE}: missing ${field}`],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n }\n\n // Check protocol version\n if (envelope.ver !== CCE_PROTOCOL_VERSION) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.UNSUPPORTED_VERSION}: ${envelope.ver}`],\n code: CCE_ERROR.UNSUPPORTED_VERSION,\n };\n }\n\n // Validate request nonce format (must be hex, correct length)\n if (!/^[0-9a-f]+$/i.test(envelope.request_nonce)) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INVALID_ENVELOPE}: invalid request_nonce format`,\n ],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n if (envelope.request_nonce.length !== CCE_NONCE_BYTES * 2) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.INVALID_ENVELOPE}: request_nonce wrong length`],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Validate capsule has required fields\n const capsule = envelope.capsule;\n if (\n !capsule.capsule_id ||\n !capsule.ver ||\n !capsule.sub ||\n !capsule.kid ||\n !capsule.intent ||\n !capsule.aud ||\n !capsule.issuer_sig\n ) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.MISSING_CAPSULE}: incomplete capsule claims`],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Validate encrypted key structure\n if (!envelope.encrypted_key.ciphertext || !envelope.encrypted_key.alg) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.MISSING_ENCRYPTED_KEY}: incomplete encrypted_key`,\n ],\n code: CCE_ERROR.MISSING_ENCRYPTED_KEY,\n };\n }\n\n // Pass: store parsed envelope in metadata for downstream sensors\n input.metadata = input.metadata ?? {};\n input.metadata.cceEnvelopeValid = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Client Signature Verification Sensor\n *\n * Band: IDENTITY (order: 45)\n * Phase: POST_DECODE\n *\n * Steps 4-5 from CCE verification order:\n * 4. Resolve client public key\n * 5. Verify client signature over canonical envelope\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport { CCE_ERROR, type CceRequestEnvelope } from \"../cce.types\";\n\n/**\n * Key resolver interface — implementations can look up Redis, DB, or in-memory.\n */\nexport interface CceClientKeyResolver {\n resolve(kid: string): Promise<{ publicKeyHex: string; alg: string } | null>;\n}\n\n/**\n * Signature verifier interface — pluggable for Ed25519, ES256, etc.\n */\nexport interface CceSignatureVerifier {\n verify(\n message: Uint8Array,\n signatureHex: string,\n publicKeyHex: string,\n alg: string,\n ): Promise<boolean>;\n}\n\nexport class CceClientSignatureSensor implements AxisSensor {\n readonly name = \"cce.client.signature\";\n readonly order = 45;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n private readonly keyResolver: CceClientKeyResolver,\n private readonly signatureVerifier: CceSignatureVerifier,\n ) {}\n\n async supports(input: SensorInput): Promise<SensorDecision> {\n return input.metadata?.cceEnvelopeValid === true\n ? { action: \"ALLOW\" }\n : {\n action: \"DENY\",\n code: \"SENSOR_NOT_APPLICABLE\",\n reason: \"CCE envelope not validated\",\n };\n }\n\n async run(input: SensorInput): Promise<SensorDecision> {\n const envelope = input.metadata?.cceEnvelope as CceRequestEnvelope;\n if (!envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.INVALID_ENVELOPE],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Step 4: Resolve client public key\n const keyRecord = await this.keyResolver.resolve(envelope.client_kid);\n if (!keyRecord) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.CLIENT_KEY_NOT_FOUND}: kid=${envelope.client_kid}`,\n ],\n code: CCE_ERROR.CLIENT_KEY_NOT_FOUND,\n };\n }\n\n // Step 5: Verify client signature\n // Canonical signing payload: everything except client_sig\n const { client_sig, ...signable } = envelope;\n const canonical = canonicalize(signable);\n const message = new TextEncoder().encode(canonical);\n\n const valid = await this.signatureVerifier.verify(\n message,\n client_sig.value,\n keyRecord.publicKeyHex,\n keyRecord.alg,\n );\n\n if (!valid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.CLIENT_SIG_INVALID],\n code: CCE_ERROR.CLIENT_SIG_INVALID,\n };\n }\n\n // Store resolved key for downstream\n input.metadata = input.metadata ?? {};\n input.metadata.cceClientKey = keyRecord;\n input.metadata.cceClientSigVerified = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n meta: { kid: envelope.client_kid },\n };\n }\n}\n\n// Canonical JSON for deterministic signature verification\nfunction canonicalize(obj: unknown): string {\n if (Array.isArray(obj)) {\n return \"[\" + obj.map(canonicalize).join(\",\") + \"]\";\n }\n if (obj !== null && typeof obj === \"object\") {\n const sorted = Object.keys(obj as object)\n .sort()\n .map(\n (k) =>\n JSON.stringify(k) +\n \":\" +\n canonicalize((obj as Record<string, unknown>)[k]),\n );\n return \"{\" + sorted.join(\",\") + \"}\";\n }\n return JSON.stringify(obj);\n}\n","/**\n * CCE Capsule Verification Sensor\n *\n * Band: IDENTITY (order: 50)\n * Phase: POST_DECODE\n *\n * Step 6 from CCE verification order:\n * 6. Parse capsule, verify TickAuth signature, verify integrity\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n CCE_PROTOCOL_VERSION,\n type CceCapsuleClaims,\n} from \"../cce.types\";\n\n/**\n * TickAuth issuer key resolver.\n */\nexport interface CceIssuerKeyResolver {\n resolve(kid: string): Promise<{ publicKeyHex: string } | null>;\n}\n\n/**\n * Signature verifier for capsule issuer signatures.\n */\nexport interface CceCapsuleSignatureVerifier {\n verify(\n claims: Omit<CceCapsuleClaims, \"issuer_sig\">,\n signature: { alg: string; kid: string; value: string },\n publicKeyHex: string,\n ): Promise<boolean>;\n}\n\nexport class CceCapsuleVerificationSensor implements AxisSensor {\n readonly name = \"cce.capsule.verification\";\n readonly order = 50;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n private readonly issuerKeyResolver: CceIssuerKeyResolver,\n private readonly capsuleVerifier: CceCapsuleSignatureVerifier,\n ) {}\n\n async supports(input: SensorInput): Promise<SensorDecision> {\n return input.metadata?.cceEnvelopeValid === true\n ? { action: \"ALLOW\" }\n : {\n action: \"DENY\",\n code: CCE_ERROR.CAPSULE_NOT_VERIFIED,\n reason: \"CCE capsule not verified\",\n };\n }\n\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceEnvelope?.capsule as\n | CceCapsuleClaims\n | undefined;\n\n if (!capsule) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Verify protocol version\n if (capsule.ver !== CCE_PROTOCOL_VERSION) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.CAPSULE_SIG_INVALID}: wrong version ${capsule.ver}`,\n ],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Verify content integrity (ID matches hash)\n const { capsule_id, issuer_sig, ...claimsBody } = capsule;\n const expectedId = computeCceCapsuleId(claimsBody);\n if (capsule_id !== expectedId) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_SIG_INVALID}: content hash mismatch`],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Resolve TickAuth issuer key\n const issuerKey = await this.issuerKeyResolver.resolve(\n capsule.issuer_sig.kid,\n );\n if (!issuerKey) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_SIG_INVALID}: issuer key not found`],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Verify issuer signature\n const { issuer_sig: sig, ...rest } = capsule;\n const sigValid = await this.capsuleVerifier.verify(\n rest,\n sig,\n issuerKey.publicKeyHex,\n );\n if (!sigValid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.CAPSULE_SIG_INVALID],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Check expiry\n const nowSeconds = Math.floor(Date.now() / 1000);\n if (capsule.exp < nowSeconds) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_EXPIRED}: exp=${capsule.exp}`],\n code: CCE_ERROR.CAPSULE_EXPIRED,\n };\n }\n\n // Check not-yet-valid (iat in future with tolerance)\n if (capsule.iat > nowSeconds + 5) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_NOT_YET_VALID}: iat=${capsule.iat}`],\n code: CCE_ERROR.CAPSULE_NOT_YET_VALID,\n };\n }\n\n // Store verified capsule for downstream\n input.metadata = input.metadata ?? {};\n input.metadata.cceCapsuleVerified = true;\n input.metadata.cceCapsule = capsule;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n meta: { capsule_id: capsule.capsule_id },\n };\n }\n}\n\n// Content-addressed capsule ID computation\nimport { blake3 } from \"@noble/hashes/blake3.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\n\nfunction canonicalize(obj: unknown): string {\n if (Array.isArray(obj)) {\n return \"[\" + obj.map(canonicalize).join(\",\") + \"]\";\n }\n if (obj !== null && typeof obj === \"object\") {\n const sorted = Object.keys(obj as object)\n .sort()\n .map(\n (k) =>\n JSON.stringify(k) +\n \":\" +\n canonicalize((obj as Record<string, unknown>)[k]),\n );\n return \"{\" + sorted.join(\",\") + \"}\";\n }\n return JSON.stringify(obj);\n}\n\nfunction computeCceCapsuleId(claims: Record<string, unknown>): string {\n const canonical = canonicalize(claims);\n const hash = blake3(new TextEncoder().encode(canonical));\n return \"cce_b3_\" + bytesToHex(hash).slice(0, 32);\n}\n","/**\n * CCE TPS Window Validation Sensor\n *\n * Band: POLICY (order: 92)\n * Phase: POST_DECODE\n *\n * Step 7 from CCE verification order:\n * 7. Verify TPS window is current (not expired, not future)\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport { CCE_ERROR, type CceCapsuleClaims } from \"../cce.types\";\n\n/** Maximum acceptable clock skew in milliseconds */\nconst DEFAULT_SKEW_MS = 5000;\n\nexport class CceTpsWindowSensor implements AxisSensor {\n readonly name = \"cce.tps.window\";\n readonly order = 92;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(private readonly skewMs: number = DEFAULT_SKEW_MS) {}\n\n async supports(input: SensorInput): Promise<SensorDecision> {\n return input.metadata?.cceCapsuleVerified === true\n ? { action: \"ALLOW\" }\n : {\n action: \"DENY\",\n code: \"SENSOR_NOT_APPLICABLE\",\n reason: \"CCE capsule not verified\",\n };\n }\n\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceCapsule as CceCapsuleClaims | undefined;\n if (!capsule) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n const nowMs = Date.now();\n\n // Check if TPS window has expired (with skew tolerance)\n if (nowMs > capsule.tps_to + this.skewMs) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.TPS_WINDOW_EXPIRED}: window ended at ${capsule.tps_to}, now=${nowMs}`,\n ],\n code: CCE_ERROR.TPS_WINDOW_EXPIRED,\n };\n }\n\n // Check if TPS window is in the future (with skew tolerance)\n if (nowMs < capsule.tps_from - this.skewMs) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.TPS_WINDOW_FUTURE}: window starts at ${capsule.tps_from}, now=${nowMs}`,\n ],\n code: CCE_ERROR.TPS_WINDOW_FUTURE,\n };\n }\n\n input.metadata = input.metadata ?? {};\n input.metadata.cceTpsValid = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Audience & Intent Binding Sensor\n *\n * Band: POLICY (order: 95)\n * Phase: POST_DECODE\n *\n * Steps 8-9 from CCE verification order:\n * 8. Verify audience matches this AXIS instance\n * 9. Verify intent matches the capsule-bound intent\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n type CceCapsuleClaims,\n type CceRequestEnvelope,\n} from \"../cce.types\";\n\nexport class CceAudienceIntentBindingSensor implements AxisSensor {\n readonly name = \"cce.audience.intent.binding\";\n readonly order = 95;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n /** This AXIS instance's audience identifier */\n private readonly axisAudience: string,\n ) {}\n\n async supports(input: SensorInput): Promise<SensorDecision> {\n return input.metadata?.cceCapsuleVerified === true\n ? { action: \"ALLOW\" }\n : {\n action: \"DENY\",\n code: CCE_ERROR.CAPSULE_NOT_VERIFIED,\n reason: \"CCE capsule not verified\",\n };\n }\n\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceCapsule as CceCapsuleClaims | undefined;\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!capsule || !envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Step 8: Verify audience\n if (capsule.aud !== this.axisAudience) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.AUDIENCE_MISMATCH}: capsule.aud=${capsule.aud}, expected=${this.axisAudience}`,\n ],\n code: CCE_ERROR.AUDIENCE_MISMATCH,\n };\n }\n\n // Step 9: Verify intent\n // The intent in the envelope should match the capsule-bound intent\n const requestIntent = input.intent ?? input.metadata?.cceRequestIntent;\n if (requestIntent && capsule.intent !== requestIntent) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INTENT_MISMATCH}: capsule.intent=${capsule.intent}, request=${requestIntent}`,\n ],\n code: CCE_ERROR.INTENT_MISMATCH,\n };\n }\n\n // Verify client_kid in envelope matches capsule kid\n if (envelope.client_kid !== capsule.kid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INTENT_MISMATCH}: envelope.kid=${envelope.client_kid}, capsule.kid=${capsule.kid}`,\n ],\n code: CCE_ERROR.INTENT_MISMATCH,\n };\n }\n\n input.metadata = input.metadata ?? {};\n input.metadata.cceBindingVerified = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Replay Protection Sensor\n *\n * Band: POLICY (order: 98)\n * Phase: POST_DECODE\n *\n * Steps 10-11 from CCE verification order:\n * 10. Verify capsule not replayed (capsule_id not consumed if SINGLE_USE)\n * 11. Verify request nonce uniqueness\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n type CceCapsuleClaims,\n type CceRequestEnvelope,\n} from \"../cce.types\";\n\n/**\n * Replay store interface — implementations can use Redis, in-memory, etc.\n * Must support O(1) lookups for performance in the hot path.\n */\nexport interface CceReplayStore {\n /**\n * Check and mark a nonce/id as used.\n * @returns true if this is the first time (valid), false if replay\n */\n checkAndMark(key: string, ttlMs: number): Promise<boolean>;\n\n /** Check if a capsule has been consumed */\n isCapsuleConsumed(capsuleId: string): Promise<boolean>;\n\n /** Mark a capsule as consumed */\n markCapsuleConsumed(capsuleId: string, ttlMs: number): Promise<void>;\n\n /** Check if a capsule has been revoked */\n isCapsuleRevoked(capsuleId: string): Promise<boolean>;\n}\n\n/**\n * In-memory replay store for development/testing.\n */\nexport class InMemoryCceReplayStore implements CceReplayStore {\n private nonces = new Map<string, number>();\n private consumed = new Set<string>();\n private revoked = new Set<string>();\n\n async checkAndMark(key: string, ttlMs: number): Promise<boolean> {\n this.cleanup();\n if (this.nonces.has(key)) return false;\n this.nonces.set(key, Date.now() + ttlMs);\n return true;\n }\n\n async isCapsuleConsumed(capsuleId: string): Promise<boolean> {\n return this.consumed.has(capsuleId);\n }\n\n async markCapsuleConsumed(capsuleId: string, _ttlMs: number): Promise<void> {\n this.consumed.add(capsuleId);\n }\n\n async isCapsuleRevoked(capsuleId: string): Promise<boolean> {\n return this.revoked.has(capsuleId);\n }\n\n /** Revoke a capsule (for testing/admin) */\n revoke(capsuleId: string): void {\n this.revoked.add(capsuleId);\n }\n\n private cleanup(): void {\n const now = Date.now();\n for (const [key, expiresAt] of this.nonces) {\n if (expiresAt < now) this.nonces.delete(key);\n }\n }\n}\n\nexport class CceReplayProtectionSensor implements AxisSensor {\n readonly name = \"cce.replay.protection\";\n readonly order = 98;\n readonly phase = \"POST_DECODE\" as const;\n\n /** Default nonce TTL: 5 minutes */\n private readonly nonceTtlMs: number;\n\n constructor(\n private readonly replayStore: CceReplayStore,\n options?: { nonceTtlMs?: number },\n ) {\n this.nonceTtlMs = options?.nonceTtlMs ?? 5 * 60 * 1000;\n }\n\n async supports(input: SensorInput): Promise<SensorDecision> {\n return input.metadata?.cceCapsuleVerified === true\n ? { action: \"ALLOW\" }\n : {\n action: \"DENY\",\n code: \"SENSOR_NOT_APPLICABLE\",\n reason: \"CCE capsule not verified\",\n };\n }\n\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceCapsule as CceCapsuleClaims | undefined;\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!capsule || !envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Check capsule revocation\n const revoked = await this.replayStore.isCapsuleRevoked(capsule.capsule_id);\n if (revoked) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_REVOKED}: ${capsule.capsule_id}`],\n code: CCE_ERROR.CAPSULE_REVOKED,\n };\n }\n\n // Check capsule consumption (SINGLE_USE mode)\n if (capsule.mode === \"SINGLE_USE\") {\n const consumed = await this.replayStore.isCapsuleConsumed(\n capsule.capsule_id,\n );\n if (consumed) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_CONSUMED}: ${capsule.capsule_id}`],\n code: CCE_ERROR.CAPSULE_CONSUMED,\n };\n }\n }\n\n // Check request nonce uniqueness\n // Namespace: sub + aud + intent to prevent cross-context collision\n const nonceKey = `cce:nonce:${capsule.sub}:${capsule.aud}:${capsule.intent}:${envelope.request_nonce}`;\n const nonceValid = await this.replayStore.checkAndMark(\n nonceKey,\n this.nonceTtlMs,\n );\n if (!nonceValid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.NONCE_REUSED}: ${envelope.request_nonce.slice(0, 16)}...`,\n ],\n code: CCE_ERROR.NONCE_REUSED,\n };\n }\n\n // Mark capsule consumed for SINGLE_USE\n if (capsule.mode === \"SINGLE_USE\") {\n const capsuleTtl = (capsule.exp - capsule.iat) * 1000 + 60_000; // TTL + 1 min buffer\n await this.replayStore.markCapsuleConsumed(\n capsule.capsule_id,\n capsuleTtl,\n );\n }\n\n input.metadata = input.metadata ?? {};\n input.metadata.cceReplayClean = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Payload Decryption Sensor\n *\n * Band: CONTENT (order: 145)\n * Phase: POST_DECODE\n *\n * Steps 12-13 from CCE verification order:\n * 12. Decrypt transport key → decrypt payload\n * 13. Validate plaintext payload schema\n *\n * This sensor performs the actual cryptographic decryption of the request payload.\n * It unwraps the AES transport key using the AXIS private key, then decrypts\n * the payload with AES-256-GCM.\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport { CCE_ERROR, type CceRequestEnvelope } from \"../cce.types\";\n\n/**\n * AXIS private key provider for decrypting the transport key.\n */\nexport interface CceAxisKeyProvider {\n /**\n * Decrypt a transport key using AXIS private key.\n * Supports X25519 (ECDH) and RSA-OAEP key unwrapping.\n */\n unwrapKey(\n encryptedKeyB64: string,\n algorithm: string,\n axisKid: string,\n ephemeralPkB64?: string,\n ): Promise<Uint8Array | null>;\n}\n\n/**\n * AES-GCM decryption provider.\n */\nexport interface CceAesGcmProvider {\n /**\n * Decrypt ciphertext with AES-256-GCM.\n * @returns plaintext bytes, or null if AEAD tag verification failed\n */\n decrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n aad?: Uint8Array,\n ): Promise<Uint8Array | null>;\n}\n\nexport interface CcePayloadValidatorResult {\n ok: boolean;\n intent?: string;\n code?: string;\n reason?: string;\n}\n\n/**\n * Optional decrypted payload validator.\n * Use this hook to enforce intent-specific schema checks before handler execution.\n */\nexport interface CcePayloadValidator {\n validate(\n plaintext: Uint8Array,\n envelope: CceRequestEnvelope,\n ): Promise<CcePayloadValidatorResult>;\n}\n\nexport class CcePayloadDecryptionSensor implements AxisSensor {\n readonly name = \"cce.payload.decryption\";\n readonly order = 145;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n private readonly keyProvider: CceAxisKeyProvider,\n private readonly aesProvider: CceAesGcmProvider,\n private readonly maxPayloadBytes: number = 64 * 1024,\n private readonly payloadValidator?: CcePayloadValidator,\n ) {}\n\n async supports(input: SensorInput): Promise<SensorDecision> {\n return input.metadata?.cceEnvelopeValid === true &&\n input.metadata?.cceClientSigVerified === true &&\n input.metadata?.cceCapsuleVerified === true &&\n input.metadata?.cceReplayClean === true\n ? { action: \"ALLOW\" }\n : {\n action: \"DENY\",\n code: \"SENSOR_NOT_APPLICABLE\",\n reason: \"CCE preconditions not met\",\n };\n }\n\n async run(input: SensorInput): Promise<SensorDecision> {\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.INVALID_ENVELOPE],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Step 11 (from spec): Decrypt transport key\n let aesKey: Uint8Array | null;\n try {\n aesKey = await this.keyProvider.unwrapKey(\n envelope.encrypted_key.ciphertext,\n envelope.encrypted_key.alg,\n envelope.encrypted_key.axis_kid,\n envelope.encrypted_key.ephemeral_pk,\n );\n } catch {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.KEY_UNWRAP_FAILED],\n code: CCE_ERROR.KEY_UNWRAP_FAILED,\n };\n }\n\n if (!aesKey) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.KEY_UNWRAP_FAILED],\n code: CCE_ERROR.KEY_UNWRAP_FAILED,\n };\n }\n\n // Step 12: Decrypt payload with AES-GCM\n let iv: Uint8Array;\n let ciphertext: Uint8Array;\n let tag: Uint8Array;\n\n try {\n iv = base64UrlDecode(envelope.encrypted_payload.iv);\n ciphertext = base64UrlDecode(envelope.encrypted_payload.ciphertext);\n tag = base64UrlDecode(envelope.encrypted_payload.tag);\n } catch {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.DECRYPTION_FAILED}: invalid base64url encoding`],\n code: CCE_ERROR.DECRYPTION_FAILED,\n };\n }\n\n // Check payload size before decryption\n if (ciphertext.length > this.maxPayloadBytes) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.PAYLOAD_TOO_LARGE}: ${ciphertext.length} > ${this.maxPayloadBytes}`,\n ],\n code: CCE_ERROR.PAYLOAD_TOO_LARGE,\n };\n }\n\n // Build AAD from envelope metadata (binds ciphertext to context)\n const aad = buildAad(envelope);\n\n let plaintext: Uint8Array | null;\n try {\n plaintext = await this.aesProvider.decrypt(\n aesKey,\n iv,\n ciphertext,\n tag,\n aad,\n );\n } catch {\n plaintext = null;\n } finally {\n // Clear AES key from memory (best effort)\n aesKey.fill(0);\n }\n\n if (!plaintext) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.AEAD_TAG_MISMATCH],\n code: CCE_ERROR.AEAD_TAG_MISMATCH,\n };\n }\n\n const capsule = input.metadata?.cceCapsule as\n | { intent: string }\n | undefined;\n\n // Built-in JSON intent binding check.\n if (capsule && isJsonContentType(envelope.content_type)) {\n const parsed = tryParseJsonObject(plaintext);\n if (parsed && typeof parsed.intent === \"string\") {\n if (parsed.intent !== capsule.intent) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INTENT_SCHEMA_MISMATCH}: payload.intent=${parsed.intent}, capsule.intent=${capsule.intent}`,\n ],\n code: CCE_ERROR.INTENT_SCHEMA_MISMATCH,\n };\n }\n input.metadata = input.metadata ?? {};\n input.metadata.cceRequestIntent = parsed.intent;\n }\n }\n\n if (this.payloadValidator) {\n const verdict = await this.payloadValidator.validate(plaintext, envelope);\n if (!verdict.ok) {\n const code = verdict.code ?? CCE_ERROR.PAYLOAD_SCHEMA_INVALID;\n return {\n allow: false,\n riskScore: 100,\n reasons: [verdict.reason ?? code],\n code,\n };\n }\n\n if (verdict.intent) {\n input.metadata = input.metadata ?? {};\n input.metadata.cceRequestIntent = verdict.intent;\n }\n }\n\n // Store decrypted payload for handler\n input.metadata = input.metadata ?? {};\n input.metadata.cceDecryptedPayload = plaintext;\n input.metadata.cceDecryptionOk = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n\n/**\n * Build Additional Authenticated Data from envelope fields.\n * Binds the ciphertext to the request context and prevents\n * transplanting encrypted payloads between requests.\n */\nfunction buildAad(envelope: CceRequestEnvelope): Uint8Array {\n const parts = [\n envelope.ver,\n envelope.request_id,\n envelope.correlation_id,\n envelope.client_kid,\n envelope.capsule.capsule_id,\n envelope.capsule.intent,\n envelope.capsule.aud,\n envelope.request_nonce,\n ];\n return new TextEncoder().encode(parts.join(\"|\"));\n}\n\nfunction isJsonContentType(contentType: string | undefined): boolean {\n return (\n typeof contentType === \"string\" &&\n contentType.toLowerCase().includes(\"application/json\")\n );\n}\n\nfunction tryParseJsonObject(\n payload: Uint8Array,\n): Record<string, unknown> | null {\n try {\n const parsed = JSON.parse(new TextDecoder().decode(payload));\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/** Base64url decode */\nfunction base64UrlDecode(input: string): Uint8Array {\n const base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = \"=\".repeat((4 - (base64.length % 4)) % 4);\n return new Uint8Array(Buffer.from(base64 + padding, \"base64\"));\n}\n"],"mappings":"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","names":["bytesToHex","sha256","bytesToHex","sha256","bytesToHex","randomBytes","bytesToHex","randomBytes","bytesToHex","hkdf","sha256","sha256","bytesToHex","hexToBytes","hkdf","verification","witness","handlerDuration","canonicalize","bytesToHex","canonicalize","base64UrlDecode"]}
1
+ {"version":3,"sources":["../../src/cce/cce.types.ts","../../src/cce/cce-derivation.service.ts","../../src/cce/cce-crypto.ts","../../src/cce/cce-response.service.ts","../../src/cce/cce-witness.observer.ts","../../src/sensor/axis-sensor.ts","../../src/cce/cce-pipeline.ts","../../src/cce/sensors/cce-envelope-validation.sensor.ts","../../src/cce/sensors/cce-client-signature.sensor.ts","../../src/cce/sensors/cce-capsule-verification.sensor.ts","../../src/cce/sensors/cce-tps-window.sensor.ts","../../src/cce/sensors/cce-audience-intent-binding.sensor.ts","../../src/cce/sensors/cce-replay-protection.sensor.ts","../../src/cce/sensors/cce-payload-decryption.sensor.ts"],"sourcesContent":["/**\n * Capsule-Carried Encryption (CCE) Types — v1\n *\n * Defines the core types for the CCE protocol where:\n * - TickAuth issues capsules (authority)\n * - AXIS verifies capsules, decrypts payloads, derives execution context\n * - Payload confidentiality uses hybrid encryption (AES-GCM + AXIS public key)\n */\n\n// ============================================================================\n// CCE Protocol Constants\n// ============================================================================\n\nexport const CCE_PROTOCOL_VERSION = \"cce-v1\" as const;\n\n/** Derivation context prefixes for HKDF */\nexport const CCE_DERIVATION = {\n /** Request execution context */\n REQUEST: \"axis:cce:req:v1\",\n /** Response execution context */\n RESPONSE: \"axis:cce:resp:v1\",\n /** Witness binding context */\n WITNESS: \"axis:cce:witness:v1\",\n} as const;\n\n/** Supported encryption algorithms */\nexport type CceAlgorithm = \"AES-256-GCM\";\n/** Supported key encapsulation algorithms */\nexport type CceKemAlgorithm = \"X25519\" | \"RSA-OAEP-256\";\n/** Supported KDF algorithms */\nexport type CceKdfAlgorithm = \"HKDF-SHA256\";\n\nexport const CCE_AES_KEY_BYTES = 32; // 256-bit AES key\nexport const CCE_IV_BYTES = 12; // 96-bit GCM nonce\nexport const CCE_TAG_BYTES = 16; // 128-bit GCM auth tag\nexport const CCE_NONCE_BYTES = 32; // 256-bit request/response nonce\n\n// ============================================================================\n// CCE Capsule Claims (extends TickAuth capsule for AXIS binding)\n// ============================================================================\n\n/**\n * CCE-specific claims that extend the TickAuth capsule.\n * These claims bind the capsule to a specific AXIS audience and intent.\n */\nexport interface CceCapsuleClaims {\n /** Capsule identifier (content-addressed) */\n capsule_id: string;\n /** Protocol version */\n ver: typeof CCE_PROTOCOL_VERSION;\n /** Subject / actor identity */\n sub: string;\n /** Client key identifier */\n kid: string;\n /** Bound intent */\n intent: string;\n /** AXIS audience (service identity) */\n aud: string;\n /** TPS window start (Unix ms or TPS index) */\n tps_from: number;\n /** TPS window end (Unix ms or TPS index) */\n tps_to: number;\n /** Capsule nonce (hex, from challenge) */\n capsule_nonce: string;\n /** Reference to originating challenge */\n challenge_id: string;\n /** Content hash of the validated proof used to issue this capsule */\n proof_hash?: string;\n /** Policy hash (hex) — Digital Fabric Law binding */\n policy_hash?: string;\n /** Issued-at timestamp (Unix seconds) */\n iat: number;\n /** Expires-at timestamp (Unix seconds) */\n exp: number;\n /** Capsule usage mode */\n mode: \"SINGLE_USE\" | \"SESSION\";\n /** Scope capabilities */\n scope?: string[];\n /** Constraints */\n constraints?: CceConstraints;\n /** TickAuth issuer signature over claims */\n issuer_sig: CceSignature;\n}\n\nexport interface CceConstraints {\n max_payload_bytes?: number;\n ip_allow?: string[];\n device_allow?: string[];\n country_allow?: string[];\n}\n\nexport interface CceSignature {\n alg: \"EdDSA\" | \"ES256\";\n kid: string;\n value: string; // base64url or hex\n}\n\n// ============================================================================\n// CCE Request Envelope\n// ============================================================================\n\n/**\n * The encrypted request envelope sent from Client → AXIS.\n *\n * The client:\n * 1. Generates ephemeral AES-256 key\n * 2. Encrypts payload with AES-256-GCM\n * 3. Encrypts AES key with AXIS public key (X25519 or RSA-OAEP)\n * 4. Signs the envelope with client private key\n * 5. Attaches capsule\n */\nexport interface CceRequestEnvelope {\n /** Protocol version */\n ver: typeof CCE_PROTOCOL_VERSION;\n /** Unique request identifier */\n request_id: string;\n /** Correlation identifier (for request/response binding) */\n correlation_id: string;\n /** Client key identifier */\n client_kid: string;\n /** The capsule claims (signed by TickAuth) */\n capsule: CceCapsuleClaims;\n /** Encrypted transport key (AXIS public key encrypted) */\n encrypted_key: CceEncryptedKey;\n /** Encrypted payload */\n encrypted_payload: CceEncryptedPayload;\n /** Request nonce (hex, 32 bytes) */\n request_nonce: string;\n /** Client signature over canonical envelope */\n client_sig: CceSignature;\n /** Content type of the plaintext payload */\n content_type: string;\n /** Algorithm descriptors */\n algorithms: CceAlgorithmDescriptor;\n /** Additional authenticated data descriptor */\n aad_descriptor?: string;\n}\n\n/**\n * Encrypted symmetric key wrapped by AXIS public key.\n */\nexport interface CceEncryptedKey {\n /** Key encapsulation algorithm */\n alg: CceKemAlgorithm;\n /** AXIS key identifier used for encapsulation */\n axis_kid: string;\n /** Encrypted key bytes (base64url) */\n ciphertext: string;\n /** Ephemeral public key (for X25519 ECDH, base64url) */\n ephemeral_pk?: string;\n}\n\n/**\n * Encrypted payload with AEAD metadata.\n */\nexport interface CceEncryptedPayload {\n /** Encryption algorithm */\n alg: CceAlgorithm;\n /** Initialization vector / nonce (base64url, 12 bytes) */\n iv: string;\n /** Ciphertext (base64url) */\n ciphertext: string;\n /** Authentication tag (base64url, 16 bytes) */\n tag: string;\n}\n\n/**\n * Algorithm descriptor for the envelope.\n */\nexport interface CceAlgorithmDescriptor {\n /** Key encapsulation */\n kem: CceKemAlgorithm;\n /** Symmetric encryption */\n enc: CceAlgorithm;\n /** Key derivation (for execution context) */\n kdf: CceKdfAlgorithm;\n /** Signature algorithm */\n sig: \"EdDSA\" | \"ES256\";\n}\n\n// ============================================================================\n// CCE Response Envelope\n// ============================================================================\n\n/**\n * The encrypted response envelope sent from AXIS → Client.\n */\nexport interface CceResponseEnvelope {\n /** Protocol version */\n ver: typeof CCE_PROTOCOL_VERSION;\n /** Response identifier */\n response_id: string;\n /** Request identifier (binding) */\n request_id: string;\n /** Correlation identifier */\n correlation_id: string;\n /** Capsule identifier of the originating request */\n capsule_id: string;\n /** Encrypted transport key (Client public key encrypted) */\n encrypted_key: CceEncryptedKey;\n /** Encrypted response payload */\n encrypted_payload: CceEncryptedPayload;\n /** Response nonce (hex, 32 bytes) */\n response_nonce: string;\n /** AXIS signature over canonical response */\n axis_sig: CceSignature;\n /** Witness reference */\n witness_ref?: string;\n /** Algorithm descriptors */\n algorithms: CceAlgorithmDescriptor;\n /** Response status (plaintext, allowed on error) */\n status: CceResponseStatus;\n}\n\nexport type CceResponseStatus =\n | \"SUCCESS\"\n | \"DENIED\"\n | \"PARTIAL\"\n | \"FAILED\"\n | \"ERROR\";\n\n// ============================================================================\n// CCE Execution Context (derived inside AXIS)\n// ============================================================================\n\n/**\n * Execution context derived from capsule claims + AXIS local secret.\n * Proves that the request was not only decrypted but legally executable.\n */\nexport interface CceExecutionContext {\n /** Derived execution key (used for witness binding, never exposed) */\n execution_key_hash: string;\n /** Request identifier */\n request_id: string;\n /** Capsule identifier */\n capsule_id: string;\n /** Subject identity */\n sub: string;\n /** Client key identifier */\n kid: string;\n /** Intent */\n intent: string;\n /** Audience */\n aud: string;\n /** TPS window */\n tps_from: number;\n tps_to: number;\n /** Policy hash (if bound) */\n policy_hash?: string;\n /** Timestamp of context derivation */\n derived_at: number;\n /** Whether this context is valid */\n valid: boolean;\n}\n\n// ============================================================================\n// CCE Witness Record\n// ============================================================================\n\n/**\n * Witness record for the CCE request/response lifecycle.\n */\nexport interface CceWitnessRecord {\n /** Witness identifier */\n witness_id: string;\n /** Request identifier */\n request_id: string;\n /** Capsule identifier */\n capsule_id: string;\n /** Subject identity */\n sub: string;\n /** Intent */\n intent: string;\n /** Audience */\n aud: string;\n /** TPS window */\n tps_from: number;\n tps_to: number;\n /** Timestamp */\n timestamp: number;\n\n /** Verification results */\n verification: {\n client_sig: boolean;\n capsule_sig: boolean;\n tps_valid: boolean;\n audience_match: boolean;\n intent_match: boolean;\n replay_clean: boolean;\n nonce_unique: boolean;\n decryption_ok: boolean;\n };\n\n /** Handler execution result */\n execution: {\n status: CceResponseStatus;\n handler_duration_ms: number;\n effect?: string;\n };\n\n /** Response encryption result */\n response_encrypted: boolean;\n\n /** Execution context hash (proves legal execution) */\n execution_context_hash: string;\n\n /** Payload hash (redacted, never raw content) */\n request_payload_hash?: string;\n response_payload_hash?: string;\n}\n\n// ============================================================================\n// CCE Error Codes\n// ============================================================================\n\nexport const CCE_ERROR = {\n // Envelope errors\n INVALID_ENVELOPE: \"CCE_INVALID_ENVELOPE\",\n UNSUPPORTED_VERSION: \"CCE_UNSUPPORTED_VERSION\",\n MISSING_CAPSULE: \"CCE_MISSING_CAPSULE\",\n MISSING_ENCRYPTED_KEY: \"CCE_MISSING_ENCRYPTED_KEY\",\n\n // Signature errors\n CLIENT_SIG_INVALID: \"CCE_CLIENT_SIG_INVALID\",\n CLIENT_KEY_NOT_FOUND: \"CCE_CLIENT_KEY_NOT_FOUND\",\n\n // Capsule errors\n CAPSULE_SIG_INVALID: \"CCE_CAPSULE_SIG_INVALID\",\n CAPSULE_EXPIRED: \"CCE_CAPSULE_EXPIRED\",\n CAPSULE_NOT_YET_VALID: \"CCE_CAPSULE_NOT_YET_VALID\",\n CAPSULE_REVOKED: \"CCE_CAPSULE_REVOKED\",\n CAPSULE_CONSUMED: \"CCE_CAPSULE_CONSUMED\",\n CAPSULE_NOT_VERIFIED: \"CCE_CAPSULE_NOT_VERIFIED\",\n // Binding errors\n AUDIENCE_MISMATCH: \"CCE_AUDIENCE_MISMATCH\",\n INTENT_MISMATCH: \"CCE_INTENT_MISMATCH\",\n TPS_WINDOW_EXPIRED: \"CCE_TPS_WINDOW_EXPIRED\",\n TPS_WINDOW_FUTURE: \"CCE_TPS_WINDOW_FUTURE\",\n\n // Replay / nonce errors\n REPLAY_DETECTED: \"CCE_REPLAY_DETECTED\",\n NONCE_REUSED: \"CCE_NONCE_REUSED\",\n\n // Decryption errors\n DECRYPTION_FAILED: \"CCE_DECRYPTION_FAILED\",\n KEY_UNWRAP_FAILED: \"CCE_KEY_UNWRAP_FAILED\",\n AEAD_TAG_MISMATCH: \"CCE_AEAD_TAG_MISMATCH\",\n PAYLOAD_TOO_LARGE: \"CCE_PAYLOAD_TOO_LARGE\",\n\n // Schema / validation errors\n PAYLOAD_SCHEMA_INVALID: \"CCE_PAYLOAD_SCHEMA_INVALID\",\n INTENT_SCHEMA_MISMATCH: \"CCE_INTENT_SCHEMA_MISMATCH\",\n\n // Policy errors\n POLICY_DENIED: \"CCE_POLICY_DENIED\",\n CONSTRAINT_VIOLATED: \"CCE_CONSTRAINT_VIOLATED\",\n\n // Handler errors\n HANDLER_NOT_FOUND: \"CCE_HANDLER_NOT_FOUND\",\n HANDLER_EXECUTION_FAILED: \"CCE_HANDLER_EXECUTION_FAILED\",\n HANDLER_TIMEOUT: \"CCE_HANDLER_TIMEOUT\",\n\n // Response errors\n RESPONSE_ENCRYPTION_FAILED: \"CCE_RESPONSE_ENCRYPTION_FAILED\",\n} as const;\n\nexport type CceErrorCode = (typeof CCE_ERROR)[keyof typeof CCE_ERROR];\n\n/**\n * Structured CCE error.\n */\nexport class CceError extends Error {\n constructor(\n public readonly code: CceErrorCode,\n message: string,\n public readonly metadata?: Record<string, unknown>,\n ) {\n super(`[${code}] ${message}`);\n this.name = \"CceError\";\n }\n\n /** Whether this error is safe to expose to the client */\n get clientSafe(): boolean {\n // Never expose internal decryption/handler details\n const internal: CceErrorCode[] = [\n CCE_ERROR.DECRYPTION_FAILED,\n CCE_ERROR.KEY_UNWRAP_FAILED,\n CCE_ERROR.AEAD_TAG_MISMATCH,\n CCE_ERROR.HANDLER_EXECUTION_FAILED,\n CCE_ERROR.RESPONSE_ENCRYPTION_FAILED,\n ];\n return !internal.includes(this.code);\n }\n\n /** Get client-safe representation */\n toClientError(): { code: CceErrorCode; message: string } {\n if (this.clientSafe) {\n return { code: this.code, message: this.message };\n }\n return {\n code: CCE_ERROR.DECRYPTION_FAILED,\n message: \"Request processing failed\",\n };\n }\n}\n","import { bytesToHex, hexToBytes } from \"@noble/hashes/utils.js\";\n/**\n * CCE Key Derivation Service\n *\n * Implements HKDF-based key derivation for the Capsule-Carried Encryption protocol.\n * Keys are never placed in capsules — they are derived from:\n * - AXIS local secret (IKM)\n * - Capsule claims (salt + info)\n * - Request/response nonce (direction binding)\n * - Protocol version (upgrade protection)\n *\n * Uses @noble/hashes HKDF (RFC 5869) with SHA-256.\n */\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nimport { CCE_AES_KEY_BYTES, CCE_DERIVATION, CCE_NONCE_BYTES, type CceCapsuleClaims, type CceExecutionContext } from \"./cce.types\";\n\n/**\n * Input parameters for key derivation.\n */\nexport interface CceDerivationInput {\n /** AXIS local secret (hex, must be kept private) */\n axisLocalSecret: string;\n /** Capsule claims from the request */\n capsule: CceCapsuleClaims;\n /** Request nonce (hex) */\n requestNonce: string;\n /** Response nonce (hex, only for response derivation) */\n responseNonce?: string;\n}\n\n/**\n * Build the salt for HKDF from capsule + nonce.\n *\n * salt = SHA-256(capsule_id || capsule_nonce || request_nonce)\n */\nfunction buildSalt(\n capsuleId: string,\n capsuleNonce: string,\n requestNonce: string,\n): Uint8Array {\n const encoder = new TextEncoder();\n const data = encoder.encode(\n capsuleId + \"|\" + capsuleNonce + \"|\" + requestNonce,\n );\n return sha256(data);\n}\n\n/**\n * Build the info string for HKDF.\n * Binds the derived key to all authority dimensions.\n *\n * info = context_prefix | sub | kid | intent | aud | tps_from | tps_to | policy_hash | ver\n */\nfunction buildInfo(\n contextPrefix: string,\n capsule: CceCapsuleClaims,\n extraNonce?: string,\n): Uint8Array {\n const encoder = new TextEncoder();\n const parts = [\n contextPrefix,\n capsule.sub,\n capsule.kid,\n capsule.intent,\n capsule.aud,\n String(capsule.tps_from),\n String(capsule.tps_to),\n capsule.policy_hash ?? \"\",\n capsule.ver,\n ];\n if (extraNonce) {\n parts.push(extraNonce);\n }\n return encoder.encode(parts.join(\"|\"));\n}\n\n/**\n * Derive the request execution key.\n *\n * This key is used internally by AXIS to prove that:\n * 1. The request arrived with a valid capsule\n * 2. The capsule was bound to this specific intent/audience/subject\n * 3. AXIS possessed the local secret at derivation time\n *\n * The key itself is NEVER exposed — only its hash appears in witness records.\n */\nexport function deriveRequestExecutionKey(\n input: CceDerivationInput,\n): Uint8Array {\n const ikm = hexToBytes(input.axisLocalSecret);\n const salt = buildSalt(\n input.capsule.capsule_id,\n input.capsule.capsule_nonce,\n input.requestNonce,\n );\n const info = buildInfo(CCE_DERIVATION.REQUEST, input.capsule);\n\n return hkdf(sha256, ikm, salt, info, CCE_AES_KEY_BYTES);\n}\n\n/**\n * Derive the response execution key.\n * Uses a different context prefix and includes the response nonce,\n * ensuring request and response keys are always distinct.\n */\nexport function deriveResponseExecutionKey(\n input: CceDerivationInput & { responseNonce: string },\n): Uint8Array {\n const ikm = hexToBytes(input.axisLocalSecret);\n\n // Response salt uses a different construction\n const encoder = new TextEncoder();\n const saltData = encoder.encode(\n input.capsule.capsule_id +\n \"|\" +\n input.capsule.capsule_nonce +\n \"|\" +\n input.requestNonce +\n \"|\" +\n input.responseNonce,\n );\n const salt = sha256(saltData);\n\n const info = buildInfo(\n CCE_DERIVATION.RESPONSE,\n input.capsule,\n input.responseNonce,\n );\n\n return hkdf(sha256, ikm, salt, info, CCE_AES_KEY_BYTES);\n}\n\n/**\n * Derive the witness binding key.\n * Used to create tamper-evident witness records.\n */\nexport function deriveWitnessKey(input: CceDerivationInput): Uint8Array {\n const ikm = hexToBytes(input.axisLocalSecret);\n const salt = buildSalt(\n input.capsule.capsule_id,\n input.capsule.capsule_nonce,\n input.requestNonce,\n );\n const info = buildInfo(CCE_DERIVATION.WITNESS, input.capsule);\n\n return hkdf(sha256, ikm, salt, info, CCE_AES_KEY_BYTES);\n}\n\n/**\n * Build a complete execution context from capsule claims and derivation.\n * The execution key is derived but only its hash is stored.\n */\nexport function buildExecutionContext(\n input: CceDerivationInput,\n requestId: string,\n): CceExecutionContext {\n const executionKey = deriveRequestExecutionKey(input);\n const keyHash = bytesToHex(sha256(executionKey));\n\n // Clear the raw key from memory (best effort)\n executionKey.fill(0);\n\n return {\n execution_key_hash: keyHash,\n request_id: requestId,\n capsule_id: input.capsule.capsule_id,\n sub: input.capsule.sub,\n kid: input.capsule.kid,\n intent: input.capsule.intent,\n aud: input.capsule.aud,\n tps_from: input.capsule.tps_from,\n tps_to: input.capsule.tps_to,\n policy_hash: input.capsule.policy_hash,\n derived_at: Math.floor(Date.now() / 1000),\n valid: true,\n };\n}\n\n/**\n * Generate a cryptographically secure nonce for CCE requests/responses.\n */\nexport function generateCceNonce(): string {\n const bytes = new Uint8Array(CCE_NONCE_BYTES);\n crypto.getRandomValues(bytes);\n return bytesToHex(bytes);\n}\n","import { bytesToHex } from \"@noble/hashes/utils.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n/**\n * CCE Crypto Primitives\n *\n * AES-256-GCM encryption/decryption and X25519 key exchange\n * for the Capsule-Carried Encryption protocol.\n *\n * Uses Node.js native crypto for AES-GCM (performant and FIPS-capable).\n */\nimport { createCipheriv, createDecipheriv, randomBytes } from \"crypto\";\n\nimport { CCE_AES_KEY_BYTES, CCE_IV_BYTES, CCE_TAG_BYTES } from \"./cce.types\";\n\n// ============================================================================\n// AES-256-GCM\n// ============================================================================\n\n/**\n * Encrypt plaintext with AES-256-GCM.\n */\nexport function aesGcmEncrypt(\n key: Uint8Array,\n plaintext: Uint8Array,\n aad?: Uint8Array,\n): { iv: Uint8Array; ciphertext: Uint8Array; tag: Uint8Array } {\n if (key.length !== CCE_AES_KEY_BYTES) {\n throw new Error(`AES key must be ${CCE_AES_KEY_BYTES} bytes`);\n }\n\n const iv = randomBytes(CCE_IV_BYTES);\n const cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n\n if (aad) {\n cipher.setAAD(aad);\n }\n\n const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n const tag = cipher.getAuthTag();\n\n return {\n iv: new Uint8Array(iv),\n ciphertext: new Uint8Array(encrypted),\n tag: new Uint8Array(tag),\n };\n}\n\n/**\n * Decrypt ciphertext with AES-256-GCM.\n * Returns null if AEAD tag verification fails.\n */\nexport function aesGcmDecrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n aad?: Uint8Array,\n): Uint8Array | null {\n if (key.length !== CCE_AES_KEY_BYTES) {\n throw new Error(`AES key must be ${CCE_AES_KEY_BYTES} bytes`);\n }\n if (iv.length !== CCE_IV_BYTES) {\n throw new Error(`IV must be ${CCE_IV_BYTES} bytes`);\n }\n if (tag.length !== CCE_TAG_BYTES) {\n throw new Error(`Tag must be ${CCE_TAG_BYTES} bytes`);\n }\n\n try {\n const decipher = createDecipheriv(\"aes-256-gcm\", key, iv);\n decipher.setAuthTag(tag);\n\n if (aad) {\n decipher.setAAD(aad);\n }\n\n const decrypted = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]);\n return new Uint8Array(decrypted);\n } catch {\n // AEAD tag mismatch or other decryption failure\n return null;\n }\n}\n\n/**\n * Generate an ephemeral AES-256 key.\n */\nexport function generateAesKey(): Uint8Array {\n return new Uint8Array(randomBytes(CCE_AES_KEY_BYTES));\n}\n\n/**\n * Generate a random IV for AES-GCM.\n */\nexport function generateIv(): Uint8Array {\n return new Uint8Array(randomBytes(CCE_IV_BYTES));\n}\n\n// ============================================================================\n// Base64url helpers\n// ============================================================================\n\nexport function base64UrlEncode(bytes: Uint8Array): string {\n return Buffer.from(bytes)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport function base64UrlDecode(input: string): Uint8Array {\n const base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = \"=\".repeat((4 - (base64.length % 4)) % 4);\n return new Uint8Array(Buffer.from(base64 + padding, \"base64\"));\n}\n\n// ============================================================================\n// Payload hashing (for witness records)\n// ============================================================================\n\n/**\n * Hash a payload for witness records (never store raw plaintext).\n */\nexport function hashPayload(payload: Uint8Array): string {\n return bytesToHex(sha256(payload));\n}\n\n// ============================================================================\n// Default AES-GCM Provider (for sensor injection)\n// ============================================================================\n\nimport type { CceAesGcmProvider } from \"./sensors/cce-payload-decryption.sensor\";\n\n/**\n * Node.js native AES-GCM provider.\n */\nexport const nodeAesGcmProvider: CceAesGcmProvider = {\n async decrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n aad?: Uint8Array,\n ): Promise<Uint8Array | null> {\n return aesGcmDecrypt(key, iv, ciphertext, tag, aad);\n },\n};\n","import { bytesToHex } from \"@noble/hashes/utils.js\";\n/**\n * CCE Response Encryption Service\n *\n * Encrypts AXIS response payloads back to the client.\n *\n * v1 model:\n * - Generate ephemeral AES-256 key\n * - Encrypt response body with AES-GCM\n * - Encrypt AES key with client public key\n * - Sign response envelope with AXIS private key\n */\nimport { randomBytes } from \"crypto\";\n\nimport { aesGcmEncrypt, base64UrlEncode, generateAesKey, hashPayload } from \"./cce-crypto\";\nimport { CCE_NONCE_BYTES, CCE_PROTOCOL_VERSION, type CceAlgorithmDescriptor, type CceCapsuleClaims, type CceEncryptedKey, type CceEncryptedPayload, type CceRequestEnvelope, type CceResponseEnvelope, type CceResponseStatus, type CceSignature } from \"./cce.types\";\n\n/**\n * Client public key encryptor — wraps AES key with client's public key.\n */\nexport interface CceClientKeyEncryptor {\n wrapKey(\n aesKey: Uint8Array,\n clientKid: string,\n clientPublicKeyHex: string,\n ): Promise<CceEncryptedKey>;\n}\n\n/**\n * AXIS signing provider — signs response envelopes.\n */\nexport interface CceAxisSigner {\n sign(payload: Uint8Array): Promise<CceSignature>;\n}\n\n/**\n * Options for building a CCE response.\n */\nexport interface CceResponseOptions {\n /** Original request envelope */\n request: CceRequestEnvelope;\n /** Verified capsule claims */\n capsule: CceCapsuleClaims;\n /** Response status */\n status: CceResponseStatus;\n /** Response body (plaintext) */\n body: Uint8Array;\n /** Client public key (hex) for response encryption */\n clientPublicKeyHex: string;\n /** Witness reference */\n witnessRef?: string;\n}\n\n/**\n * Build and encrypt a CCE response envelope.\n */\nexport async function buildCceResponse(\n options: CceResponseOptions,\n clientKeyEncryptor: CceClientKeyEncryptor,\n axisSigner: CceAxisSigner,\n): Promise<{ envelope: CceResponseEnvelope; responsePayloadHash: string }> {\n const { request, capsule, status, body, clientPublicKeyHex, witnessRef } =\n options;\n\n // Generate response nonce\n const responseNonce = bytesToHex(\n new Uint8Array(randomBytes(CCE_NONCE_BYTES)),\n );\n\n // Generate response ID\n const responseId = generateResponseId();\n\n // Generate ephemeral AES key for response\n const aesKey = generateAesKey();\n\n // Build AAD for response (binds ciphertext to response context)\n const aad = buildResponseAad(\n request.request_id,\n responseId,\n request.correlation_id,\n capsule.capsule_id,\n responseNonce,\n );\n\n // Encrypt response body\n const { iv, ciphertext, tag } = aesGcmEncrypt(aesKey, body, aad);\n\n // Wrap AES key with client public key\n const encryptedKey = await clientKeyEncryptor.wrapKey(\n aesKey,\n request.client_kid,\n clientPublicKeyHex,\n );\n\n // Clear the raw AES key\n aesKey.fill(0);\n\n const encryptedPayload: CceEncryptedPayload = {\n alg: \"AES-256-GCM\",\n iv: base64UrlEncode(iv),\n ciphertext: base64UrlEncode(ciphertext),\n tag: base64UrlEncode(tag),\n };\n\n const algorithms: CceAlgorithmDescriptor = {\n kem: encryptedKey.alg,\n enc: \"AES-256-GCM\",\n kdf: \"HKDF-SHA256\",\n sig: \"EdDSA\",\n };\n\n // Build unsigned response\n const unsignedResponse: Omit<CceResponseEnvelope, \"axis_sig\"> = {\n ver: CCE_PROTOCOL_VERSION,\n response_id: responseId,\n request_id: request.request_id,\n correlation_id: request.correlation_id,\n capsule_id: capsule.capsule_id,\n encrypted_key: encryptedKey,\n encrypted_payload: encryptedPayload,\n response_nonce: responseNonce,\n algorithms,\n status,\n ...(witnessRef ? { witness_ref: witnessRef } : {}),\n };\n\n // Sign the response\n const signPayload = new TextEncoder().encode(canonicalize(unsignedResponse));\n const axisSig = await axisSigner.sign(signPayload);\n\n const envelope: CceResponseEnvelope = {\n ...unsignedResponse,\n axis_sig: axisSig,\n };\n\n return {\n envelope,\n responsePayloadHash: hashPayload(body),\n };\n}\n\n/**\n * Build a plaintext (unencrypted) error response for cases where\n * encryption is impossible (e.g., before capsule verification).\n */\nexport function buildCceErrorResponse(\n requestId: string,\n correlationId: string,\n status: CceResponseStatus,\n errorCode: string,\n message: string,\n): {\n ver: string;\n request_id: string;\n correlation_id: string;\n status: CceResponseStatus;\n error: { code: string; message: string };\n} {\n return {\n ver: CCE_PROTOCOL_VERSION,\n request_id: requestId,\n correlation_id: correlationId,\n status,\n error: { code: errorCode, message },\n };\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction generateResponseId(): string {\n const bytes = randomBytes(16);\n return \"resp_\" + bytesToHex(new Uint8Array(bytes)).slice(0, 24);\n}\n\nfunction buildResponseAad(\n requestId: string,\n responseId: string,\n correlationId: string,\n capsuleId: string,\n responseNonce: string,\n): Uint8Array {\n const parts = [\n requestId,\n responseId,\n correlationId,\n capsuleId,\n responseNonce,\n ];\n return new TextEncoder().encode(parts.join(\"|\"));\n}\n\nfunction canonicalize(obj: unknown): string {\n if (Array.isArray(obj)) {\n return \"[\" + obj.map(canonicalize).join(\",\") + \"]\";\n }\n if (obj !== null && typeof obj === \"object\") {\n const sorted = Object.keys(obj as object)\n .sort()\n .map(\n (k) =>\n JSON.stringify(k) +\n \":\" +\n canonicalize((obj as Record<string, unknown>)[k]),\n );\n return \"{\" + sorted.join(\",\") + \"}\";\n }\n return JSON.stringify(obj);\n}\n","import { bytesToHex } from \"@noble/hashes/utils.js\";\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n/**\n * CCE Witness Observer\n *\n * Records tamper-evident witness logs for every CCE request/response lifecycle.\n *\n * Redaction rules:\n * - Never store raw plaintext payloads (only hashes)\n * - Never store raw encryption keys\n * - Store verification outcomes, not raw crypto material\n */\nimport { randomBytes } from \"crypto\";\n\nimport { hashPayload } from \"./cce-crypto\";\nimport { CCE_DERIVATION, type CceCapsuleClaims, type CceRequestEnvelope, type CceResponseStatus, type CceWitnessRecord } from \"./cce.types\";\n\n/**\n * Witness store interface — implementations persist witness records.\n */\nexport interface CceWitnessStore {\n record(witness: CceWitnessRecord): Promise<void>;\n}\n\n/**\n * In-memory witness store for development/testing.\n */\nexport class InMemoryCceWitnessStore implements CceWitnessStore {\n readonly records: CceWitnessRecord[] = [];\n\n async record(witness: CceWitnessRecord): Promise<void> {\n this.records.push(witness);\n }\n\n getByRequestId(requestId: string): CceWitnessRecord | undefined {\n return this.records.find((w) => w.request_id === requestId);\n }\n\n getByCapsuleId(capsuleId: string): CceWitnessRecord[] {\n return this.records.filter((w) => w.capsule_id === capsuleId);\n }\n}\n\n/**\n * Verification state accumulated during sensor chain execution.\n */\nexport interface CceVerificationState {\n clientSigVerified: boolean;\n capsuleSigVerified: boolean;\n tpsValid: boolean;\n audienceMatch: boolean;\n intentMatch: boolean;\n replayClean: boolean;\n nonceUnique: boolean;\n decryptionOk: boolean;\n}\n\n/**\n * Build a witness record from verification state and execution result.\n */\nexport function buildWitnessRecord(\n envelope: CceRequestEnvelope,\n capsule: CceCapsuleClaims,\n verification: CceVerificationState,\n execution: {\n status: CceResponseStatus;\n handlerDurationMs: number;\n effect?: string;\n },\n options: {\n axisLocalSecret: string;\n requestPayload?: Uint8Array;\n responsePayload?: Uint8Array;\n responseEncrypted: boolean;\n },\n): CceWitnessRecord {\n // Generate witness ID\n const witnessId = generateWitnessId(envelope.request_id, capsule.capsule_id);\n\n // Compute execution context hash using HKDF witness derivation\n const executionContextHash = computeExecutionContextHash(\n options.axisLocalSecret,\n capsule,\n envelope.request_nonce,\n );\n\n return {\n witness_id: witnessId,\n request_id: envelope.request_id,\n capsule_id: capsule.capsule_id,\n sub: capsule.sub,\n intent: capsule.intent,\n aud: capsule.aud,\n tps_from: capsule.tps_from,\n tps_to: capsule.tps_to,\n timestamp: Math.floor(Date.now() / 1000),\n verification: {\n client_sig: verification.clientSigVerified,\n capsule_sig: verification.capsuleSigVerified,\n tps_valid: verification.tpsValid,\n audience_match: verification.audienceMatch,\n intent_match: verification.intentMatch,\n replay_clean: verification.replayClean,\n nonce_unique: verification.nonceUnique,\n decryption_ok: verification.decryptionOk,\n },\n execution: {\n status: execution.status,\n handler_duration_ms: execution.handlerDurationMs,\n ...(execution.effect ? { effect: execution.effect } : {}),\n },\n response_encrypted: options.responseEncrypted,\n execution_context_hash: executionContextHash,\n ...(options.requestPayload\n ? { request_payload_hash: hashPayload(options.requestPayload) }\n : {}),\n ...(options.responsePayload\n ? { response_payload_hash: hashPayload(options.responsePayload) }\n : {}),\n };\n}\n\n/**\n * Extract verification state from sensor chain metadata.\n */\nexport function extractVerificationState(\n metadata: Record<string, any>,\n): CceVerificationState {\n return {\n clientSigVerified: metadata.cceClientSigVerified === true,\n capsuleSigVerified: metadata.cceCapsuleVerified === true,\n tpsValid: metadata.cceTpsValid === true,\n audienceMatch: metadata.cceBindingVerified === true,\n intentMatch: metadata.cceBindingVerified === true,\n replayClean: metadata.cceReplayClean === true,\n nonceUnique: metadata.cceReplayClean === true,\n decryptionOk: metadata.cceDecryptionOk === true,\n };\n}\n\n// ============================================================================\n// Internal\n// ============================================================================\n\nfunction generateWitnessId(requestId: string, capsuleId: string): string {\n const input = `witness:${requestId}:${capsuleId}:${Date.now()}`;\n const hash = sha256(new TextEncoder().encode(input));\n return \"wit_\" + bytesToHex(hash).slice(0, 24);\n}\n\nfunction computeExecutionContextHash(\n axisLocalSecret: string,\n capsule: CceCapsuleClaims,\n requestNonce: string,\n): string {\n const encoder = new TextEncoder();\n\n // Use HKDF to derive witness key\n const ikm = hexToBytes(axisLocalSecret);\n const salt = sha256(\n encoder.encode(\n capsule.capsule_id + \"|\" + capsule.capsule_nonce + \"|\" + requestNonce,\n ),\n );\n const info = encoder.encode(\n [\n CCE_DERIVATION.WITNESS,\n capsule.sub,\n capsule.kid,\n capsule.intent,\n capsule.aud,\n String(capsule.tps_from),\n String(capsule.tps_to),\n capsule.policy_hash ?? \"\",\n capsule.ver,\n ].join(\"|\"),\n );\n\n const witnessKey = hkdf(sha256, ikm, salt, info, 32);\n const hash = bytesToHex(sha256(witnessKey));\n\n // Clear sensitive material\n witnessKey.fill(0);\n\n return hash;\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n","import type { AxisObservedContext } from \"../types/axis-frame.types\";\n\n/**\n * Sensor Phase Metadata\n *\n * Metadata describing which phase(s) a sensor executes in.\n * Used for validation and optimization.\n *\n * @interface SensorPhaseMetadata\n */\nexport interface SensorPhaseMetadata {\n /** Execution phase: pre-decode (middleware) or post-decode (controller) */\n phase: \"PRE_DECODE\" | \"POST_DECODE\";\n\n /** Other sensors that must run before this one */\n dependencies?: string[];\n\n /** Whether this sensor can perform async I/O */\n asyncOk?: boolean;\n\n /** Whether this sensor can use cryptographic operations */\n cryptoOk?: boolean;\n\n /** Human-readable description of sensor purpose */\n description?: string;\n}\n\n/**\n * AXIS Sensor Interface\n *\n * Core interface for all security sensors in the AXIS pipeline.\n */\nexport interface AxisSensor {\n readonly name: string;\n readonly order?: number; // Lower runs first\n /** Execution phase hint */\n phase?: SensorPhaseMetadata | \"PRE_DECODE\" | \"POST_DECODE\";\n /**\n * Synchronous applicability gate.\n *\n * Return `false` when the sensor does not apply to this input. The chain will\n * skip the sensor without recording a deny decision. Do not perform policy\n * decisions or async I/O here; put those in `run()`.\n */\n supports?(input: SensorInput): boolean;\n /**\n * Executes the sensor's actual check after `supports()` has passed.\n *\n * Return a SensorDecision to allow, deny, throttle, flag, or tighten the\n * request. This method may perform async work according to the sensor phase\n * and metadata.\n */\n run(input: SensorInput): Promise<SensorDecision>;\n}\n\n// Optional lifecycle hook for frameworks that support module initialization.\nexport interface AxisSensorInit extends AxisSensor {\n onModuleInit?(): void | Promise<void>;\n}\n\n/**\n * Sensors that run before frame decoding/deserialization.\n * They should be fast, avoid I/O, and fail fast on malformed traffic.\n */\nexport interface AxisPreSensor extends AxisSensor {\n phase: \"PRE_DECODE\";\n}\n\n/**\n * Sensors that run after a frame is fully decoded and parsed.\n * They may use full context (intent, actor, proofs) and can perform I/O.\n */\nexport interface AxisPostSensor extends AxisSensor {\n phase: \"POST_DECODE\";\n}\n\n/**\n * Sensor Input\n *\n * Represents the structured data passed to a security sensor for evaluation.\n * Depending on the execution phase, different fields may be populated.\n *\n * **Flow:**\n * - **Phase 1 (Pre-decode):** `rawBytes`, `ip`, `path`, and `peek` are typically available.\n * - **Phase 2/3 (Post-decode):** `intent`, `contentLength`, and `metadata` are populated after frame parsing.\n *\n * @interface SensorInput\n */\nexport interface SensorInput {\n /** The full raw binary frame from the wire (if available) */\n rawBytes?: Buffer | Uint8Array;\n\n /** The AXIS intent string extracted from the frame header (e.g., 'system.info') */\n intent?: string;\n\n /** IPv4/IPv6 address of the edge client */\n ip?: string;\n\n /** The HTTP or transport path being accessed */\n path?: string;\n\n /** Total size of the frame body in bytes */\n contentLength?: number;\n\n /** A small slice of the beginning of the body for early pattern matching */\n peek?: Uint8Array;\n\n /** Geolocation country code (if resolved by upstream middleware) */\n country?: string;\n\n /** Client identifier from the transport layer (e.g., Capsule ID or Socket ID) */\n clientId?: string;\n\n /** Whether the request is coming via a WebSocket connection */\n isWs?: boolean;\n\n /** Extensible metadata for cross-sensor communication */\n metadata?: Record<string, any>;\n\n /** Actor ID from frame or request */\n actorId?: string;\n\n /** Operation code */\n opcode?: string;\n\n /** Audience field */\n aud?: string;\n\n /** Observed context from frame parsing */\n observed?: AxisObservedContext;\n\n /** Parsed frame body */\n frameBody?: any;\n\n /** Device identifier */\n deviceId?: string;\n\n /** Session identifier */\n sessionId?: string;\n\n /** Parsed packet data */\n packet?: Record<string, any>;\n\n /** Dynamic field access for sensor-specific data */\n [key: string]: any;\n}\n\nexport enum Decision {\n ALLOW = \"ALLOW\",\n DENY = \"DENY\",\n THROTTLE = \"THROTTLE\",\n FLAG = \"FLAG\",\n}\n/**\n * Sensor Decision\n *\n * Represents the outcome of an individual sensor's evaluation.\n * Supports two formats for backward compatibility:\n *\n * 1. Modern format (preferred): Uses decision/allow/riskScore/reasons\n * 2. Legacy format: Uses action/code/reason (deprecated, will be removed)\n */\nexport type SensorDecision =\n // Modern format (preferred)\n | {\n /** Final decision outcome (optional for backward compatibility) */\n decision?: Decision;\n /** Whether the request may continue immediately */\n allow: boolean;\n /** Risk score from 0–100 (0 = safe, 100 = blocked) */\n riskScore: number;\n /** Human & machine traceable reasons */\n reasons: string[];\n /** Machine-readable error or control code */\n code?: string;\n /** Throttle hint (only relevant for THROTTLE) */\n retryAfterMs?: number;\n /** Optional delta applied to rolling risk/anomaly state */\n scoreDelta?: number;\n /** Extra signals for audit, observability, forensics */\n tags?: Record<string, any>;\n /** Optional capsule / verification metadata */\n meta?: any;\n /** Optional constraint tightening instructions */\n tighten?: {\n expSecondsMax?: number;\n constraintsPatch?: Record<string, any>;\n };\n }\n // Legacy action-based format (deprecated)\n | { action: \"ALLOW\"; meta?: any }\n | {\n action: \"DENY\";\n code: string;\n reason?: string;\n retryAfterMs?: number;\n meta?: any;\n }\n | { action: \"THROTTLE\"; retryAfterMs: number; meta?: any }\n | { action: \"FLAG\"; scoreDelta: number; reasons: string[]; meta?: any };\n\nexport type SensorMinifiedDecision = {\n allow: boolean;\n riskScore: number;\n reasons: string[];\n tags?: Record<string, any>;\n meta?: any;\n tighten?: { expSecondsMax?: number; constraintsPatch?: Record<string, any> };\n /** Legacy fields for compatibility */\n retryAfterMs?: number;\n};\n\n/**\n * Helper to normalize SensorDecision (handles both legacy and modern formats)\n */\nexport function normalizeSensorDecision(\n sensorDecision: SensorDecision,\n): SensorMinifiedDecision {\n // Check if it's a legacy action-based format\n if (\"action\" in sensorDecision) {\n // Convert legacy format to modern\n switch (sensorDecision.action) {\n case \"ALLOW\":\n return {\n allow: true,\n riskScore: 0,\n reasons: [],\n meta: sensorDecision.meta,\n };\n case \"DENY\":\n return {\n allow: false,\n riskScore: 100,\n reasons: [sensorDecision.code, sensorDecision.reason].filter(\n Boolean,\n ) as string[],\n meta: sensorDecision.meta,\n retryAfterMs: sensorDecision.retryAfterMs,\n };\n case \"THROTTLE\":\n return {\n allow: false,\n riskScore: 50,\n reasons: [\"RATE_LIMIT\"],\n retryAfterMs: sensorDecision.retryAfterMs,\n meta: sensorDecision.meta,\n };\n case \"FLAG\":\n return {\n allow: true,\n riskScore: sensorDecision.scoreDelta,\n reasons: sensorDecision.reasons,\n meta: sensorDecision.meta,\n };\n }\n }\n\n // Modern format - already has the required fields\n return {\n allow: sensorDecision.allow,\n riskScore: sensorDecision.riskScore,\n reasons: sensorDecision.reasons,\n tags: sensorDecision.tags,\n meta: sensorDecision.meta,\n tighten: sensorDecision.tighten,\n retryAfterMs: sensorDecision.retryAfterMs,\n };\n}\n\n/**\n * Helper factories for creating SensorDecision objects\n */\nexport const SensorDecisions = {\n allow(meta?: any, tags?: Record<string, any>): SensorDecision {\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n tags,\n meta,\n };\n },\n\n deny(code: string, reason?: string, meta?: any): SensorDecision {\n return {\n decision: Decision.DENY,\n allow: false,\n riskScore: 100,\n code,\n reasons: [code, reason].filter(Boolean) as string[],\n meta,\n };\n },\n\n throttle(retryAfterMs: number, meta?: any): SensorDecision {\n return {\n decision: Decision.THROTTLE,\n allow: false,\n riskScore: 50,\n retryAfterMs,\n code: \"RATE_LIMIT\",\n reasons: [\"RATE_LIMIT\"],\n meta,\n };\n },\n\n flag(scoreDelta: number, reasons: string[], meta?: any): SensorDecision {\n return {\n decision: Decision.FLAG,\n allow: true,\n riskScore: scoreDelta,\n scoreDelta,\n reasons,\n meta,\n };\n },\n};\n","import { buildExecutionContext, type CceDerivationInput } from \"./cce-derivation.service\";\nimport { buildCceErrorResponse, buildCceResponse, type CceAxisSigner, type CceClientKeyEncryptor } from \"./cce-response.service\";\nimport { buildWitnessRecord, type CceWitnessStore, extractVerificationState } from \"./cce-witness.observer\";\nimport type { AxisSensor, SensorDecision, SensorInput } from \"../sensor/axis-sensor\";\nimport { normalizeSensorDecision } from \"../sensor/axis-sensor\";\n/**\n * CCE Pipeline Orchestrator\n *\n * Orchestrates the full CCE request/response lifecycle within AXIS:\n *\n * Request path:\n * 1. Parse envelope\n * 2. Run sensor chain (7 CCE sensors in order)\n * 3. Derive execution context\n * 4. Route to handler\n * 5. Execute handler\n *\n * Response path:\n * 6. Encrypt response\n * 7. Sign response\n * 8. Record witness\n * 9. Return response\n *\n * This orchestrator can be integrated into IntentRouter or used standalone.\n */\nimport { CCE_ERROR, CCE_PROTOCOL_VERSION, type CceCapsuleClaims, CceError, type CceExecutionContext, type CceRequestEnvelope, type CceResponseEnvelope, type CceResponseStatus } from \"./cce.types\";\n\n/**\n * CCE handler function — receives decrypted payload and execution context.\n */\nexport type CceHandler = (\n payload: Uint8Array,\n context: CceHandlerContext,\n) => Promise<CceHandlerResult>;\n\nexport interface CceHandlerContext {\n /** Verified capsule claims */\n capsule: CceCapsuleClaims;\n /** Derived execution context */\n executionContext: CceExecutionContext;\n /** Original request envelope */\n envelope: CceRequestEnvelope;\n /** Client's verified public key */\n clientPublicKeyHex: string;\n /** Request intent */\n intent: string;\n /** Actor identity */\n sub: string;\n}\n\nexport interface CceHandlerResult {\n status: CceResponseStatus;\n body: Uint8Array;\n effect?: string;\n}\n\nexport interface CcePolicyContext {\n envelope: CceRequestEnvelope;\n capsule: CceCapsuleClaims;\n executionContext: CceExecutionContext;\n decryptedPayload: Uint8Array;\n clientPublicKeyHex: string;\n}\n\nexport interface CcePolicyDecision {\n allow: boolean;\n code?: string;\n message?: string;\n}\n\nexport interface CcePolicyEvaluator {\n evaluate(context: CcePolicyContext): Promise<CcePolicyDecision>;\n}\n\n/**\n * CCE Pipeline Configuration\n */\nexport interface CcePipelineConfig {\n /** AXIS local secret for key derivation (hex) */\n axisLocalSecret: string;\n /** AXIS audience identifier */\n axisAudience: string;\n /** CCE sensors (will be sorted by order) */\n sensors: AxisSensor[];\n /** Intent → handler mapping */\n handlers: Map<string, CceHandler>;\n /** Witness store */\n witnessStore: CceWitnessStore;\n /** Client key encryptor (for response encryption) */\n clientKeyEncryptor: CceClientKeyEncryptor;\n /** AXIS response signer */\n axisSigner: CceAxisSigner;\n /** Optional policy/law evaluator run after decryption and before handler execution */\n policyEvaluator?: CcePolicyEvaluator;\n}\n\n/**\n * Result of CCE pipeline execution.\n */\nexport type CcePipelineResult =\n | { ok: true; response: CceResponseEnvelope; witnessId: string }\n | {\n ok: false;\n error: { code: string; message: string };\n status: CceResponseStatus;\n };\n\n/**\n * Execute the full CCE pipeline.\n */\nexport async function executeCcePipeline(\n envelope: CceRequestEnvelope,\n config: CcePipelineConfig,\n): Promise<CcePipelineResult> {\n const startTime = Date.now();\n\n // Validate protocol version\n if (envelope.ver !== CCE_PROTOCOL_VERSION) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.UNSUPPORTED_VERSION,\n message: `Unsupported version: ${envelope.ver}`,\n },\n status: \"ERROR\",\n };\n }\n\n // Build sensor input\n const sensorInput: SensorInput = {\n intent: envelope.capsule.intent,\n metadata: {\n cce: true,\n cceEnvelope: envelope,\n contentType: \"application/axis-cce\",\n },\n };\n\n // Run sensor chain in order\n const sortedSensors = [...config.sensors].sort(\n (a, b) => (a.order ?? 999) - (b.order ?? 999),\n );\n\n for (const sensor of sortedSensors) {\n if (sensor.supports && !sensor.supports(sensorInput)) {\n continue;\n }\n\n let decision: SensorDecision;\n try {\n decision = await sensor.run(sensorInput);\n } catch (err) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.DECRYPTION_FAILED,\n message: `Sensor ${sensor.name} failed`,\n },\n status: \"ERROR\",\n };\n }\n\n const normalized = normalizeSensorDecision(decision);\n if (!normalized.allow) {\n const code =\n normalized.reasons[0]?.split(\":\")[0] ?? CCE_ERROR.DECRYPTION_FAILED;\n return {\n ok: false,\n error: { code, message: normalized.reasons.join(\"; \") },\n status: \"DENIED\",\n };\n }\n }\n\n // Extract verified state\n const capsule = sensorInput.metadata?.cceCapsule as CceCapsuleClaims;\n const decryptedPayload = sensorInput.metadata\n ?.cceDecryptedPayload as Uint8Array;\n const clientKey = sensorInput.metadata?.cceClientKey as {\n publicKeyHex: string;\n };\n\n if (!capsule || !decryptedPayload || !clientKey) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.DECRYPTION_FAILED,\n message: \"Sensor chain did not produce required outputs\",\n },\n status: \"ERROR\",\n };\n }\n\n // Derive execution context\n const derivationInput: CceDerivationInput = {\n axisLocalSecret: config.axisLocalSecret,\n capsule,\n requestNonce: envelope.request_nonce,\n };\n const executionContext = buildExecutionContext(\n derivationInput,\n envelope.request_id,\n );\n\n if (config.policyEvaluator) {\n try {\n const policyDecision = await config.policyEvaluator.evaluate({\n envelope,\n capsule,\n executionContext,\n decryptedPayload,\n clientPublicKeyHex: clientKey.publicKeyHex,\n });\n if (!policyDecision.allow) {\n const verification = extractVerificationState(sensorInput.metadata ?? {});\n const witness = buildWitnessRecord(\n envelope,\n capsule,\n verification,\n {\n status: \"DENIED\",\n handlerDurationMs: 0,\n effect: \"policy_denied\",\n },\n {\n axisLocalSecret: config.axisLocalSecret,\n requestPayload: decryptedPayload,\n responseEncrypted: false,\n },\n );\n await config.witnessStore.record(witness);\n\n return {\n ok: false,\n error: {\n code: policyDecision.code ?? CCE_ERROR.POLICY_DENIED,\n message:\n policyDecision.message ?? \"Request denied by policy evaluator\",\n },\n status: \"DENIED\",\n };\n }\n } catch (err) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.POLICY_DENIED,\n message: \"Policy evaluator failed\",\n },\n status: \"ERROR\",\n };\n }\n }\n\n // Route to handler\n const handler = config.handlers.get(capsule.intent);\n if (!handler) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.HANDLER_NOT_FOUND,\n message: `No handler for intent: ${capsule.intent}`,\n },\n status: \"ERROR\",\n };\n }\n\n // Execute handler\n const handlerContext: CceHandlerContext = {\n capsule,\n executionContext,\n envelope,\n clientPublicKeyHex: clientKey.publicKeyHex,\n intent: capsule.intent,\n sub: capsule.sub,\n };\n\n let result: CceHandlerResult;\n const handlerStart = Date.now();\n try {\n result = await handler(decryptedPayload, handlerContext);\n } catch (err) {\n const handlerDuration = Date.now() - handlerStart;\n\n // Record failure witness\n const verification = extractVerificationState(sensorInput.metadata ?? {});\n const witness = buildWitnessRecord(\n envelope,\n capsule,\n verification,\n { status: \"FAILED\", handlerDurationMs: handlerDuration },\n {\n axisLocalSecret: config.axisLocalSecret,\n requestPayload: decryptedPayload,\n responseEncrypted: false,\n },\n );\n await config.witnessStore.record(witness);\n\n return {\n ok: false,\n error: {\n code: CCE_ERROR.HANDLER_EXECUTION_FAILED,\n message: \"Handler execution failed\",\n },\n status: \"FAILED\",\n };\n }\n const handlerDuration = Date.now() - handlerStart;\n\n // Encrypt response\n let responseEnvelope: CceResponseEnvelope;\n let responsePayloadHash: string;\n\n try {\n const responseResult = await buildCceResponse(\n {\n request: envelope,\n capsule,\n status: result.status,\n body: result.body,\n clientPublicKeyHex: clientKey.publicKeyHex,\n },\n config.clientKeyEncryptor,\n config.axisSigner,\n );\n responseEnvelope = responseResult.envelope;\n responsePayloadHash = responseResult.responsePayloadHash;\n } catch (err) {\n return {\n ok: false,\n error: {\n code: CCE_ERROR.RESPONSE_ENCRYPTION_FAILED,\n message: \"Response encryption failed\",\n },\n status: \"ERROR\",\n };\n }\n\n // Record witness\n const verification = extractVerificationState(sensorInput.metadata ?? {});\n const witness = buildWitnessRecord(\n envelope,\n capsule,\n verification,\n {\n status: result.status,\n handlerDurationMs: handlerDuration,\n effect: result.effect,\n },\n {\n axisLocalSecret: config.axisLocalSecret,\n requestPayload: decryptedPayload,\n responsePayload: result.body,\n responseEncrypted: true,\n },\n );\n await config.witnessStore.record(witness);\n\n return {\n ok: true,\n response: responseEnvelope,\n witnessId: witness.witness_id,\n };\n}\n","/**\n * CCE Envelope Validation Sensor\n *\n * Band: WIRE (order: 5)\n * Phase: PRE_DECODE\n *\n * Step 1-2 from CCE verification order:\n * 1. Validate envelope schema\n * 2. Check protocol version\n *\n * Fast-fails malformed CCE requests before any crypto work.\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n CCE_NONCE_BYTES,\n CCE_PROTOCOL_VERSION,\n type CceRequestEnvelope,\n} from \"../cce.types\";\n\nconst REQUIRED_FIELDS: (keyof CceRequestEnvelope)[] = [\n \"ver\",\n \"request_id\",\n \"correlation_id\",\n \"client_kid\",\n \"capsule\",\n \"encrypted_key\",\n \"encrypted_payload\",\n \"request_nonce\",\n \"client_sig\",\n \"content_type\",\n \"algorithms\",\n];\n\nexport class CceEnvelopeValidationSensor implements AxisSensor {\n readonly name = \"cce.envelope.validation\";\n readonly order = 5;\n readonly phase = \"PRE_DECODE\" as const;\n\n // supports() is a synchronous applicability gate.\n // Return false to skip this sensor without producing a denial.\n supports(input: SensorInput): boolean {\n // Only process CCE envelopes (detected by metadata flag or content type)\n return input.metadata?.cce === true ||\n input.metadata?.contentType === \"application/axis-cce\";\n }\n\n // run() executes only after supports() passes.\n // Return the actual ALLOW/DENY/FLAG/THROTTLE decision here.\n async run(input: SensorInput): Promise<SensorDecision> {\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.INVALID_ENVELOPE],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Check required fields\n for (const field of REQUIRED_FIELDS) {\n if (envelope[field] === undefined || envelope[field] === null) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.INVALID_ENVELOPE}: missing ${field}`],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n }\n\n // Check protocol version\n if (envelope.ver !== CCE_PROTOCOL_VERSION) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.UNSUPPORTED_VERSION}: ${envelope.ver}`],\n code: CCE_ERROR.UNSUPPORTED_VERSION,\n };\n }\n\n // Validate request nonce format (must be hex, correct length)\n if (!/^[0-9a-f]+$/i.test(envelope.request_nonce)) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INVALID_ENVELOPE}: invalid request_nonce format`,\n ],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n if (envelope.request_nonce.length !== CCE_NONCE_BYTES * 2) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.INVALID_ENVELOPE}: request_nonce wrong length`],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Validate capsule has required fields\n const capsule = envelope.capsule;\n if (\n !capsule.capsule_id ||\n !capsule.ver ||\n !capsule.sub ||\n !capsule.kid ||\n !capsule.intent ||\n !capsule.aud ||\n !capsule.issuer_sig\n ) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.MISSING_CAPSULE}: incomplete capsule claims`],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Validate encrypted key structure\n if (!envelope.encrypted_key.ciphertext || !envelope.encrypted_key.alg) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.MISSING_ENCRYPTED_KEY}: incomplete encrypted_key`,\n ],\n code: CCE_ERROR.MISSING_ENCRYPTED_KEY,\n };\n }\n\n // Pass: store parsed envelope in metadata for downstream sensors\n input.metadata = input.metadata ?? {};\n input.metadata.cceEnvelopeValid = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Client Signature Verification Sensor\n *\n * Band: IDENTITY (order: 45)\n * Phase: POST_DECODE\n *\n * Steps 4-5 from CCE verification order:\n * 4. Resolve client public key\n * 5. Verify client signature over canonical envelope\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport { CCE_ERROR, type CceRequestEnvelope } from \"../cce.types\";\n\n/**\n * Key resolver interface — implementations can look up Redis, DB, or in-memory.\n */\nexport interface CceClientKeyResolver {\n resolve(kid: string): Promise<{ publicKeyHex: string; alg: string } | null>;\n}\n\n/**\n * Signature verifier interface — pluggable for Ed25519, ES256, etc.\n */\nexport interface CceSignatureVerifier {\n verify(\n message: Uint8Array,\n signatureHex: string,\n publicKeyHex: string,\n alg: string,\n ): Promise<boolean>;\n}\n\nexport class CceClientSignatureSensor implements AxisSensor {\n readonly name = \"cce.client.signature\";\n readonly order = 45;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n private readonly keyResolver: CceClientKeyResolver,\n private readonly signatureVerifier: CceSignatureVerifier,\n ) {}\n\n // supports() is a synchronous applicability gate.\n // Return false to skip this sensor without producing a denial.\n supports(input: SensorInput): boolean {\n return input.metadata?.cceEnvelopeValid === true;\n }\n\n // run() executes only after supports() passes.\n // Return the actual ALLOW/DENY/FLAG/THROTTLE decision here.\n async run(input: SensorInput): Promise<SensorDecision> {\n const envelope = input.metadata?.cceEnvelope as CceRequestEnvelope;\n if (!envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.INVALID_ENVELOPE],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Step 4: Resolve client public key\n const keyRecord = await this.keyResolver.resolve(envelope.client_kid);\n if (!keyRecord) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.CLIENT_KEY_NOT_FOUND}: kid=${envelope.client_kid}`,\n ],\n code: CCE_ERROR.CLIENT_KEY_NOT_FOUND,\n };\n }\n\n // Step 5: Verify client signature\n // Canonical signing payload: everything except client_sig\n const { client_sig, ...signable } = envelope;\n const canonical = canonicalize(signable);\n const message = new TextEncoder().encode(canonical);\n\n const valid = await this.signatureVerifier.verify(\n message,\n client_sig.value,\n keyRecord.publicKeyHex,\n keyRecord.alg,\n );\n\n if (!valid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.CLIENT_SIG_INVALID],\n code: CCE_ERROR.CLIENT_SIG_INVALID,\n };\n }\n\n // Store resolved key for downstream\n input.metadata = input.metadata ?? {};\n input.metadata.cceClientKey = keyRecord;\n input.metadata.cceClientSigVerified = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n meta: { kid: envelope.client_kid },\n };\n }\n}\n\n// Canonical JSON for deterministic signature verification\nfunction canonicalize(obj: unknown): string {\n if (Array.isArray(obj)) {\n return \"[\" + obj.map(canonicalize).join(\",\") + \"]\";\n }\n if (obj !== null && typeof obj === \"object\") {\n const sorted = Object.keys(obj as object)\n .sort()\n .map(\n (k) =>\n JSON.stringify(k) +\n \":\" +\n canonicalize((obj as Record<string, unknown>)[k]),\n );\n return \"{\" + sorted.join(\",\") + \"}\";\n }\n return JSON.stringify(obj);\n}\n","/**\n * CCE Capsule Verification Sensor\n *\n * Band: IDENTITY (order: 50)\n * Phase: POST_DECODE\n *\n * Step 6 from CCE verification order:\n * 6. Parse capsule, verify TickAuth signature, verify integrity\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n CCE_PROTOCOL_VERSION,\n type CceCapsuleClaims,\n} from \"../cce.types\";\n\n/**\n * TickAuth issuer key resolver.\n */\nexport interface CceIssuerKeyResolver {\n resolve(kid: string): Promise<{ publicKeyHex: string } | null>;\n}\n\n/**\n * Signature verifier for capsule issuer signatures.\n */\nexport interface CceCapsuleSignatureVerifier {\n verify(\n claims: Omit<CceCapsuleClaims, \"issuer_sig\">,\n signature: { alg: string; kid: string; value: string },\n publicKeyHex: string,\n ): Promise<boolean>;\n}\n\nexport class CceCapsuleVerificationSensor implements AxisSensor {\n readonly name = \"cce.capsule.verification\";\n readonly order = 50;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n private readonly issuerKeyResolver: CceIssuerKeyResolver,\n private readonly capsuleVerifier: CceCapsuleSignatureVerifier,\n ) {}\n\n // supports() is a synchronous applicability gate.\n // Return false to skip this sensor without producing a denial.\n supports(input: SensorInput): boolean {\n return input.metadata?.cceEnvelopeValid === true;\n }\n\n // run() executes only after supports() passes.\n // Return the actual ALLOW/DENY/FLAG/THROTTLE decision here.\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceEnvelope?.capsule as\n | CceCapsuleClaims\n | undefined;\n\n if (!capsule) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Verify protocol version\n if (capsule.ver !== CCE_PROTOCOL_VERSION) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.CAPSULE_SIG_INVALID}: wrong version ${capsule.ver}`,\n ],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Verify content integrity (ID matches hash)\n const { capsule_id, issuer_sig, ...claimsBody } = capsule;\n const expectedId = computeCceCapsuleId(claimsBody);\n if (capsule_id !== expectedId) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_SIG_INVALID}: content hash mismatch`],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Resolve TickAuth issuer key\n const issuerKey = await this.issuerKeyResolver.resolve(\n capsule.issuer_sig.kid,\n );\n if (!issuerKey) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_SIG_INVALID}: issuer key not found`],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Verify issuer signature\n const { issuer_sig: sig, ...rest } = capsule;\n const sigValid = await this.capsuleVerifier.verify(\n rest,\n sig,\n issuerKey.publicKeyHex,\n );\n if (!sigValid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.CAPSULE_SIG_INVALID],\n code: CCE_ERROR.CAPSULE_SIG_INVALID,\n };\n }\n\n // Check expiry\n const nowSeconds = Math.floor(Date.now() / 1000);\n if (capsule.exp < nowSeconds) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_EXPIRED}: exp=${capsule.exp}`],\n code: CCE_ERROR.CAPSULE_EXPIRED,\n };\n }\n\n // Check not-yet-valid (iat in future with tolerance)\n if (capsule.iat > nowSeconds + 5) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_NOT_YET_VALID}: iat=${capsule.iat}`],\n code: CCE_ERROR.CAPSULE_NOT_YET_VALID,\n };\n }\n\n // Store verified capsule for downstream\n input.metadata = input.metadata ?? {};\n input.metadata.cceCapsuleVerified = true;\n input.metadata.cceCapsule = capsule;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n meta: { capsule_id: capsule.capsule_id },\n };\n }\n}\n\n// Content-addressed capsule ID computation\nimport { blake3 } from \"@noble/hashes/blake3.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\n\nfunction canonicalize(obj: unknown): string {\n if (Array.isArray(obj)) {\n return \"[\" + obj.map(canonicalize).join(\",\") + \"]\";\n }\n if (obj !== null && typeof obj === \"object\") {\n const sorted = Object.keys(obj as object)\n .sort()\n .map(\n (k) =>\n JSON.stringify(k) +\n \":\" +\n canonicalize((obj as Record<string, unknown>)[k]),\n );\n return \"{\" + sorted.join(\",\") + \"}\";\n }\n return JSON.stringify(obj);\n}\n\nfunction computeCceCapsuleId(claims: Record<string, unknown>): string {\n const canonical = canonicalize(claims);\n const hash = blake3(new TextEncoder().encode(canonical));\n return \"cce_b3_\" + bytesToHex(hash).slice(0, 32);\n}\n","/**\n * CCE TPS Window Validation Sensor\n *\n * Band: POLICY (order: 92)\n * Phase: POST_DECODE\n *\n * Step 7 from CCE verification order:\n * 7. Verify TPS window is current (not expired, not future)\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport { CCE_ERROR, type CceCapsuleClaims } from \"../cce.types\";\n\n/** Maximum acceptable clock skew in milliseconds */\nconst DEFAULT_SKEW_MS = 5000;\n\nexport class CceTpsWindowSensor implements AxisSensor {\n readonly name = \"cce.tps.window\";\n readonly order = 92;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(private readonly skewMs: number = DEFAULT_SKEW_MS) {}\n\n // supports() is a synchronous applicability gate.\n // Return false to skip this sensor without producing a denial.\n supports(input: SensorInput): boolean {\n return input.metadata?.cceCapsuleVerified === true;\n }\n\n // run() executes only after supports() passes.\n // Return the actual ALLOW/DENY/FLAG/THROTTLE decision here.\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceCapsule as CceCapsuleClaims | undefined;\n if (!capsule) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n const nowMs = Date.now();\n\n // Check if TPS window has expired (with skew tolerance)\n if (nowMs > capsule.tps_to + this.skewMs) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.TPS_WINDOW_EXPIRED}: window ended at ${capsule.tps_to}, now=${nowMs}`,\n ],\n code: CCE_ERROR.TPS_WINDOW_EXPIRED,\n };\n }\n\n // Check if TPS window is in the future (with skew tolerance)\n if (nowMs < capsule.tps_from - this.skewMs) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.TPS_WINDOW_FUTURE}: window starts at ${capsule.tps_from}, now=${nowMs}`,\n ],\n code: CCE_ERROR.TPS_WINDOW_FUTURE,\n };\n }\n\n input.metadata = input.metadata ?? {};\n input.metadata.cceTpsValid = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Audience & Intent Binding Sensor\n *\n * Band: POLICY (order: 95)\n * Phase: POST_DECODE\n *\n * Steps 8-9 from CCE verification order:\n * 8. Verify audience matches this AXIS instance\n * 9. Verify intent matches the capsule-bound intent\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n type CceCapsuleClaims,\n type CceRequestEnvelope,\n} from \"../cce.types\";\n\nexport class CceAudienceIntentBindingSensor implements AxisSensor {\n readonly name = \"cce.audience.intent.binding\";\n readonly order = 95;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n /** This AXIS instance's audience identifier */\n private readonly axisAudience: string,\n ) {}\n\n // supports() is a synchronous applicability gate.\n // Return false to skip this sensor without producing a denial.\n supports(input: SensorInput): boolean {\n return input.metadata?.cceCapsuleVerified === true;\n }\n\n // run() executes only after supports() passes.\n // Return the actual ALLOW/DENY/FLAG/THROTTLE decision here.\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceCapsule as CceCapsuleClaims | undefined;\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!capsule || !envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Step 8: Verify audience\n if (capsule.aud !== this.axisAudience) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.AUDIENCE_MISMATCH}: capsule.aud=${capsule.aud}, expected=${this.axisAudience}`,\n ],\n code: CCE_ERROR.AUDIENCE_MISMATCH,\n };\n }\n\n // Step 9: Verify intent\n // The intent in the envelope should match the capsule-bound intent\n const requestIntent = input.intent ?? input.metadata?.cceRequestIntent;\n if (requestIntent && capsule.intent !== requestIntent) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INTENT_MISMATCH}: capsule.intent=${capsule.intent}, request=${requestIntent}`,\n ],\n code: CCE_ERROR.INTENT_MISMATCH,\n };\n }\n\n // Verify client_kid in envelope matches capsule kid\n if (envelope.client_kid !== capsule.kid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INTENT_MISMATCH}: envelope.kid=${envelope.client_kid}, capsule.kid=${capsule.kid}`,\n ],\n code: CCE_ERROR.INTENT_MISMATCH,\n };\n }\n\n input.metadata = input.metadata ?? {};\n input.metadata.cceBindingVerified = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Replay Protection Sensor\n *\n * Band: POLICY (order: 98)\n * Phase: POST_DECODE\n *\n * Steps 10-11 from CCE verification order:\n * 10. Verify capsule not replayed (capsule_id not consumed if SINGLE_USE)\n * 11. Verify request nonce uniqueness\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport {\n CCE_ERROR,\n type CceCapsuleClaims,\n type CceRequestEnvelope,\n} from \"../cce.types\";\n\n/**\n * Replay store interface — implementations can use Redis, in-memory, etc.\n * Must support O(1) lookups for performance in the hot path.\n */\nexport interface CceReplayStore {\n /**\n * Check and mark a nonce/id as used.\n * @returns true if this is the first time (valid), false if replay\n */\n checkAndMark(key: string, ttlMs: number): Promise<boolean>;\n\n /** Check if a capsule has been consumed */\n isCapsuleConsumed(capsuleId: string): Promise<boolean>;\n\n /** Mark a capsule as consumed */\n markCapsuleConsumed(capsuleId: string, ttlMs: number): Promise<void>;\n\n /** Check if a capsule has been revoked */\n isCapsuleRevoked(capsuleId: string): Promise<boolean>;\n}\n\n/**\n * In-memory replay store for development/testing.\n */\nexport class InMemoryCceReplayStore implements CceReplayStore {\n private nonces = new Map<string, number>();\n private consumed = new Set<string>();\n private revoked = new Set<string>();\n\n async checkAndMark(key: string, ttlMs: number): Promise<boolean> {\n this.cleanup();\n if (this.nonces.has(key)) return false;\n this.nonces.set(key, Date.now() + ttlMs);\n return true;\n }\n\n async isCapsuleConsumed(capsuleId: string): Promise<boolean> {\n return this.consumed.has(capsuleId);\n }\n\n async markCapsuleConsumed(capsuleId: string, _ttlMs: number): Promise<void> {\n this.consumed.add(capsuleId);\n }\n\n async isCapsuleRevoked(capsuleId: string): Promise<boolean> {\n return this.revoked.has(capsuleId);\n }\n\n /** Revoke a capsule (for testing/admin) */\n revoke(capsuleId: string): void {\n this.revoked.add(capsuleId);\n }\n\n private cleanup(): void {\n const now = Date.now();\n for (const [key, expiresAt] of this.nonces) {\n if (expiresAt < now) this.nonces.delete(key);\n }\n }\n}\n\nexport class CceReplayProtectionSensor implements AxisSensor {\n readonly name = \"cce.replay.protection\";\n readonly order = 98;\n readonly phase = \"POST_DECODE\" as const;\n\n /** Default nonce TTL: 5 minutes */\n private readonly nonceTtlMs: number;\n\n constructor(\n private readonly replayStore: CceReplayStore,\n options?: { nonceTtlMs?: number },\n ) {\n this.nonceTtlMs = options?.nonceTtlMs ?? 5 * 60 * 1000;\n }\n\n // supports() is a synchronous applicability gate.\n // Return false to skip this sensor without producing a denial.\n supports(input: SensorInput): boolean {\n return input.metadata?.cceCapsuleVerified === true;\n }\n\n // run() executes only after supports() passes.\n // Return the actual ALLOW/DENY/FLAG/THROTTLE decision here.\n async run(input: SensorInput): Promise<SensorDecision> {\n const capsule = input.metadata?.cceCapsule as CceCapsuleClaims | undefined;\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!capsule || !envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.MISSING_CAPSULE],\n code: CCE_ERROR.MISSING_CAPSULE,\n };\n }\n\n // Check capsule revocation\n const revoked = await this.replayStore.isCapsuleRevoked(capsule.capsule_id);\n if (revoked) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_REVOKED}: ${capsule.capsule_id}`],\n code: CCE_ERROR.CAPSULE_REVOKED,\n };\n }\n\n // Check capsule consumption (SINGLE_USE mode)\n if (capsule.mode === \"SINGLE_USE\") {\n const consumed = await this.replayStore.isCapsuleConsumed(\n capsule.capsule_id,\n );\n if (consumed) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.CAPSULE_CONSUMED}: ${capsule.capsule_id}`],\n code: CCE_ERROR.CAPSULE_CONSUMED,\n };\n }\n }\n\n // Check request nonce uniqueness\n // Namespace: sub + aud + intent to prevent cross-context collision\n const nonceKey = `cce:nonce:${capsule.sub}:${capsule.aud}:${capsule.intent}:${envelope.request_nonce}`;\n const nonceValid = await this.replayStore.checkAndMark(\n nonceKey,\n this.nonceTtlMs,\n );\n if (!nonceValid) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.NONCE_REUSED}: ${envelope.request_nonce.slice(0, 16)}...`,\n ],\n code: CCE_ERROR.NONCE_REUSED,\n };\n }\n\n // Mark capsule consumed for SINGLE_USE\n if (capsule.mode === \"SINGLE_USE\") {\n const capsuleTtl = (capsule.exp - capsule.iat) * 1000 + 60_000; // TTL + 1 min buffer\n await this.replayStore.markCapsuleConsumed(\n capsule.capsule_id,\n capsuleTtl,\n );\n }\n\n input.metadata = input.metadata ?? {};\n input.metadata.cceReplayClean = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n","/**\n * CCE Payload Decryption Sensor\n *\n * Band: CONTENT (order: 145)\n * Phase: POST_DECODE\n *\n * Steps 12-13 from CCE verification order:\n * 12. Decrypt transport key → decrypt payload\n * 13. Validate plaintext payload schema\n *\n * This sensor performs the actual cryptographic decryption of the request payload.\n * It unwraps the AES transport key using the AXIS private key, then decrypts\n * the payload with AES-256-GCM.\n */\nimport type {\n AxisSensor,\n SensorDecision,\n SensorInput,\n} from \"../../sensor/axis-sensor\";\nimport { Decision } from \"../../sensor/axis-sensor\";\nimport { CCE_ERROR, type CceRequestEnvelope } from \"../cce.types\";\n\n/**\n * AXIS private key provider for decrypting the transport key.\n */\nexport interface CceAxisKeyProvider {\n /**\n * Decrypt a transport key using AXIS private key.\n * Supports X25519 (ECDH) and RSA-OAEP key unwrapping.\n */\n unwrapKey(\n encryptedKeyB64: string,\n algorithm: string,\n axisKid: string,\n ephemeralPkB64?: string,\n ): Promise<Uint8Array | null>;\n}\n\n/**\n * AES-GCM decryption provider.\n */\nexport interface CceAesGcmProvider {\n /**\n * Decrypt ciphertext with AES-256-GCM.\n * @returns plaintext bytes, or null if AEAD tag verification failed\n */\n decrypt(\n key: Uint8Array,\n iv: Uint8Array,\n ciphertext: Uint8Array,\n tag: Uint8Array,\n aad?: Uint8Array,\n ): Promise<Uint8Array | null>;\n}\n\nexport interface CcePayloadValidatorResult {\n ok: boolean;\n intent?: string;\n code?: string;\n reason?: string;\n}\n\n/**\n * Optional decrypted payload validator.\n * Use this hook to enforce intent-specific schema checks before handler execution.\n */\nexport interface CcePayloadValidator {\n validate(\n plaintext: Uint8Array,\n envelope: CceRequestEnvelope,\n ): Promise<CcePayloadValidatorResult>;\n}\n\nexport class CcePayloadDecryptionSensor implements AxisSensor {\n readonly name = \"cce.payload.decryption\";\n readonly order = 145;\n readonly phase = \"POST_DECODE\" as const;\n\n constructor(\n private readonly keyProvider: CceAxisKeyProvider,\n private readonly aesProvider: CceAesGcmProvider,\n private readonly maxPayloadBytes: number = 64 * 1024,\n private readonly payloadValidator?: CcePayloadValidator,\n ) {}\n\n // supports() is a synchronous applicability gate.\n // Return false to skip this sensor without producing a denial.\n supports(input: SensorInput): boolean {\n return input.metadata?.cceEnvelopeValid === true &&\n input.metadata?.cceClientSigVerified === true &&\n input.metadata?.cceCapsuleVerified === true &&\n input.metadata?.cceReplayClean === true;\n }\n\n // run() executes only after supports() passes.\n // Return the actual ALLOW/DENY/FLAG/THROTTLE decision here.\n async run(input: SensorInput): Promise<SensorDecision> {\n const envelope = input.metadata?.cceEnvelope as\n | CceRequestEnvelope\n | undefined;\n\n if (!envelope) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.INVALID_ENVELOPE],\n code: CCE_ERROR.INVALID_ENVELOPE,\n };\n }\n\n // Step 11 (from spec): Decrypt transport key\n let aesKey: Uint8Array | null;\n try {\n aesKey = await this.keyProvider.unwrapKey(\n envelope.encrypted_key.ciphertext,\n envelope.encrypted_key.alg,\n envelope.encrypted_key.axis_kid,\n envelope.encrypted_key.ephemeral_pk,\n );\n } catch {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.KEY_UNWRAP_FAILED],\n code: CCE_ERROR.KEY_UNWRAP_FAILED,\n };\n }\n\n if (!aesKey) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.KEY_UNWRAP_FAILED],\n code: CCE_ERROR.KEY_UNWRAP_FAILED,\n };\n }\n\n // Step 12: Decrypt payload with AES-GCM\n let iv: Uint8Array;\n let ciphertext: Uint8Array;\n let tag: Uint8Array;\n\n try {\n iv = base64UrlDecode(envelope.encrypted_payload.iv);\n ciphertext = base64UrlDecode(envelope.encrypted_payload.ciphertext);\n tag = base64UrlDecode(envelope.encrypted_payload.tag);\n } catch {\n return {\n allow: false,\n riskScore: 100,\n reasons: [`${CCE_ERROR.DECRYPTION_FAILED}: invalid base64url encoding`],\n code: CCE_ERROR.DECRYPTION_FAILED,\n };\n }\n\n // Check payload size before decryption\n if (ciphertext.length > this.maxPayloadBytes) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.PAYLOAD_TOO_LARGE}: ${ciphertext.length} > ${this.maxPayloadBytes}`,\n ],\n code: CCE_ERROR.PAYLOAD_TOO_LARGE,\n };\n }\n\n // Build AAD from envelope metadata (binds ciphertext to context)\n const aad = buildAad(envelope);\n\n let plaintext: Uint8Array | null;\n try {\n plaintext = await this.aesProvider.decrypt(\n aesKey,\n iv,\n ciphertext,\n tag,\n aad,\n );\n } catch {\n plaintext = null;\n } finally {\n // Clear AES key from memory (best effort)\n aesKey.fill(0);\n }\n\n if (!plaintext) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [CCE_ERROR.AEAD_TAG_MISMATCH],\n code: CCE_ERROR.AEAD_TAG_MISMATCH,\n };\n }\n\n const capsule = input.metadata?.cceCapsule as\n | { intent: string }\n | undefined;\n\n // Built-in JSON intent binding check.\n if (capsule && isJsonContentType(envelope.content_type)) {\n const parsed = tryParseJsonObject(plaintext);\n if (parsed && typeof parsed.intent === \"string\") {\n if (parsed.intent !== capsule.intent) {\n return {\n allow: false,\n riskScore: 100,\n reasons: [\n `${CCE_ERROR.INTENT_SCHEMA_MISMATCH}: payload.intent=${parsed.intent}, capsule.intent=${capsule.intent}`,\n ],\n code: CCE_ERROR.INTENT_SCHEMA_MISMATCH,\n };\n }\n input.metadata = input.metadata ?? {};\n input.metadata.cceRequestIntent = parsed.intent;\n }\n }\n\n if (this.payloadValidator) {\n const verdict = await this.payloadValidator.validate(plaintext, envelope);\n if (!verdict.ok) {\n const code = verdict.code ?? CCE_ERROR.PAYLOAD_SCHEMA_INVALID;\n return {\n allow: false,\n riskScore: 100,\n reasons: [verdict.reason ?? code],\n code,\n };\n }\n\n if (verdict.intent) {\n input.metadata = input.metadata ?? {};\n input.metadata.cceRequestIntent = verdict.intent;\n }\n }\n\n // Store decrypted payload for handler\n input.metadata = input.metadata ?? {};\n input.metadata.cceDecryptedPayload = plaintext;\n input.metadata.cceDecryptionOk = true;\n\n return {\n decision: Decision.ALLOW,\n allow: true,\n riskScore: 0,\n reasons: [],\n };\n }\n}\n\n/**\n * Build Additional Authenticated Data from envelope fields.\n * Binds the ciphertext to the request context and prevents\n * transplanting encrypted payloads between requests.\n */\nfunction buildAad(envelope: CceRequestEnvelope): Uint8Array {\n const parts = [\n envelope.ver,\n envelope.request_id,\n envelope.correlation_id,\n envelope.client_kid,\n envelope.capsule.capsule_id,\n envelope.capsule.intent,\n envelope.capsule.aud,\n envelope.request_nonce,\n ];\n return new TextEncoder().encode(parts.join(\"|\"));\n}\n\nfunction isJsonContentType(contentType: string | undefined): boolean {\n return (\n typeof contentType === \"string\" &&\n contentType.toLowerCase().includes(\"application/json\")\n );\n}\n\nfunction tryParseJsonObject(\n payload: Uint8Array,\n): Record<string, unknown> | null {\n try {\n const parsed = JSON.parse(new TextDecoder().decode(payload));\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/** Base64url decode */\nfunction base64UrlDecode(input: string): Uint8Array {\n const base64 = input.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = \"=\".repeat((4 - (base64.length % 4)) % 4);\n return new Uint8Array(Buffer.from(base64 + padding, \"base64\"));\n}\n"],"mappings":"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","names":["bytesToHex","sha256","bytesToHex","sha256","bytesToHex","randomBytes","bytesToHex","randomBytes","bytesToHex","hkdf","sha256","sha256","bytesToHex","hexToBytes","hkdf","verification","witness","handlerDuration","canonicalize","bytesToHex","canonicalize","base64UrlDecode"]}
@@ -1,4 +1,4 @@
1
- import { A as AxisSensor } from './axis-sensor-DMW4rfRg.mjs';
1
+ import { A as AxisSensor } from './axis-sensor-BLUemDiZ.mjs';
2
2
 
3
3
  declare const CCE_PROTOCOL_VERSION: "cce-v1";
4
4
  declare const CCE_DERIVATION: {
@@ -1,4 +1,4 @@
1
- import { A as AxisSensor } from './axis-sensor-DMW4rfRg.js';
1
+ import { A as AxisSensor } from './axis-sensor-BLUemDiZ.js';
2
2
 
3
3
  declare const CCE_PROTOCOL_VERSION: "cce-v1";
4
4
  declare const CCE_DERIVATION: {