mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 16:21:30 +00:00
fix(deploy/test) + ci(guard): unblock deploy-vendor-e2e — encryption-key length
Two-part complete-path fix for the deploy-vendor-e2e failure that has
been firing since the ci-pipeline-cleanup Phase 5 matrix collapse
started actually booting the certctl-test-server:
Failed to load configuration:
CERTCTL_CONFIG_ENCRYPTION_KEY too short (29 bytes; minimum 32).
Surfaced via the diagnostic-dump step landed in commit 3b96b35 — the
server panicked on startup, Docker restarted it endlessly, compose
reported the dependency-chain symptom ("container certctl-test-server
is unhealthy"), but the actual cause was invisible in the previous
CI output. With the dump in place, the next failing run named the
problem in one line.
Root cause. The H-1 audit-closure master commit 3e78ecb
("feat(security): bodyLimit on noAuth + security headers + encryption-
key validation (H-1 master)") added internal/config/config.go's
minEncryptionKeyLength = 32 byte floor + 5 unit tests that pin it.
The closure was incomplete: it never enforced the rule against the
literal CERTCTL_CONFIG_ENCRYPTION_KEY values certctl's own
deploy/docker-compose*.yml files pass. Pre-Phase-5 the test stack
didn't fully exercise the validator (the per-vendor matrix didn't
boot certctl-test-server in every job), so the gap was silent.
deploy/docker-compose.test.yml's literal value
`test-encryption-key-32chars!!` was 29 bytes — the name claimed 32
but the author miscounted (4+1+10+1+3+1+2+5+2 = 29). Pattern matches
every fix in this CI-stabilization sequence: pre-existing latent bug
that the old CI structurally hid.
Part 1 — direct fix (deploy/docker-compose.test.yml):
Replace the 29-byte literal with a clearly test-only,
self-documenting 49-byte value (`test-encryption-key-deterministic-
32-byte-fixture`). 17 bytes of safety margin so a future tightening
of the floor (32 → 33+) doesn't break this fixture again. Inline
comment block explains the byte-budget contract + points at the
H-1 closure commit. Production deploy/docker-compose.yml's default
(`change-me-32-char-encryption-key`) is exactly 32 bytes — passes
by 1 byte but on the edge; not touched here because operators are
already told to override it via env (`${VAR:-default}`).
Part 2 — structural fix (scripts/ci-guards/H-1-encryption-key-min-
length.sh):
New regression guard. Scans every deploy/docker-compose*.yml for
literal CERTCTL_CONFIG_ENCRYPTION_KEY values + values inside
${VAR:-default} expansions, checks each against the 32-byte floor,
fails CI with `::error::` annotation pointing at the offending
file:line if any literal regresses. Bare ${VAR} env references with
no default are skipped — those are operator-supplied at runtime
and the validator handles them at boot.
Verified manually:
- Clean repo: `H-1-encryption-key-min-length: clean.` (exit 0)
- 5-byte regression: emits proper ::error:: annotation, exit 1
- Restore: clean again (exit 0)
CI auto-picks up the new guard via the `for g in
scripts/ci-guards/*.sh; do bash "$g"; done` loop in ci.yml's
Regression guards step (no ci.yml change required).
scripts/ci-guards/README.md updated: 20 → 21 guards, new row
explaining the closure rationale.
The structural piece is the more important half of this fix. The
direct fix unblocks today's CI; the guard prevents the same class of
drift from ever recurring silently. Future audit closures that add
new validation rules to internal/config/config.go now have a working
template for the matching CI guard — drop a sibling .sh in the
ci-guards directory.
Bonus — what the diagnostic-dump step (3b96b35) bought us. Before
that step landed, the same failure looked like an opaque "container
unhealthy" with no actionable signal. With it, the actual error
message + the offending env var + the exact byte count came out in
one CI run. The diagnostic infrastructure paid for itself within one
push.
This commit is contained in:
@@ -53,7 +53,7 @@ Current helpers:
|
||||
4. CI auto-picks up new scripts via the `for g in scripts/ci-guards/*.sh`
|
||||
loop in the `Regression guards` step — no ci.yml change required.
|
||||
|
||||
## The 20 guards in this directory
|
||||
## The 21 guards in this directory
|
||||
|
||||
| ID | Finding | Catches |
|
||||
|---|---|---|
|
||||
@@ -77,6 +77,7 @@ Current helpers:
|
||||
| `bundle-8-L-015-target-blank-rel-noopener` | L-015 (CWE-1022) reverse-tabnabbing | `target="_blank"` without `rel="noopener noreferrer"` |
|
||||
| `bundle-8-L-019-dangerously-set-inner-html` | L-019 (CWE-79) XSS | `dangerouslySetInnerHTML` outside `safeHtml.ts` |
|
||||
| `bundle-8-M-009-bare-usemutation` | M-009 + M-029 mutation contract | Bare `useMutation()` outside `useTrackedMutation` wrapper |
|
||||
| `H-1-encryption-key-min-length` | H-1 closure follow-up (post-Phase-5 surfacing) | `CERTCTL_CONFIG_ENCRYPTION_KEY` literal in any `deploy/docker-compose*.yml` shorter than the 32-byte floor enforced by `internal/config/config.go::Validate()` |
|
||||
|
||||
## Guards explicitly NOT here
|
||||
|
||||
|
||||
Reference in New Issue
Block a user