# kyverno-json (`kj`) Lambda layer This document records how the `kj` (kyverno-json) binary is pinned and bundled into the Nova token-vend Lambda layer (D-227, C-8.2). ## Pin (C-8.2) The `kj` binary is pinned to a specific release. The version + SHA256 of the binary used for local ABAC tests and bundled into the Lambda layer are recorded in [`platform/abac/kj-version.txt`](../platform/abac/kj-version.txt): ``` ``` **Current pin:** `v0.0.3` — `4ebb9a19fbf545e17f046c137f9b69c4288d021e5c73d962835671e0cb3fbf07` (measured from `/usr/local/bin/kj` on the build host). C-8.2 requires pinning to a specific release (not `latest`) and recording the SHA256 so a supply-chain compromise of the upstream release is detectable. The build step downloads the pinned release, verifies the SHA256 against the recorded value, and aborts on mismatch. ## Lambda layer bundling The publish workflow (P1, `.github/workflows/`) bundles the pinned `kj` Linux amd64 binary into the `nova-cli` Lambda layer at `layer/bin/kj`. At runtime the Lambda mounts the layer at `/opt`, so `kj` is on PATH at `/opt/bin/kj`. `KyvernoJsonEngine.is_configured()` checks `which kj` → `/opt/bin/kj` and returns `False` when absent — the token-vend Lambda then **fails closed** (C-6.1, 403 `abac_eval_failed`), it never vends a token without an ABAC decision. ## Local testing `/usr/local/bin/kj` exists on the build host. The local ABAC tests (`tests/test_abac_policy.py`, `tests/test_abac_fail_closed.py`) use the real `kj` binary — they are skipped (not failed) when `kj` is absent. ## Fallback / migration path (D-227) If the `kj` Go binary proves unsuitable for the Lambda runtime (e.g. a future release exceeds the 250 MB layer unzip limit or drops AL2023 compatibility), the migration path is to run kyverno-json on AWS Fargate behind an internal NLB and have the token-vend Lambda call it over HTTP. The `PolicyEngine` Protocol (`core/policy_engine.py`) is the swap boundary — a `KyvernoJsonHttpEngine` would implement the same protocol without touching the token-vend Lambda's ABAC fail-closed logic. This is a documented fallback, not the v1.28 default.