@astrasyncai/adapter-lambda 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/cf.ts","../src/config.ts","../src/classify.ts","../src/detect.ts","../src/pipeline.ts","../src/events.ts","../src/messaging.ts","../src/enforce.ts","../src/handler.ts"],"sourcesContent":["/**\n * @astrasyncai/adapter-lambda — Commerce Shield edge adapter (spec §7.4,\n * backlog §33.5 #1).\n *\n * Library surface: `createEdgeHandler(options)` builds a Lambda@Edge\n * origin-request handler. The deployable single-file bundle lives at\n * `dist/lambda/index.js` (see `src/lambda-entry.ts` + `infra/`).\n */\n\nexport { createEdgeHandler, type EdgeHandler } from './handler';\nexport { classify, resolvePolicy } from './classify';\nexport { detectCommerce, type DetectedCommerce } from './detect';\nexport { runTier } from './pipeline';\nexport { applyOutcome, ASAT_HEADERS } from './enforce';\nexport { buildDenyBody, buildManualReviewBody } from './messaging';\nexport { emitBeacon, withBudget, sampled } from './events';\nexport { resolveApiKey, loadEdgeConfig, _resetConfigCaches } from './config';\nexport {\n getRequest,\n getHeader,\n flattenHeaders,\n decodeBody,\n requestUrl,\n setHeader,\n stripHeadersByPrefix,\n jsonResponse,\n} from './cf';\nexport type {\n EdgeAdapterOptions,\n Classification,\n TrafficTier,\n TierOutcome,\n EdgeDecision,\n EffectivePolicy,\n} from './types';\n","/**\n * CloudFront origin-request event helpers. The Lambda@Edge event shape puts\n * headers in `{ key, value }[]` arrays keyed by LOWERCASED header name, and\n * (with IncludeBody) the body arrives base64-encoded with an\n * `inputTruncated` flag when it exceeded CloudFront's ~1MB exposure cap.\n */\n\nimport type {\n CloudFrontRequest,\n CloudFrontRequestEvent,\n CloudFrontHeaders,\n CloudFrontResultResponse,\n} from 'aws-lambda';\nimport {\n sanitizeHeaders,\n type ObservedMetadata,\n} from '@astrasyncai/verification-gateway/metadata-capture';\n\nexport function getRequest(event: CloudFrontRequestEvent): CloudFrontRequest {\n return event.Records[0].cf.request;\n}\n\n/** First value of a header (lowercase name), or undefined. */\nexport function getHeader(request: CloudFrontRequest, name: string): string | undefined {\n return request.headers[name.toLowerCase()]?.[0]?.value;\n}\n\n/**\n * Flatten CloudFront headers into the `Record<string, string | string[]>`\n * shape the SDK extractors and verify-access artifacts expect.\n */\nexport function flattenHeaders(headers: CloudFrontHeaders): Record<string, string | string[]> {\n const out: Record<string, string | string[]> = {};\n for (const [name, entries] of Object.entries(headers)) {\n if (!entries?.length) continue;\n out[name] = entries.length === 1 ? entries[0].value : entries.map((e) => e.value);\n }\n return out;\n}\n\nexport interface DecodedBody {\n /** UTF-8 body text, undefined when there is no body. */\n text?: string;\n /** True when CloudFront truncated the body before handing it to the trigger. */\n truncated: boolean;\n}\n\nexport function decodeBody(request: CloudFrontRequest): DecodedBody {\n const body = request.body;\n if (!body?.data) return { truncated: false };\n const text =\n body.encoding === 'base64' ? Buffer.from(body.data, 'base64').toString('utf8') : body.data;\n return { text, truncated: body.inputTruncated === true };\n}\n\n/**\n * Workstream D — connection-layer signals the edge can see but the SDK cannot.\n * CloudFront injects the `CloudFront-Viewer-*` header family (IP, ASN, country,\n * TLS version/cipher, HTTP version, device class) when the OriginRequestPolicy\n * whitelists them (see infra/template.yaml). Absent values are simply omitted —\n * a partial connection block is fine.\n */\nexport function collectConnectionMetadata(request: CloudFrontRequest): Record<string, string> {\n const out: Record<string, string> = {};\n const put = (key: string, headerName: string, transform?: (v: string) => string) => {\n const v = getHeader(request, headerName);\n if (v) out[key] = transform ? transform(v) : v;\n };\n // `cloudfront-viewer-address` is `ip:port` (IPv6 keeps its brackets); take the\n // address portion the same way the beacon/pipeline already do.\n const addr = getHeader(request, 'cloudfront-viewer-address');\n if (addr) out.ip = addr.replace(/:\\d+$/, '');\n put('country', 'cloudfront-viewer-country');\n put('countryName', 'cloudfront-viewer-country-name');\n put('region', 'cloudfront-viewer-country-region');\n put('city', 'cloudfront-viewer-city');\n put('asn', 'cloudfront-viewer-asn');\n put('tlsVersion', 'cloudfront-viewer-tls');\n put('httpVersion', 'cloudfront-viewer-http-version');\n // Device-class booleans → a single compact device string.\n const devices: string[] = [];\n for (const [label, header] of [\n ['desktop', 'cloudfront-is-desktop-viewer'],\n ['mobile', 'cloudfront-is-mobile-viewer'],\n ['tablet', 'cloudfront-is-tablet-viewer'],\n ['smarttv', 'cloudfront-is-smarttv-viewer'],\n ] as const) {\n if (getHeader(request, header) === 'true') devices.push(label);\n }\n if (devices.length) out.device = devices.join(',');\n return out;\n}\n\n/**\n * Workstream D — the FULL sanitised metadata capture for one request: every\n * inbound header (secrets stripped, credential headers reduced to a safe format\n * prefix) plus the connection-layer block. The edge is the richest capture\n * point — the header arrays are already in memory — and this is pure string\n * work, so it adds no page latency. Forwarded on both the verify-access call\n * and the beacon.\n */\nexport function buildObservedMetadata(request: CloudFrontRequest): ObservedMetadata {\n const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(\n flattenHeaders(request.headers)\n );\n const connection = collectConnectionMetadata(request);\n return {\n headers,\n ...(apiKeyFormat && { apiKeyFormat }),\n ...(platformHeaders && { platformHeaders }),\n ...(Object.keys(connection).length > 0 && { connection }),\n };\n}\n\n/**\n * Workstream D — normalize the origin-bound `Host` header.\n *\n * To receive the `CloudFront-Viewer-*` connection headers (IP/ASN/TLS/country)\n * we must move off the managed `AllViewerExceptHostHeader` origin-request policy\n * onto one that whitelists those headers — but every such policy ALSO forwards\n * the viewer `Host`, which would break vhost / PaaS origin routing that expects\n * the origin's own hostname. So the Lambda takes ownership of the Host rewrite:\n * stash the public (viewer) host into `X-Forwarded-Host` for downstream use and\n * detection, then set `Host` to the origin's domain (available on the event as\n * `request.origin.custom.domainName`). No-ops when the origin domain is absent\n * (synthetic test events) or already matches — so it is safe on every path,\n * including static-asset pass-through.\n */\nexport function normalizeOriginHost(request: CloudFrontRequest): void {\n const originDomain =\n request.origin?.custom?.domainName ?? request.origin?.s3?.domainName ?? undefined;\n if (!originDomain) return;\n const currentHost = getHeader(request, 'host');\n if (!currentHost || currentHost === originDomain) return;\n if (!getHeader(request, 'x-forwarded-host')) {\n setHeader(request, 'X-Forwarded-Host', currentHost);\n }\n setHeader(request, 'Host', originDomain);\n}\n\n/** Full request URL as the origin will see it (scheme fixed to https). */\nexport function requestUrl(request: CloudFrontRequest, host: string): string {\n const qs = request.querystring ? `?${request.querystring}` : '';\n return `https://${host}${request.uri}${qs}`;\n}\n\n/**\n * Set a header on the origin-bound request (overwrites all prior values).\n */\nexport function setHeader(request: CloudFrontRequest, name: string, value: string): void {\n request.headers[name.toLowerCase()] = [{ key: name, value }];\n}\n\n/**\n * Strip every inbound header matching a prefix (lowercase compare). Used to\n * drop spoofed `x-astrasync-*` trust headers before the shell injects its\n * own — in BOTH modes, so a caller can never smuggle trust past the origin.\n */\nexport function stripHeadersByPrefix(request: CloudFrontRequest, prefix: string): void {\n const p = prefix.toLowerCase();\n for (const name of Object.keys(request.headers)) {\n if (name.startsWith(p)) delete request.headers[name];\n }\n}\n\nexport function jsonResponse(\n status: number,\n body: unknown,\n extraHeaders?: Record<string, string>\n): CloudFrontResultResponse {\n const headers: CloudFrontResultResponse['headers'] = {\n 'content-type': [{ key: 'Content-Type', value: 'application/json' }],\n };\n for (const [name, value] of Object.entries(extraHeaders ?? {})) {\n headers[name.toLowerCase()] = [{ key: name, value }];\n }\n return {\n status: String(status),\n statusDescription: status === 403 ? 'Forbidden' : status === 202 ? 'Accepted' : 'OK',\n headers,\n body: JSON.stringify(body),\n };\n}\n","/**\n * Runtime configuration for the edge shell.\n *\n * Lambda@Edge forbids environment variables, so configuration is layered:\n * 1. Build-time constants baked into the bundle (apiBaseUrl,\n * counterpartyId, counterpartyUrl, apiKeySecretName) — see\n * `tsup.config.ts` define block and `infra/deploy.sh`.\n * 2. The merchant API key from AWS Secrets Manager (us-east-1), fetched\n * lazily once per container and cached with a 15-minute TTL so\n * rotation needs no redeploy. Observe mode works fully without it —\n * the beacon endpoint is unauthenticated and verify() degrades\n * keyless — so a Secrets Manager outage can never take the shell down.\n * 3. The dashboard EdgeConfig via the SDK's getEdgeConfig (60s TTL,\n * stale-while-revalidate, enforce→observe degradation after 24h\n * staleness, DEFAULT_EDGE_CONFIG fallback — all in the SDK).\n */\n\nimport {\n getEdgeConfig,\n DEFAULT_EDGE_CONFIG,\n type EdgeConfig,\n} from '@astrasyncai/verification-gateway/edge-config';\nimport type { EdgeAdapterOptions } from './types';\n\nconst SECRET_TTL_MS = 15 * 60 * 1000;\n\ninterface SecretCacheEntry {\n value: string | undefined;\n fetchedAt: number;\n}\n\nconst secretCache = new Map<string, SecretCacheEntry>();\n\nasync function defaultFetchSecret(secretName: string): Promise<string | undefined> {\n // Lazy import so tests (and the library build) never touch the AWS SDK\n // unless a secret name is actually configured.\n const { SecretsManagerClient, GetSecretValueCommand } =\n await import('@aws-sdk/client-secrets-manager');\n // Lambda@Edge replicates globally but secrets live in us-east-1 (the\n // Lambda@Edge home region).\n const client = new SecretsManagerClient({ region: 'us-east-1' });\n const result = await client.send(new GetSecretValueCommand({ SecretId: secretName }));\n return result.SecretString ?? undefined;\n}\n\n/**\n * Resolve the merchant API key. Never throws — a missing/unreachable secret\n * degrades to keyless operation (observe mode is fully functional without\n * it; enforce mode without a key cannot fetch a config that enforces, so it\n * degrades to observe by construction).\n */\nexport async function resolveApiKey(options: EdgeAdapterOptions): Promise<string | undefined> {\n if (options.apiKey) return options.apiKey;\n const secretName = options.apiKeySecretName;\n if (!secretName) return undefined;\n\n const cached = secretCache.get(secretName);\n if (cached && Date.now() - cached.fetchedAt < SECRET_TTL_MS) return cached.value;\n\n try {\n const fetcher = options.fetchSecret ?? defaultFetchSecret;\n const value = await fetcher(secretName);\n secretCache.set(secretName, { value, fetchedAt: Date.now() });\n return value;\n } catch (err) {\n options.log?.('warn', 'Secrets Manager fetch failed — continuing keyless', {\n secretName,\n error: err instanceof Error ? err.message : String(err),\n });\n // Serve a stale value if we ever had one; otherwise keyless.\n return cached?.value;\n }\n}\n\n/**\n * Load the effective EdgeConfig. Delegates caching/fallback/degradation to\n * the SDK; adds the compile-time fallback override and never throws.\n */\nexport async function loadEdgeConfig(\n options: EdgeAdapterOptions,\n apiKey: string | undefined\n): Promise<EdgeConfig> {\n try {\n return await getEdgeConfig({ apiBaseUrl: options.apiBaseUrl, apiKey }, options.counterpartyId, {\n ttlMs: options.configTtlMs,\n });\n } catch {\n return options.fallbackConfig ?? DEFAULT_EDGE_CONFIG;\n }\n}\n\n/** Reset module caches — tests only. */\nexport function _resetConfigCaches(): void {\n secretCache.clear();\n}\n","/**\n * Three-tier traffic classification (§33.5 #1: verified /\n * identified-but-unregistered / anonymous) plus the two non-tiers the shell\n * touches as little as possible: `human` (zero network calls, zero logging)\n * and `skipped` (static assets / excluded paths).\n *\n * Cheapest checks first — the human path must add microseconds, not\n * milliseconds. Platform signatures come from the SDK so the edge and the\n * backend's verify-access anonymous handler classify identically.\n */\n\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport { extractCredentials } from '@astrasyncai/verification-gateway/verify';\nimport { detectPlatformFingerprint } from '@astrasyncai/verification-gateway/platform-signatures';\nimport { matchEdgePathRule, type EdgeConfig } from '@astrasyncai/verification-gateway/edge-config';\nimport { sanitizeHeaders } from '@astrasyncai/verification-gateway/metadata-capture';\nimport { getHeader, decodeBody, flattenHeaders } from './cf';\nimport { detectCommerce } from './detect';\nimport type { Classification, EffectivePolicy } from './types';\n\n/** Extensions the shell never classifies — static assets. */\nconst STATIC_EXTENSIONS =\n /\\.(css|js|mjs|map|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|mp4|webm|pdf|txt|xml)$/i;\n\n/** Non-browser, non-platform CLI/library UA tokens → anonymous bot. */\nconst BOT_UA_PATTERN =\n /curl|wget|python-requests|python-urllib|node-fetch|axios|got|okhttp|go-http-client|libwww|httpie|java\\/|ruby|php|scrapy|headless|phantomjs|selenium|playwright|puppeteer|bot|crawler|spider|slurp/i;\n\n/** Browser-shaped UA. */\nconst BROWSER_UA_PATTERN = /mozilla\\/\\d/i;\n\n/**\n * Resolve the effective mode/depth for a path from the EdgeConfig — ordered\n * first-match-wins rules with case-insensitive globs; no match falls through\n * to the config's top-level defaults. Static extensions are always skipped\n * regardless of rules (a rule can only skip MORE, never un-skip an asset).\n */\nexport function resolvePolicy(config: EdgeConfig, path: string): EffectivePolicy {\n if (STATIC_EXTENSIONS.test(path)) {\n return { mode: config.mode, depth: config.depth, skip: true };\n }\n const rule = matchEdgePathRule(config.pathRules, path);\n if (!rule) return { mode: config.mode, depth: config.depth, skip: false };\n return {\n mode: rule.mode ?? config.mode,\n depth: rule.depth ?? config.depth,\n skip: rule.skip === true,\n };\n}\n\n/**\n * Classify one request. Order (cheapest sufficient evidence wins):\n * 1. X-Astra-* credentials → `verified` candidate\n * 2. commerce-protocol credentials on the wire → `identified`\n * 3. platform UA fingerprint (Claude/ChatGPT/Gemini/…) → `identified`\n * 4. bot-shaped UA / headerless non-browser → `anonymous-bot`\n * 5. everything browser-shaped → `human`\n *\n * `depth: 'classify'` skips step 2 (no body decode, no header sniffing\n * beyond UA) — that is the zero-friction setting.\n */\nexport function classify(\n request: CloudFrontRequest,\n host: string,\n depth: 'classify' | 'authenticate' | 'authorize'\n): Classification {\n const userAgent = getHeader(request, 'user-agent') ?? '';\n const flat = flattenHeaders(request.headers);\n\n // 1. Native AstraSync credentials.\n const credentials = extractCredentials(flat, {});\n if (credentials.astraId || credentials.apiKey || credentials.jwt) {\n return { tier: 'verified', protocol: 'x-astra' };\n }\n\n // Workstream D — the key-format prefix + platform-signal headers are stronger,\n // less-spoofable platform signals than the UA. Compute once (cheap string\n // work) and feed every fingerprint call below.\n const { apiKeyFormat, platformHeaders } = sanitizeHeaders(flat);\n const detectionInput = { userAgent, apiKeyFormat, platformHeaders };\n\n // 2. Commerce-protocol credentials (skipped entirely at classify depth).\n if (depth !== 'classify') {\n const commerce = detectCommerce(request, host, decodeBody(request));\n if (commerce) {\n return {\n tier: 'identified',\n protocol: commerce.protocol,\n artifacts: commerce.artifacts,\n evidence: commerce.evidence,\n fingerprint: detectPlatformFingerprint(detectionInput),\n };\n }\n }\n\n // 3. Platform-agent fingerprint (UA, key-format, or platform header).\n const fingerprint = detectPlatformFingerprint(detectionInput);\n if (fingerprint) {\n return { tier: 'identified', protocol: 'platform-ua', fingerprint };\n }\n\n // 4. Bot-shaped: CLI/library UA, no UA at all, or any non-browser UA —\n // humans arrive with Mozilla-family UAs; everything else is automation.\n if (!userAgent || BOT_UA_PATTERN.test(userAgent) || !BROWSER_UA_PATTERN.test(userAgent)) {\n return { tier: 'anonymous-bot', evidence: { userAgent: userAgent || '(none)' } };\n }\n\n // 4b. Claims to be a browser but is missing every browser fetch-metadata\n // header — headless/spoofed. `sec-fetch-mode` is sent by all evergreen\n // browsers; its absence on a Mozilla UA is a strong bot signal.\n if (!getHeader(request, 'sec-fetch-mode') && !getHeader(request, 'accept-language')) {\n return { tier: 'anonymous-bot', evidence: { userAgent, spoofedBrowser: true } };\n }\n\n // 5. Human traffic — the shell gets out of the way.\n return { tier: 'human' };\n}\n\n/** Exported for tests. */\nexport const _patterns = { STATIC_EXTENSIONS, BOT_UA_PATTERN, BROWSER_UA_PATTERN };\n","/**\n * Crypto-free commerce-protocol detection (§7.4.2 detection order).\n *\n * The edge only SNIFFS — header shapes, compact-JWT patterns, body field\n * names — and packages what it saw as raw `CommerceArtifactsPayload` for\n * verify-access, whose Step 0.5 pipeline does the authoritative parsing and\n * cryptographic verification server-side. Nothing here imports jose/sd-jwt/\n * signature libraries: detection must stay cheap enough to run on every\n * non-human request, and verification must happen exactly once, in the\n * canonical sink, where it is recorded.\n */\n\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport type { CommerceArtifactsPayload } from '@astrasyncai/verification-gateway';\nimport { flattenHeaders, getHeader, requestUrl, type DecodedBody } from './cf';\n\nexport interface DetectedCommerce {\n /** Detection-order label: rfc9421-agent-pay | rfc9421-tap | rfc9421-web-bot-auth | vi-sd-jwt | ap2 | acp | ucp | mpp | x402 */\n protocol: string;\n artifacts: CommerceArtifactsPayload;\n /** Light detection detail for beacons/audit — never secrets or full credentials. */\n evidence: Record<string, unknown>;\n}\n\n/** Compact SD-JWT: JWT + `~`-separated disclosures. */\nconst SD_JWT_PATTERN = /^eyJ[\\w-]+\\.[\\w-]*\\.[\\w-]+~/;\n\n/** Decode a JWT header segment without verifying anything. */\nfunction sniffJwtHeader(compact: string): Record<string, unknown> | undefined {\n try {\n const seg = compact.split('.')[0];\n return JSON.parse(Buffer.from(seg, 'base64url').toString('utf8')) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n}\n\nfunction parseJsonBody(body: DecodedBody): Record<string, unknown> | undefined {\n if (!body.text) return undefined;\n try {\n const parsed: unknown = JSON.parse(body.text);\n return typeof parsed === 'object' && parsed !== null\n ? (parsed as Record<string, unknown>)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * §7.4.2 order (after the X-Astra native check, which classify.ts owns):\n * SD-JWT/VI → RFC 9421 (Agent Pay / TAP / Web Bot Auth by kid namespace or\n * Signature-Agent) → ACP HMAC → UCP session → AP2 body triple → MPP → x402.\n * Returns undefined when nothing commerce-shaped is on the wire.\n *\n * When the body was truncated by CloudFront (`inputTruncated`), body-bound\n * artifacts still forward what arrived but carry a `bodyTruncated` evidence\n * flag — the backend downgrades those signatures rather than hard-failing.\n */\nexport function detectCommerce(\n request: CloudFrontRequest,\n host: string,\n body: DecodedBody\n): DetectedCommerce | undefined {\n const url = requestUrl(request, host);\n const method = request.method;\n const headers = flattenHeaders(request.headers);\n const jsonBody = parseJsonBody(body);\n const truncated = body.truncated ? { bodyTruncated: true } : {};\n\n // --- VI / SD-JWT credential in a header ------------------------------\n const authHeader = getHeader(request, 'authorization');\n const bearer = authHeader?.replace(/^Bearer\\s+/i, '');\n const mandateHeader =\n getHeader(request, 'x-payment-mandate') ?? getHeader(request, 'payment-mandate');\n const sdJwtCandidate = [mandateHeader, bearer].find((v) => v && SD_JWT_PATTERN.test(v));\n if (sdJwtCandidate) {\n const typ = sniffJwtHeader(sdJwtCandidate)?.typ;\n return {\n protocol: 'vi-sd-jwt',\n artifacts: { viSdJwt: sdJwtCandidate },\n evidence: { typ, ...truncated },\n };\n }\n\n // --- RFC 9421 (Agent Pay / TAP / Web Bot Auth) ------------------------\n const signature = getHeader(request, 'signature');\n const signatureInput = getHeader(request, 'signature-input');\n if (signature && signatureInput) {\n const signatureAgent = getHeader(request, 'signature-agent');\n const registryHint = getHeader(request, 'x-agent-registry');\n const lowerInput = signatureInput.toLowerCase();\n const protocol = signatureAgent\n ? 'rfc9421-web-bot-auth'\n : registryHint?.toLowerCase().includes('visa') || lowerInput.includes('visa')\n ? 'rfc9421-tap'\n : registryHint?.toLowerCase().includes('mastercard') || lowerInput.includes('mastercard')\n ? 'rfc9421-agent-pay'\n : 'rfc9421';\n return {\n protocol,\n artifacts: {\n rfc9421: { headers, method, url, ...(body.text && { body: body.text }) },\n },\n evidence: {\n ...(signatureAgent && { signatureAgent }),\n ...(registryHint && { registryHint }),\n keyid: signatureInput.match(/keyid=\"([^\"]+)\"/)?.[1],\n ...truncated,\n },\n };\n }\n\n // --- ACP (HMAC-signed webhook/checkout: signature WITHOUT signature-input)\n const acpTimestamp = getHeader(request, 'timestamp');\n if (signature && !signatureInput && (acpTimestamp || getHeader(request, 'idempotency-key'))) {\n return {\n protocol: 'acp',\n artifacts: {\n acpRequest: {\n method,\n url,\n headers,\n ...(body.text && { rawBody: body.text }),\n ...(jsonBody && { body: jsonBody }),\n },\n },\n evidence: { hasTimestamp: Boolean(acpTimestamp), ...truncated },\n };\n }\n\n // --- UCP checkout session ---------------------------------------------\n if (/\\/checkout[-_]sessions(\\/|$)/.test(request.uri)) {\n return {\n protocol: 'ucp',\n artifacts: { ucpRequest: { method, url, ...(jsonBody && { body: jsonBody }) } },\n evidence: { path: request.uri, ...truncated },\n };\n }\n\n // --- AP2 mandate triple in the body -----------------------------------\n if (jsonBody) {\n const intent = jsonBody.intent_mandate ?? jsonBody.intentMandate;\n const cart = jsonBody.cart_mandate ?? jsonBody.cartMandate;\n const payment = jsonBody.payment_mandate ?? jsonBody.paymentMandate;\n if (typeof intent === 'string' || typeof cart === 'string' || typeof payment === 'string') {\n return {\n protocol: 'ap2',\n artifacts: {\n ap2Mandates: {\n ...(typeof intent === 'string' && { intent }),\n ...(typeof cart === 'string' && { cart }),\n ...(typeof payment === 'string' && { payment }),\n },\n },\n evidence: {\n mandatesPresent: [\n typeof intent === 'string' && 'intent',\n typeof cart === 'string' && 'cart',\n typeof payment === 'string' && 'payment',\n ].filter(Boolean),\n ...truncated,\n },\n };\n }\n }\n\n // --- MPP (`Authorization: Payment <credential>`) -----------------------\n if (authHeader && /^Payment\\s+/i.test(authHeader)) {\n return {\n protocol: 'mpp',\n artifacts: {\n mppRequest: {\n method,\n url,\n headers,\n ...(body.text && { rawBody: body.text }),\n ...(jsonBody && { body: jsonBody }),\n },\n },\n evidence: truncated,\n };\n }\n\n // --- x402 (X-PAYMENT header) ------------------------------------------\n if (getHeader(request, 'x-payment')) {\n return {\n protocol: 'x402',\n artifacts: {\n x402Request: { method, url, headers, ...(jsonBody && { body: jsonBody }) },\n },\n evidence: truncated,\n };\n }\n\n return undefined;\n}\n","/**\n * Depth-controlled verification per tier. The edge never verifies\n * credentials itself — it forwards what it detected to verify-access, the\n * canonical sole verification sink (backend Step 0.5 runs the commerce\n * pipeline, records events, provisions orphans, persists sessions). What\n * the depth setting controls is how much the edge LOOKS and how much it\n * FORWARDS:\n *\n * classify — what is it? UA tiers only. Zero verify-access calls;\n * beacons only.\n * authenticate — who is it? + protocol detection. X-Astra agents get a\n * verify-access identity check; commerce/platform traffic\n * is beaconed with protocol + evidence (no signature\n * verification anywhere).\n * authorize — are they allowed? + artifact forwarding. X-Astra verify\n * calls carry commerceArtifacts; identified traffic gets an\n * anonymous verify-access call with artifacts +\n * callerMetadata so the backend cryptographically proves\n * and policy-evaluates once.\n */\n\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport { verify, extractCredentials } from '@astrasyncai/verification-gateway/verify';\nimport { resolveHttpPdlss } from '@astrasyncai/verification-gateway/http-pdlss';\nimport type { GatewayConfig, VerificationRequest } from '@astrasyncai/verification-gateway';\nimport { flattenHeaders, getHeader, buildObservedMetadata } from './cf';\nimport { withBudget, emitBeacon, sampled } from './events';\nimport type { Classification, EdgeAdapterOptions, EffectivePolicy, TierOutcome } from './types';\n\nfunction baseOutcome(classification: Classification): TierOutcome {\n return {\n tier: classification.tier,\n decision: 'allow',\n reasons: [],\n protocol: classification.protocol,\n };\n}\n\nfunction buildVerificationRequest(\n options: EdgeAdapterOptions,\n request: CloudFrontRequest,\n classification: Classification,\n includeArtifacts: boolean\n): VerificationRequest {\n const headers = flattenHeaders(request.headers);\n const clientIp = getHeader(request, 'cloudfront-viewer-address')?.split(':')[0];\n // verify-access REQUIRES a purpose. Resolve via the shared §4.6 chain:\n // the agent's X-Astra-Purpose/-Action declarations, else the pinned\n // method table (GET → data/data.read etc.) — a transport verb never\n // travels as a PDLSS action.\n const pdlss = resolveHttpPdlss({\n method: request.method,\n astraPurpose: getHeader(request, 'x-astra-purpose'),\n astraAction: getHeader(request, 'x-astra-action'),\n });\n // Trust Record (§33.5 #3): forward the caller's attempt-chain handle when\n // well-formed (agent-declared, like x-astra-purpose — not a trust header,\n // so no spoof-strip needed). The edge synthesises NO consideration data —\n // it can't see offer semantics; pure pass-through.\n const attemptId = getHeader(request, 'x-astra-attempt-id');\n return {\n ...(attemptId && /^att_[0-9a-f]{32}$/.test(attemptId) && { attemptId }),\n credentials: extractCredentials(headers, {}),\n purpose: pdlss.purpose,\n action: pdlss.action,\n resource: request.uri,\n createSession: true,\n counterpartyType: 'website',\n counterpartyUrl: options.counterpartyUrl,\n callerMetadata: {\n sourceIp: clientIp,\n userAgent: getHeader(request, 'user-agent'),\n referer: getHeader(request, 'referer'),\n host: getHeader(request, 'host'),\n // Workstream D — the full sanitised header + connection capture. The\n // backend stores it fire-and-forget (zero decision latency) and uses the\n // key-format / platform headers for attribution.\n observedMetadata: buildObservedMetadata(request),\n },\n ...(includeArtifacts &&\n classification.artifacts && { commerceArtifacts: classification.artifacts }),\n };\n}\n\nfunction outcomeFromVerifyResult(\n classification: Classification,\n result: Awaited<ReturnType<typeof verify>>\n): TierOutcome {\n const outcome = baseOutcome(classification);\n outcome.sessionId = (result as { sessionId?: string }).sessionId;\n outcome.correlationId = result.correlationId;\n outcome.guidance = result.guidance;\n\n // 2.0.0 BREAKING (enforce-mode semantic): the PROPERTY'S own API key was\n // rejected by the backend — neither an agent deny nor an infra failure.\n // Fail OPEN in both modes: agents must not be blocked by the property's\n // dead key. The misconfig flag stamps X-AstraSync-Observed-Decision so\n // origin logs surface it; the owner is alerted server-side\n // (api_key.dead_key_in_use) on every rejected call.\n if (result.misconfigured) {\n outcome.reasons = ['verification key misconfigured — fail-open (merchant_misconfig)'];\n outcome.misconfig = true;\n return outcome;\n }\n\n if (result.requiresStepUp || result.stepUpApproval) {\n outcome.decision = 'manual_review';\n outcome.reasons = ['step-up approval required'];\n outcome.stepUp = {\n pollUrl: (result.stepUpApproval as { pollUrl?: string } | undefined)?.pollUrl,\n expiresAt: (result.stepUpApproval as { expiresAt?: string } | undefined)?.expiresAt,\n };\n return outcome;\n }\n\n if (!result.identityVerified || !result.policyAllowed) {\n outcome.decision = 'deny';\n outcome.reasons = result.denialReasons?.length\n ? result.denialReasons\n : [!result.identityVerified ? 'identity not verified' : 'denied by access policy'];\n return outcome;\n }\n\n outcome.asat = {\n trustScore: result.agent?.trustScore,\n agentId: result.agent?.astraId,\n developerId: result.developer?.astradId,\n accessLevel: result.accessLevel,\n };\n return outcome;\n}\n\n/**\n * Run the tier-appropriate verification/telemetry for one classified\n * request. NEVER throws; on any failure returns an `allow` outcome with the\n * failure recorded in `reasons` (infra failures fail open — a presented\n * credential the BACKEND rejected is a deny, but an unreachable backend is\n * not a rejection).\n */\nexport async function runTier(\n options: EdgeAdapterOptions,\n request: CloudFrontRequest,\n classification: Classification,\n policy: EffectivePolicy,\n apiKey: string | undefined,\n sampling: { anonymousBeaconRate: number }\n): Promise<TierOutcome> {\n const budgets = options.budgets ?? {};\n const beaconMs = budgets.beaconMs ?? 300;\n const verifyMs =\n policy.mode === 'enforce'\n ? (budgets.verifyEnforceMs ?? 3000)\n : (budgets.verifyObserveMs ?? 1500);\n\n const gatewayConfig: GatewayConfig = {\n apiBaseUrl: options.apiBaseUrl,\n ...(apiKey && { apiKey }),\n counterpartyId: options.counterpartyId,\n // The shell handles its own error semantics; init self-probes don't\n // belong in a per-request edge function.\n disableInitChecks: true,\n } as GatewayConfig;\n\n try {\n switch (classification.tier) {\n case 'verified': {\n // classify depth = zero API calls, even for credentialed agents.\n if (policy.depth === 'classify') {\n return baseOutcome(classification);\n }\n const result = await withBudget(\n verify(\n gatewayConfig,\n buildVerificationRequest(options, request, classification, policy.depth === 'authorize')\n ),\n verifyMs\n );\n if (!result) {\n const outcome = baseOutcome(classification);\n outcome.reasons = ['verify-access unreachable within budget — fail-open'];\n return outcome;\n }\n return outcomeFromVerifyResult(classification, result);\n }\n\n case 'identified': {\n if (policy.depth === 'authorize' && classification.artifacts) {\n // Anonymous verify-access call WITH artifacts: the backend runs\n // the commerce pipeline, records unverified events, and\n // provisions orphan platform agents — one sink, recorded once.\n const result = await withBudget(\n verify(gatewayConfig, buildVerificationRequest(options, request, classification, true)),\n verifyMs\n );\n if (!result) {\n const outcome = baseOutcome(classification);\n outcome.reasons = ['verify-access unreachable within budget — fail-open'];\n return outcome;\n }\n return outcomeFromVerifyResult(classification, result);\n }\n // classify/credentials depth (or no artifacts): lightweight beacon.\n await emitBeacon(options, request, classification, beaconMs);\n const outcome = baseOutcome(classification);\n if (policy.mode === 'enforce' && policy.depth !== 'classify') {\n // Unregistered agent on an enforced path: deny with guidance.\n outcome.decision = 'deny';\n outcome.reasons = ['agent is not registered with AstraSync'];\n }\n return outcome;\n }\n\n case 'anonymous-bot': {\n if (sampled(sampling.anonymousBeaconRate, options.random)) {\n await emitBeacon(\n options,\n request,\n { ...classification, protocol: classification.protocol ?? 'ua-heuristic' },\n beaconMs\n );\n }\n // Anonymous bots pass through even in enforce mode — enforce gates\n // AGENT traffic; generic bot management stays the CDN/WAF's job\n // (mixed-traffic classification §5.1.7 is the enforce-mode\n // prerequisite tracked as §33.5 #9).\n return baseOutcome(classification);\n }\n\n default:\n return baseOutcome(classification);\n }\n } catch (err) {\n const outcome = baseOutcome(classification);\n outcome.reasons = [\n `edge pipeline error — fail-open: ${err instanceof Error ? err.message : String(err)}`,\n ];\n return outcome;\n }\n}\n","/**\n * Time-budgeted event emission.\n *\n * Lambda@Edge has no `waitUntil` — anything not awaited before the handler\n * returns may never run (the container freezes). So every network call is\n * awaited under an explicit budget and DROPPED on timeout: latency to the\n * customer's traffic is bounded, and a slow AstraSync API costs telemetry,\n * never page loads.\n */\n\nimport { reportUnregisteredAttempt } from '@astrasyncai/verification-gateway/verify';\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport { getHeader, buildObservedMetadata } from './cf';\nimport type { Classification, EdgeAdapterOptions } from './types';\n\n/** Await `promise` for at most `ms`; resolve `undefined` on timeout/error. */\nexport async function withBudget<T>(promise: Promise<T>, ms: number): Promise<T | undefined> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<undefined>((resolve) => {\n timer = setTimeout(() => resolve(undefined), ms);\n }),\n ]);\n } catch {\n return undefined;\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\n/**\n * Emit an unregistered-attempt beacon for `identified` (non-crypto depths)\n * and sampled `anonymous-bot` traffic. Unauthenticated by design\n * (CSRF-exempt on the backend); the backend fingerprints the UA and\n * find-or-provisions orphan platform agents server-side.\n */\nexport async function emitBeacon(\n options: EdgeAdapterOptions,\n request: CloudFrontRequest,\n classification: Classification,\n budgetMs: number\n): Promise<void> {\n const clientIp = getHeader(request, 'cloudfront-viewer-address')?.split(':')[0];\n await withBudget(\n reportUnregisteredAttempt(\n { apiBaseUrl: options.apiBaseUrl, counterpartyId: options.counterpartyId },\n {\n counterpartyUrl: options.counterpartyUrl,\n counterpartyType: 'website',\n sourceIp: clientIp,\n userAgent: getHeader(request, 'user-agent'),\n requestPath: request.uri,\n requestMethod: request.method,\n // 3.9.0 evidence fields (backend persists them into eventData).\n protocol: classification.protocol,\n evidence: classification.evidence,\n // Workstream D — full sanitised header + connection capture for the\n // unregistered caller (fire-and-forget, so free).\n observedMetadata: buildObservedMetadata(request),\n }\n ),\n budgetMs\n );\n}\n\n/** Deterministic-in-tests sampling gate. */\nexport function sampled(rate: number, random: () => number = Math.random): boolean {\n if (rate <= 0) return false;\n if (rate >= 1) return true;\n return random() < rate;\n}\n","/**\n * §7.4.6 — protocol-specific machine-readable messaging for enforce-mode\n * responses. Agents (not humans) consume these bodies: stable error codes,\n * the failure list, and registration guidance with real URLs.\n */\n\nimport type { TierOutcome } from './types';\n\nconst PROTOCOL_MESSAGES: Record<string, string> = {\n 'vi-sd-jwt':\n 'This request presented Visa Intelligent Commerce credentials, but the agent is not verified with AstraSync. Register the agent to pair your VI credentials with a verified identity and mandate.',\n 'rfc9421-agent-pay':\n 'This request carried a Mastercard Agent Pay signature, but the agent is not verified with AstraSync. Register the agent to pair Agent Pay credentials with a verified identity and mandate.',\n 'rfc9421-tap':\n 'This request carried a Visa TAP signature, but the agent is not verified with AstraSync. Register the agent to pair TAP credentials with a verified identity and mandate.',\n 'rfc9421-web-bot-auth':\n 'This request carried a Web Bot Auth signature, but the agent is not verified with AstraSync. Register the agent to link your signed-agent identity to a verified principal.',\n rfc9421:\n 'This request carried an RFC 9421 HTTP message signature, but the agent is not verified with AstraSync. Register the agent to link the signing identity to a verified principal.',\n acp: 'This request used the Agentic Commerce Protocol, but the agent is not verified with AstraSync. Register the agent to transact on this property.',\n ucp: 'This request used a UCP checkout session, but the agent is not verified with AstraSync. Register the agent to transact on this property.',\n ap2: 'This request presented AP2 mandates, but the agent is not verified with AstraSync. Register the agent to pair your mandates with a verified identity.',\n mpp: 'This request presented MPP payment credentials, but the agent is not verified with AstraSync. Register the agent to transact on this property.',\n x402: 'This request used x402 payment headers, but the agent is not verified with AstraSync. Register the agent to transact on this property.',\n 'platform-ua':\n 'This traffic was identified as a platform AI agent without AstraSync credentials. Register the agent to access this property with a verified identity.',\n 'x-astra':\n 'The presented AstraSync credentials failed verification or were denied by this property’s access policy.',\n};\n\nexport interface DenyBody {\n success: false;\n error: {\n code: 'UNAUTHORIZED' | 'INSUFFICIENT_ACCESS';\n message: string;\n protocol?: string;\n failures: string[];\n correlationId?: string;\n guidance: {\n message?: string;\n registrationUrl?: string;\n documentationUrl?: string;\n };\n };\n}\n\nexport function buildDenyBody(outcome: TierOutcome, apiBaseUrl: string): DenyBody {\n const origin = apiBaseUrl.replace(/\\/api\\/?$/, '');\n const protocolMessage =\n (outcome.protocol && PROTOCOL_MESSAGES[outcome.protocol]) ??\n 'This request could not be verified by AstraSync.';\n return {\n success: false,\n error: {\n // UNAUTHORIZED = identity failed (register/re-authenticate helps);\n // INSUFFICIENT_ACCESS = identity fine, policy denied (fix the mandate).\n code: outcome.tier === 'verified' ? 'INSUFFICIENT_ACCESS' : 'UNAUTHORIZED',\n message: protocolMessage,\n ...(outcome.protocol && { protocol: outcome.protocol }),\n failures: outcome.reasons,\n ...(outcome.correlationId && { correlationId: outcome.correlationId }),\n guidance: {\n // `||` not `??`: verify() fills these with EMPTY STRINGS when the\n // well-known cache is cold — empty means \"use the fallback\".\n message:\n outcome.guidance?.message ||\n 'Register this agent with AstraSync to receive verifiable credentials.',\n registrationUrl: outcome.guidance?.registrationUrl || `${origin}/register`,\n documentationUrl: outcome.guidance?.documentationUrl || `${origin}/docs/edge-adapter`,\n },\n },\n };\n}\n\nexport interface ManualReviewBody {\n success: false;\n status: 'manual_review';\n message: string;\n stepUpApproval?: { pollUrl?: string; expiresAt?: string };\n correlationId?: string;\n}\n\nexport function buildManualReviewBody(outcome: TierOutcome): ManualReviewBody {\n return {\n success: false,\n status: 'manual_review',\n message:\n 'This action requires human approval. Poll the step-up approval endpoint and retry once approved.',\n ...(outcome.stepUp && { stepUpApproval: outcome.stepUp }),\n ...(outcome.correlationId && { correlationId: outcome.correlationId }),\n };\n}\n","/**\n * Decision → CloudFront result wiring (§7.4 enforcement, §7.4.7 ASAT\n * headers). Executed in BOTH modes so observe mode records exactly what\n * enforce mode would have done — but only enforce mode is allowed to return\n * anything other than the origin-bound request.\n */\n\nimport type { CloudFrontRequest, CloudFrontRequestResult } from 'aws-lambda';\nimport { jsonResponse, setHeader, stripHeadersByPrefix } from './cf';\nimport { buildDenyBody, buildManualReviewBody } from './messaging';\nimport type { EdgeAdapterOptions, EffectivePolicy, TierOutcome } from './types';\n\n/** §7.4.7 ASAT trust-attestation headers injected on allowed requests. */\nexport const ASAT_HEADERS = {\n trustScore: 'X-AstraSync-Trust-Score',\n agentId: 'X-AstraSync-Agent-Id',\n developerId: 'X-AstraSync-Developer-Id',\n permissions: 'X-AstraSync-Permissions',\n observedDecision: 'X-AstraSync-Observed-Decision',\n} as const;\n\n/**\n * Apply the outcome. Always strips inbound spoofed `x-astrasync-*` headers\n * first (both modes — trust headers must only ever originate here).\n *\n * Observe mode: returns the request untouched apart from header hygiene and\n * an `X-AstraSync-Observed-Decision` stamp for origin-side log correlation.\n *\n * Enforce mode: ALLOW → request + ASAT headers; DENY → 403 machine-readable\n * body; MANUAL_REVIEW → 202 with step-up poll info.\n */\nexport function applyOutcome(\n options: EdgeAdapterOptions,\n request: CloudFrontRequest,\n outcome: TierOutcome,\n policy: EffectivePolicy\n): CloudFrontRequestResult {\n stripHeadersByPrefix(request, 'x-astrasync-');\n\n // 2.0.0: surface a rejected property key in origin logs in BOTH modes —\n // the outcome is allow (fail-open) so the deny stamp below never fires.\n if (outcome.misconfig) {\n setHeader(request, ASAT_HEADERS.observedDecision, 'misconfig');\n }\n\n if (policy.mode !== 'enforce') {\n // Shadow stamp: what enforce WOULD have done, visible in origin logs.\n if (outcome.decision !== 'allow') {\n setHeader(request, ASAT_HEADERS.observedDecision, outcome.decision);\n }\n injectAsat(request, outcome);\n return request;\n }\n\n switch (outcome.decision) {\n case 'deny':\n return jsonResponse(403, buildDenyBody(outcome, options.apiBaseUrl));\n case 'manual_review':\n return jsonResponse(202, buildManualReviewBody(outcome), {\n 'Retry-After': '30',\n });\n default:\n injectAsat(request, outcome);\n return request;\n }\n}\n\nfunction injectAsat(request: CloudFrontRequest, outcome: TierOutcome): void {\n if (!outcome.asat) return;\n const { trustScore, agentId, developerId, accessLevel } = outcome.asat;\n if (trustScore !== undefined) {\n setHeader(request, ASAT_HEADERS.trustScore, String(trustScore));\n }\n if (agentId) setHeader(request, ASAT_HEADERS.agentId, agentId);\n if (developerId) setHeader(request, ASAT_HEADERS.developerId, developerId);\n if (accessLevel) setHeader(request, ASAT_HEADERS.permissions, accessLevel);\n}\n","/**\n * Commerce Shield edge shell — Lambda@Edge origin-request handler factory\n * (§7.4 / §33.5 #1).\n *\n * Composition per request:\n * config (cached) → path policy → classify → tier pipeline → apply outcome\n *\n * THE invariant (tested): outside enforce mode the handler ALWAYS returns\n * the origin-bound request — any error, timeout, or misconfiguration\n * results in pass-through. A top-level catch guarantees it even against\n * bugs in the shell itself.\n */\n\nimport type { CloudFrontRequestEvent, CloudFrontRequestResult } from 'aws-lambda';\nimport { getRequest, getHeader, normalizeOriginHost } from './cf';\nimport { resolveApiKey, loadEdgeConfig } from './config';\nimport { classify, resolvePolicy } from './classify';\nimport { runTier } from './pipeline';\nimport { applyOutcome } from './enforce';\nimport type { EdgeAdapterOptions } from './types';\n\nexport type EdgeHandler = (event: CloudFrontRequestEvent) => Promise<CloudFrontRequestResult>;\n\nexport function createEdgeHandler(options: EdgeAdapterOptions): EdgeHandler {\n const log =\n options.log ??\n ((level, message, data) => {\n // Lambda@Edge writes console output to the regional CloudWatch log\n // group of whichever edge location served the request.\n console[level === 'info' ? 'log' : level](`[astrasync-edge] ${message}`, data ?? '');\n });\n\n return async function handler(event) {\n const request = getRequest(event);\n try {\n // Own the Host rewrite (Workstream D): the CloudFront-Viewer-* capture\n // requires an origin-request policy that also forwards the viewer Host,\n // so the shell restores origin-domain Host + X-Forwarded-Host itself.\n // Runs first so EVERY origin-bound return (skip / human / allow) is\n // correctly routed.\n normalizeOriginHost(request);\n\n const apiKey = await resolveApiKey({ ...options, log });\n const config = await loadEdgeConfig(options, apiKey);\n const policy = resolvePolicy(config, request.uri);\n\n // Skipped paths (static assets / skip rules): untouched, zero work.\n if (policy.skip) return request;\n\n const host =\n getHeader(request, 'x-forwarded-host') ??\n getHeader(request, 'host') ??\n new URL(options.counterpartyUrl).host;\n\n const classification = classify(request, host, policy.depth);\n\n // Humans: get out of the way. No calls, no logs, no header changes\n // beyond nothing at all.\n if (classification.tier === 'human') return request;\n\n const outcome = await runTier(\n { ...options, log },\n request,\n classification,\n policy,\n apiKey,\n config.sampling\n );\n\n if (outcome.decision !== 'allow') {\n log(\n 'info',\n policy.mode === 'enforce'\n ? `${outcome.decision.toUpperCase()}: ${request.method} ${request.uri}`\n : `[OBSERVE] would have been ${outcome.decision.toUpperCase()}: ${request.method} ${request.uri}`,\n { tier: outcome.tier, protocol: outcome.protocol, reasons: outcome.reasons }\n );\n }\n\n return applyOutcome(options, request, outcome, policy);\n } catch (err) {\n // Fail-open, unconditionally: the shell must never take the site down.\n log('error', 'edge handler error — passing request through', {\n error: err instanceof Error ? err.message : String(err),\n });\n return request;\n }\n };\n}\n"],"mappings":"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","names":["import_edge_config","import_metadata_capture","import_verify","import_verify","outcome"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/handler.ts","../src/cf.ts","../src/config.ts","../src/classify.ts","../src/detect.ts","../src/pipeline.ts","../src/enforce.ts","../src/messaging.ts","../src/events.ts"],"sourcesContent":["/**\n * @astrasyncai/adapter-lambda — AstraSync Trusted Agent Gateway,\n * CloudFront/Lambda@Edge adapter.\n *\n * Library surface: `createEdgeHandler(options)` builds a Lambda@Edge\n * origin-request handler. The deployable single-file bundle lives at\n * `dist/lambda/index.js` (see `src/lambda-entry.ts` + `infra/`).\n */\n\nexport { createEdgeHandler, type EdgeHandler } from './handler';\nexport { classify, resolvePolicy } from './classify';\nexport { detectCommerce, type DetectedCommerce } from './detect';\nexport { runTier } from './pipeline';\nexport { applyOutcome, ASAT_HEADERS } from './enforce';\nexport { buildDenyBody, buildManualReviewBody } from './messaging';\nexport { emitBeacon, withBudget, sampled } from './events';\nexport { resolveApiKey, loadEdgeConfig, _resetConfigCaches } from './config';\nexport {\n getRequest,\n getHeader,\n flattenHeaders,\n decodeBody,\n requestUrl,\n setHeader,\n stripHeadersByPrefix,\n jsonResponse,\n} from './cf';\nexport type {\n EdgeAdapterOptions,\n Classification,\n TrafficTier,\n TierOutcome,\n EdgeDecision,\n EffectivePolicy,\n} from './types';\n","/**\n * Trusted Agent Gateway edge shell — Lambda@Edge origin-request handler\n * factory.\n *\n * Composition per request:\n * config (cached) → edge core evaluation (path policy → classify → tier\n * pipeline) → apply outcome onto the CloudFront request\n *\n * THE invariant (tested): outside enforce mode the handler ALWAYS returns\n * the origin-bound request — any error, timeout, or misconfiguration\n * results in pass-through. A top-level catch guarantees it even against\n * bugs in the shell itself.\n */\n\nimport type { CloudFrontRequestEvent, CloudFrontRequestResult } from 'aws-lambda';\nimport { evaluateEdgeRequest } from '@astrasyncai/verification-gateway/edge-core';\nimport { getRequest, normalizeOriginHost, toNormalizedRequest, applyCoreOutcome } from './cf';\nimport { resolveApiKey, loadEdgeConfig } from './config';\nimport type { EdgeAdapterOptions } from './types';\n\nexport type EdgeHandler = (event: CloudFrontRequestEvent) => Promise<CloudFrontRequestResult>;\n\nexport function createEdgeHandler(options: EdgeAdapterOptions): EdgeHandler {\n const log =\n options.log ??\n ((level, message, data) => {\n // Lambda@Edge writes console output to the regional CloudWatch log\n // group of whichever edge location served the request.\n console[level === 'info' ? 'log' : level](`[astrasync-edge] ${message}`, data ?? '');\n });\n\n return async function handler(event) {\n const request = getRequest(event);\n try {\n // Own the Host rewrite (metadata capture): the CloudFront-Viewer-* capture\n // requires an origin-request policy that also forwards the viewer Host,\n // so the shell restores origin-domain Host + X-Forwarded-Host itself.\n // Runs first so EVERY origin-bound return (skip / human / allow) is\n // correctly routed — and so the normalized request the core sees\n // already carries the viewer host in X-Forwarded-Host.\n normalizeOriginHost(request);\n\n const apiKey = await resolveApiKey({ ...options, log });\n const config = await loadEdgeConfig(options, apiKey);\n\n const { application } = await evaluateEdgeRequest(\n { ...options, log },\n toNormalizedRequest(request),\n config,\n apiKey\n );\n\n return applyCoreOutcome(request, application);\n } catch (err) {\n // Fail-open, unconditionally: the shell must never take the site down.\n log('error', 'edge handler error — passing request through', {\n error: err instanceof Error ? err.message : String(err),\n });\n return request;\n }\n };\n}\n","/**\n * CloudFront platform I/O — the Lambda@Edge side of the edge core's\n * PlatformIo contract, plus origin-request event helpers.\n *\n * The Lambda@Edge event shape puts headers in `{ key, value }[]` arrays\n * keyed by LOWERCASED header name, and (with IncludeBody) the body arrives\n * base64-encoded with an `inputTruncated` flag when it exceeded\n * CloudFront's ~1MB exposure cap. `toNormalizedRequest` converts that into\n * the core's NormalizedRequest; `applyCoreOutcome` executes the core's\n * abstract outcome application against the CloudFront request/response\n * primitives.\n */\n\nimport type {\n CloudFrontRequest,\n CloudFrontRequestEvent,\n CloudFrontRequestResult,\n CloudFrontHeaders,\n CloudFrontResultResponse,\n} from 'aws-lambda';\nimport type {\n NormalizedRequest,\n OutcomeApplication,\n} from '@astrasyncai/verification-gateway/edge-core';\nimport { buildObservedMetadata as buildObservedMetadataCore } from '@astrasyncai/verification-gateway/edge-core';\nimport type { ObservedMetadata } from '@astrasyncai/verification-gateway/metadata-capture';\n\nexport function getRequest(event: CloudFrontRequestEvent): CloudFrontRequest {\n return event.Records[0].cf.request;\n}\n\n/** First value of a header (lowercase name), or undefined. */\nexport function getHeader(request: CloudFrontRequest, name: string): string | undefined {\n return request.headers[name.toLowerCase()]?.[0]?.value;\n}\n\n/**\n * Flatten CloudFront headers into the `Record<string, string | string[]>`\n * shape the SDK extractors and verify-access artifacts expect.\n */\nexport function flattenHeaders(headers: CloudFrontHeaders): Record<string, string | string[]> {\n const out: Record<string, string | string[]> = {};\n for (const [name, entries] of Object.entries(headers)) {\n if (!entries?.length) continue;\n out[name] = entries.length === 1 ? entries[0].value : entries.map((e) => e.value);\n }\n return out;\n}\n\n/**\n * Flatten CloudFront headers to single string values (multi-valued headers\n * joined with `\", \"`, standard HTTP field-value concatenation) — the\n * NormalizedRequest header shape.\n */\nfunction flattenHeadersSingle(headers: CloudFrontHeaders): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, entries] of Object.entries(headers)) {\n if (!entries?.length) continue;\n out[name] = entries.map((e) => e.value).join(', ');\n }\n return out;\n}\n\nexport interface DecodedBody {\n /** UTF-8 body text, undefined when there is no body. */\n text?: string;\n /** True when CloudFront truncated the body before handing it to the trigger. */\n truncated: boolean;\n}\n\nexport function decodeBody(request: CloudFrontRequest): DecodedBody {\n const body = request.body;\n if (!body?.data) return { truncated: false };\n const text =\n body.encoding === 'base64' ? Buffer.from(body.data, 'base64').toString('utf8') : body.data;\n return { text, truncated: body.inputTruncated === true };\n}\n\n/**\n * Connection-layer signals the edge can see but the SDK cannot. CloudFront\n * injects the `CloudFront-Viewer-*` header family (IP, ASN, country, TLS\n * version/cipher, HTTP version, device class) when the OriginRequestPolicy\n * whitelists them (see infra/template.yaml). Absent values are simply\n * omitted — a partial connection block is fine.\n */\nexport function collectConnectionMetadata(request: CloudFrontRequest): Record<string, string> {\n const out: Record<string, string> = {};\n const put = (key: string, headerName: string, transform?: (v: string) => string) => {\n const v = getHeader(request, headerName);\n if (v) out[key] = transform ? transform(v) : v;\n };\n // `cloudfront-viewer-address` is `ip:port` (IPv6 keeps its brackets); take the\n // address portion the same way the beacon/pipeline already do.\n const addr = getHeader(request, 'cloudfront-viewer-address');\n if (addr) out.ip = addr.replace(/:\\d+$/, '');\n put('country', 'cloudfront-viewer-country');\n put('countryName', 'cloudfront-viewer-country-name');\n put('region', 'cloudfront-viewer-country-region');\n put('countryRegionName', 'cloudfront-viewer-country-region-name');\n put('city', 'cloudfront-viewer-city');\n put('asn', 'cloudfront-viewer-asn');\n put('tlsVersion', 'cloudfront-viewer-tls');\n put('httpVersion', 'cloudfront-viewer-http-version');\n put('timeZone', 'cloudfront-viewer-time-zone');\n put('metroCode', 'cloudfront-viewer-metro-code');\n // JA3/JA4 client fingerprints (HTTPS viewers only; delivered solely via the\n // OriginRequestPolicy — see infra/template.yaml, kept in lockstep by test).\n put('tlsFingerprint', 'cloudfront-viewer-ja3-fingerprint');\n put('ja4', 'cloudfront-viewer-ja4-fingerprint');\n // Header-structure fingerprint. headerOrder can exceed the platform's\n // 256-char connection-value bound — truncate at the emitter.\n put('headerOrder', 'cloudfront-viewer-header-order', (v) => v.slice(0, 256));\n put('headerCount', 'cloudfront-viewer-header-count');\n // Device-class booleans → a single compact device string.\n const devices: string[] = [];\n for (const [label, header] of [\n ['desktop', 'cloudfront-is-desktop-viewer'],\n ['mobile', 'cloudfront-is-mobile-viewer'],\n ['tablet', 'cloudfront-is-tablet-viewer'],\n ['smarttv', 'cloudfront-is-smarttv-viewer'],\n ] as const) {\n if (getHeader(request, header) === 'true') devices.push(label);\n }\n if (devices.length) out.device = devices.join(',');\n return out;\n}\n\n/**\n * CloudFront PlatformIo normalization: origin-request event → the edge\n * core's NormalizedRequest. `clientIp` keeps the pipeline's historical\n * viewer-address derivation (address portion before the first `:`) so\n * verify-access/beacon telemetry is byte-identical to earlier releases.\n */\nexport function toNormalizedRequest(request: CloudFrontRequest): NormalizedRequest {\n const body = decodeBody(request);\n const connection = collectConnectionMetadata(request);\n const clientIp = getHeader(request, 'cloudfront-viewer-address')?.split(':')[0];\n return {\n method: request.method,\n uri: request.uri,\n querystring: request.querystring ?? '',\n headers: flattenHeadersSingle(request.headers),\n ...(body.text !== undefined && { bodyText: body.text }),\n ...(body.truncated && { bodyTruncated: true }),\n ...(clientIp && { clientIp }),\n ...(Object.keys(connection).length > 0 && { connection }),\n };\n}\n\n/**\n * Execute the core's abstract outcome application against the CloudFront\n * request: `pass` mutates the origin-bound request (strip spoofable\n * prefixes, inject trust headers) and returns it; `respond` short-circuits\n * with a CloudFront JSON response.\n */\nexport function applyCoreOutcome(\n request: CloudFrontRequest,\n application: OutcomeApplication\n): CloudFrontRequestResult {\n if (application.action === 'respond') {\n return jsonResponse(application.status, application.bodyJson, application.headers);\n }\n for (const prefix of application.stripHeaderPrefixes) {\n stripHeadersByPrefix(request, prefix);\n }\n for (const [name, value] of Object.entries(application.injectHeaders)) {\n setHeader(request, name, value);\n }\n return request;\n}\n\n/**\n * The FULL sanitised metadata capture for one request: every inbound header\n * (secrets stripped, credential headers reduced to a safe format prefix)\n * plus the connection-layer block. Forwarded on both the verify-access call\n * and the beacon.\n */\nexport function buildObservedMetadata(request: CloudFrontRequest): ObservedMetadata {\n return buildObservedMetadataCore(toNormalizedRequest(request));\n}\n\n/**\n * Normalize the origin-bound `Host` header.\n *\n * To receive the `CloudFront-Viewer-*` connection headers (IP/ASN/TLS/country)\n * we must move off the managed `AllViewerExceptHostHeader` origin-request policy\n * onto one that whitelists those headers — but every such policy ALSO forwards\n * the viewer `Host`, which would break vhost / PaaS origin routing that expects\n * the origin's own hostname. So the Lambda takes ownership of the Host rewrite:\n * stash the public (viewer) host into `X-Forwarded-Host` for downstream use and\n * detection, then set `Host` to the origin's domain (available on the event as\n * `request.origin.custom.domainName`). No-ops when the origin domain is absent\n * (synthetic test events) or already matches — so it is safe on every path,\n * including static-asset pass-through.\n */\nexport function normalizeOriginHost(request: CloudFrontRequest): void {\n const originDomain =\n request.origin?.custom?.domainName ?? request.origin?.s3?.domainName ?? undefined;\n if (!originDomain) return;\n const currentHost = getHeader(request, 'host');\n if (!currentHost || currentHost === originDomain) return;\n if (!getHeader(request, 'x-forwarded-host')) {\n setHeader(request, 'X-Forwarded-Host', currentHost);\n }\n setHeader(request, 'Host', originDomain);\n}\n\n/** Full request URL as the origin will see it (scheme fixed to https). */\nexport function requestUrl(request: CloudFrontRequest, host: string): string {\n const qs = request.querystring ? `?${request.querystring}` : '';\n return `https://${host}${request.uri}${qs}`;\n}\n\n/**\n * Set a header on the origin-bound request (overwrites all prior values).\n */\nexport function setHeader(request: CloudFrontRequest, name: string, value: string): void {\n request.headers[name.toLowerCase()] = [{ key: name, value }];\n}\n\n/**\n * Strip every inbound header matching a prefix (lowercase compare). Used to\n * drop spoofed `x-astrasync-*` trust headers before the shell injects its\n * own — in BOTH modes, so a caller can never smuggle trust past the origin.\n */\nexport function stripHeadersByPrefix(request: CloudFrontRequest, prefix: string): void {\n const p = prefix.toLowerCase();\n for (const name of Object.keys(request.headers)) {\n if (name.startsWith(p)) delete request.headers[name];\n }\n}\n\nexport function jsonResponse(\n status: number,\n body: unknown,\n extraHeaders?: Record<string, string>\n): CloudFrontResultResponse {\n const headers: CloudFrontResultResponse['headers'] = {\n 'content-type': [{ key: 'Content-Type', value: 'application/json' }],\n };\n for (const [name, value] of Object.entries(extraHeaders ?? {})) {\n headers[name.toLowerCase()] = [{ key: name, value }];\n }\n return {\n status: String(status),\n statusDescription: status === 403 ? 'Forbidden' : status === 202 ? 'Accepted' : 'OK',\n headers,\n body: JSON.stringify(body),\n };\n}\n","/**\n * Runtime configuration for the edge shell.\n *\n * Lambda@Edge forbids environment variables, so configuration is layered:\n * 1. Build-time constants baked into the bundle (apiBaseUrl,\n * counterpartyId, counterpartyUrl, apiKeySecretName) — see\n * `tsup.config.ts` define block and `infra/deploy.sh`.\n * 2. The merchant API key from AWS Secrets Manager (us-east-1), fetched\n * lazily once per container and cached with a 15-minute TTL so\n * rotation needs no redeploy. Observe mode works fully without it —\n * the beacon endpoint is unauthenticated and verify() degrades\n * keyless — so a Secrets Manager outage can never take the shell down.\n * 3. The dashboard EdgeConfig via the SDK's getEdgeConfig (60s TTL,\n * stale-while-revalidate, enforce→observe degradation after 24h\n * staleness, DEFAULT_EDGE_CONFIG fallback — all in the SDK).\n */\n\nimport {\n getEdgeConfig,\n DEFAULT_EDGE_CONFIG,\n type EdgeConfig,\n} from '@astrasyncai/verification-gateway/edge-config';\nimport type { EdgeAdapterOptions } from './types';\n\nconst SECRET_TTL_MS = 15 * 60 * 1000;\n\ninterface SecretCacheEntry {\n value: string | undefined;\n fetchedAt: number;\n}\n\nconst secretCache = new Map<string, SecretCacheEntry>();\n\nasync function defaultFetchSecret(secretName: string): Promise<string | undefined> {\n // Lazy import so tests (and the library build) never touch the AWS SDK\n // unless a secret name is actually configured.\n const { SecretsManagerClient, GetSecretValueCommand } =\n await import('@aws-sdk/client-secrets-manager');\n // Lambda@Edge replicates globally but secrets live in us-east-1 (the\n // Lambda@Edge home region).\n const client = new SecretsManagerClient({ region: 'us-east-1' });\n const result = await client.send(new GetSecretValueCommand({ SecretId: secretName }));\n return result.SecretString ?? undefined;\n}\n\n/**\n * Resolve the merchant API key. Never throws — a missing/unreachable secret\n * degrades to keyless operation (observe mode is fully functional without\n * it; enforce mode without a key cannot fetch a config that enforces, so it\n * degrades to observe by construction).\n */\nexport async function resolveApiKey(options: EdgeAdapterOptions): Promise<string | undefined> {\n if (options.apiKey) return options.apiKey;\n const secretName = options.apiKeySecretName;\n if (!secretName) return undefined;\n\n const cached = secretCache.get(secretName);\n if (cached && Date.now() - cached.fetchedAt < SECRET_TTL_MS) return cached.value;\n\n try {\n const fetcher = options.fetchSecret ?? defaultFetchSecret;\n const value = await fetcher(secretName);\n secretCache.set(secretName, { value, fetchedAt: Date.now() });\n return value;\n } catch (err) {\n options.log?.('warn', 'Secrets Manager fetch failed — continuing keyless', {\n secretName,\n error: err instanceof Error ? err.message : String(err),\n });\n // Serve a stale value if we ever had one; otherwise keyless.\n return cached?.value;\n }\n}\n\n/**\n * Load the effective EdgeConfig. Delegates caching/fallback/degradation to\n * the SDK; adds the compile-time fallback override and never throws.\n */\nexport async function loadEdgeConfig(\n options: EdgeAdapterOptions,\n apiKey: string | undefined\n): Promise<EdgeConfig> {\n try {\n return await getEdgeConfig({ apiBaseUrl: options.apiBaseUrl, apiKey }, options.counterpartyId, {\n ttlMs: options.configTtlMs,\n });\n } catch {\n return options.fallbackConfig ?? DEFAULT_EDGE_CONFIG;\n }\n}\n\n/** Reset module caches — tests only. */\nexport function _resetConfigCaches(): void {\n secretCache.clear();\n}\n","/**\n * Three-tier traffic classification — CloudFront wrapper over\n * the edge core's classifier. The classification logic itself (tier order,\n * UA patterns, path-rule resolution) lives in\n * `@astrasyncai/verification-gateway/edge-core` and is shared with every\n * edge platform adapter.\n */\n\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport {\n classify as classifyCore,\n resolvePolicy,\n _patterns,\n} from '@astrasyncai/verification-gateway/edge-core';\nimport { toNormalizedRequest } from './cf';\nimport type { Classification } from './types';\n\nexport { resolvePolicy, _patterns };\n\n/** Classify one CloudFront origin-request. See the edge core for the tier order. */\nexport function classify(\n request: CloudFrontRequest,\n host: string,\n depth: 'classify' | 'authenticate' | 'authorize'\n): Classification {\n return classifyCore(toNormalizedRequest(request), host, depth);\n}\n","/**\n * Crypto-free commerce-protocol detection (fixed detection order) —\n * CloudFront wrapper over the edge core's detector. The sniffing logic\n * (header shapes, compact-JWT patterns, body field names) lives in\n * `@astrasyncai/verification-gateway/edge-core`; this module adapts the\n * CloudFront event shape (separately-decoded body) onto it.\n */\n\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport {\n detectCommerce as detectCommerceCore,\n type DetectedCommerce,\n} from '@astrasyncai/verification-gateway/edge-core';\nimport { toNormalizedRequest, type DecodedBody } from './cf';\n\nexport type { DetectedCommerce };\n\n/**\n * Detect commerce-protocol credentials on a CloudFront origin-request.\n * `body` is the caller-decoded request body (see `decodeBody`) — kept as an\n * explicit parameter so callers that already decoded it don't pay twice.\n */\nexport function detectCommerce(\n request: CloudFrontRequest,\n host: string,\n body: DecodedBody\n): DetectedCommerce | undefined {\n const normalized = toNormalizedRequest(request);\n return detectCommerceCore(\n {\n ...normalized,\n bodyText: body.text,\n bodyTruncated: body.truncated,\n },\n host\n );\n}\n","/**\n * Depth-controlled verification per tier — CloudFront wrapper over the edge\n * core's tier pipeline. The verification semantics (what each depth looks\n * at and forwards, the fail-open rules, the verify-access request shape)\n * live in `@astrasyncai/verification-gateway/edge-core`; the edge never\n * verifies credentials itself — verify-access is the canonical sole\n * verification sink.\n */\n\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport { runTier as runTierCore } from '@astrasyncai/verification-gateway/edge-core';\nimport { toNormalizedRequest } from './cf';\nimport type { Classification, EdgeAdapterOptions, EffectivePolicy, TierOutcome } from './types';\n\n/**\n * Run the tier-appropriate verification/telemetry for one classified\n * request. NEVER throws; on any failure returns an `allow` outcome with the\n * failure recorded in `reasons` (infra failures fail open — a presented\n * credential the BACKEND rejected is a deny, but an unreachable backend is\n * not a rejection).\n */\nexport async function runTier(\n options: EdgeAdapterOptions,\n request: CloudFrontRequest,\n classification: Classification,\n policy: EffectivePolicy,\n apiKey: string | undefined,\n sampling: { anonymousBeaconRate: number }\n): Promise<TierOutcome> {\n return runTierCore(\n options,\n toNormalizedRequest(request),\n classification,\n policy,\n apiKey,\n sampling\n );\n}\n","/**\n * Decision → CloudFront result wiring (enforcement + ASAT trust-attestation\n * headers). The decision logic (observe shadow stamps, misconfig fail-open,\n * enforce-mode response bodies) lives in the edge core; this module\n * executes the core's abstract outcome application against CloudFront\n * request/response primitives.\n */\n\nimport type { CloudFrontRequest, CloudFrontRequestResult } from 'aws-lambda';\nimport {\n applyOutcome as resolveOutcomeApplication,\n ASAT_HEADERS,\n} from '@astrasyncai/verification-gateway/edge-core';\nimport { applyCoreOutcome } from './cf';\nimport type { EdgeAdapterOptions, EffectivePolicy, TierOutcome } from './types';\n\nexport { ASAT_HEADERS };\n\n/**\n * Apply the outcome. Always strips inbound spoofed `x-astrasync-*` headers\n * first (both modes — trust headers must only ever originate here).\n *\n * Observe mode: returns the request untouched apart from header hygiene and\n * an `X-AstraSync-Observed-Decision` stamp for origin-side log correlation.\n *\n * Enforce mode: ALLOW → request + ASAT headers; DENY → 403 machine-readable\n * body; MANUAL_REVIEW → 202 with step-up poll info.\n */\nexport function applyOutcome(\n options: EdgeAdapterOptions,\n request: CloudFrontRequest,\n outcome: TierOutcome,\n policy: EffectivePolicy\n): CloudFrontRequestResult {\n return applyCoreOutcome(request, resolveOutcomeApplication(options, outcome, policy));\n}\n","/**\n * Protocol-specific machine-readable messaging for enforce-mode\n * responses. The message catalogue and body builders live in the edge core\n * (shared across every edge platform adapter); re-exported here so the\n * adapter's public API is unchanged.\n */\n\nexport {\n buildDenyBody,\n buildManualReviewBody,\n type DenyBody,\n type ManualReviewBody,\n} from '@astrasyncai/verification-gateway/edge-core';\n","/**\n * Time-budgeted event emission — CloudFront wrapper over the edge core's\n * telemetry. Lambda@Edge has no `waitUntil`, so every network call is\n * awaited under an explicit budget and DROPPED on timeout (the core's\n * default posture): latency to the customer's traffic is bounded, and a\n * slow AstraSync API costs telemetry, never page loads.\n */\n\nimport type { CloudFrontRequest } from 'aws-lambda';\nimport {\n emitBeacon as emitBeaconCore,\n withBudget,\n sampled,\n} from '@astrasyncai/verification-gateway/edge-core';\nimport { toNormalizedRequest } from './cf';\nimport type { Classification, EdgeAdapterOptions } from './types';\n\nexport { withBudget, sampled };\n\n/**\n * Emit an unregistered-attempt beacon for `identified` (non-crypto depths)\n * and sampled `anonymous-bot` traffic. Unauthenticated by design\n * (CSRF-exempt on the backend); the backend fingerprints the UA and\n * find-or-provisions orphan platform agents server-side.\n */\nexport async function emitBeacon(\n options: EdgeAdapterOptions,\n request: CloudFrontRequest,\n classification: Classification,\n budgetMs: number\n): Promise<void> {\n await emitBeaconCore(options, toNormalizedRequest(request), classification, budgetMs);\n}\n"],"mappings":"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","names":["import_edge_core","import_edge_core","classifyCore","import_edge_core","detectCommerceCore","import_edge_core","runTierCore","import_edge_core","resolveOutcomeApplication","import_edge_core","import_edge_core","emitBeaconCore"]}