Tablet 45: the courtyard gate checks the key, not the shape of the header
/courtyard/* and /chatzer/* admitted any `Authorization: Bearer <x>`. Every test sent `Bearer test-token`; none sent a wrong one. Every admitted request spends the day's manna. VavPipeline.BigdeiKodesh.Gate: keys are a file (Construction §4.6 — never env, never config, never git), one `tier key` per line, tiers courtyard < chatzer (the inner ring opens the outer). Constant-time compare against every line; no file / empty / unreadable → nobody passes, GATE_NO_KEYS in the log, the caller told only "missing or invalid". 403 FORBIDDEN for an outer key at an inner gate. Read on every request so a rotated key is live in ~1 min without a rollout. Deploy: Secret shorashim-api-keys projected at /etc/shorashim/secrets/api_keys (vav-pipeline only, 0440), API_KEYS_FILE in the configmap, template + issue/rotate recipe in secrets.yaml and KOHEN.md "Issuing a key". Spec: tamid §1.1 (gate, 403), vayakhel §4.6. Doorpost 91d09d8d… → 42b38626…. Tests: tablet45_gate_test (parse, tiers, wrong/near/empty/no key, no file) — Elixir 527/0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
996a8efe68
commit
79eb34840f
17 files changed
+372
-34
No files matched your search
@@ -88,3 +88,38 @@ type: Opaque
|
||||
stringData:
|
||||
# ecto://avnadmin:PASSWORD@host:port/database?sslmode=require
|
||||
DATABASE_URL: "REPLACE_WITH_AVNADMIN_DATABASE_URL"
|
||||
|
||||
---
|
||||
# ============================================================
|
||||
# shorashim-api-keys — who may enter the courtyard
|
||||
# ============================================================
|
||||
#
|
||||
# Mounted as the file /etc/shorashim/secrets/api_keys in vav-pipeline
|
||||
# (Construction §4.6: a secret is a file). One key per line:
|
||||
#
|
||||
# courtyard <key> offerings and bedikot (/courtyard/*)
|
||||
# chatzer <key> also the Sanhedrin (/chatzer/*); opens the courtyard too
|
||||
#
|
||||
# Issue a key (KOHEN.md "Issuing a key"):
|
||||
#
|
||||
# umask 077; TMP=$(mktemp)
|
||||
# printf 'courtyard %s\n' "$(openssl rand -hex 32)" >> "$TMP"
|
||||
# kubectl create secret generic shorashim-api-keys -n shorashim \
|
||||
# --from-file=api_keys="$TMP"
|
||||
# # rotate: kubectl create ... --dry-run=client -o yaml | kubectl apply -f -
|
||||
# rm -f "$TMP"
|
||||
#
|
||||
# The kubelet refreshes a projected Secret within about a minute; the
|
||||
# gate reads the file on every request, so a rotated key takes effect
|
||||
# without a rollout. No file, no keys → nobody passes (GATE_NO_KEYS in
|
||||
# the log).
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: shorashim-api-keys
|
||||
namespace: shorashim
|
||||
type: Opaque
|
||||
stringData:
|
||||
api_keys: |
|
||||
# tier key
|
||||
courtyard REPLACE_WITH_openssl_rand_hex_32
|
||||
Reference in new issue
Block a user