mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 19:31:31 +00:00
a1c7741e1b
The deploy-vendor-e2e job has been failing with the certctl-test-server container restarting endlessly. Diagnostic dump (added in3b96b35) finally surfaced the actual cause: Failed to load configuration: SCEP profile 0 (PathID="e2eintune") has empty CHALLENGE_PASSWORD — refuse to start (CWE-306: per-profile shared secret is the sole application-layer auth boundary; an empty password would allow any client reaching /scep/e2eintune to enroll a CSR against issuer "iss-local") Same shape as the encryption-key fix that landed inc4157fd: a config validation gate added in code that the test compose never got updated to satisfy, hidden pre-Phase-5 because the matrix-collapse hadn't yet forced the certctl-server to actually boot in CI. Root cause is more interesting than just "missing env var." The 2026-04-29 SCEP RFC 8894 + Intune master bundle Phase I added an `e2eintune` SCEP profile to docker-compose.test.yml expecting deploy/test/scep_intune_e2e_test.go to exercise it. That integration test does exist (//go:build integration) but **NO CI job ever selects it** — ci.yml's deploy-vendor-e2e job runs only `-run 'VendorEdge_'` (line 379), and no other job invokes `go test -tags integration` with a SCEP selector. Confirmed via `grep -rnE "scep_intune|SCEPIntune" .github/workflows/` returning empty. Worse: the supporting fixtures (ra.crt + ra.key + intune_trust_anchor.pem) were documented in deploy/test/fixtures/README.md with the regeneration recipe but never actually committed. Pre-Phase-5 the test stack didn't fully boot the server in CI, so the entire stack of debt — dead config + missing fixtures + no consumer test — sat silent until the matrix collapse forced the boot path. Fixing this with a fake CHALLENGE_PASSWORD value would silence the immediate validator but leave the real problem in place: maintenance cost on test config that no test exercises. Same critique applies to "let me commit fake fixtures" — the fixtures alone don't add test coverage when no CI job runs the SCEP test. The complete-path fix is to make the test compose match what CI actually exercises: - deploy/docker-compose.test.yml: drop CERTCTL_SCEP_ENABLED + the full e2eintune profile env var family (10 lines) + the ./test/fixtures volume mount (1 line). Replace with an in-line comment explaining why SCEP is intentionally disabled and what needs to come back together when SCEP is added to CI for real. - scripts/ci-guards/test-compose-scep-coherence.sh (new, 22nd guard): refuses any future state where CERTCTL_SCEP_ENABLED=true in test compose without ALL of: 1. A CI job that runs the SCEP integration test (matched by scep_intune | SCEPIntune | -run [Ss]cep in ci.yml) 2. The fixture files actually committed (ra.crt, ra.key, intune_trust_anchor.pem) 3. The ./test/fixtures:/etc/certctl/scep:ro volume mount Verified manually with the same pattern as the H-1 guard: clean tree → exit 0; deliberate SCEP_ENABLED=true regression → exit 1 with 5 ::error:: annotations covering each gap; restore → exit 0 again. - scripts/ci-guards/README.md: 21 → 22 guards, new row. The fixtures README at deploy/test/fixtures/README.md keeps the regeneration recipe so the eventual SCEP CI job lands cleanly: the operator who adds the SCEP job restores the env vars, regenerates + commits the fixtures, and the guard auto-passes. Pattern (now firm across this CI-stabilization sequence): - Pre-existing latent bug - Old CI structurally hid it (per-vendor matrix, missing boot path) - Phase-5 matrix collapse + new diagnostic infra exposed it - Direct fix unblocks today - Regression guard prevents the same shape of drift forever Encryption-key (c4157fd) was the same shape; this is its sibling.
86 lines
4.0 KiB
Bash
Executable File
86 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# scripts/ci-guards/test-compose-scep-coherence.sh
|
|
#
|
|
# Enforces that deploy/docker-compose.test.yml's SCEP profile config
|
|
# stays coherent with the rest of the test infrastructure: if SCEP is
|
|
# enabled in test compose, then there MUST be a CI job that exercises
|
|
# the SCEP integration test, AND the supporting fixture files must
|
|
# actually exist on disk (not just be documented in the fixtures README).
|
|
#
|
|
# Background. The 2026-04-29 SCEP RFC 8894 + Intune master bundle
|
|
# Phase I added an `e2eintune` SCEP profile to docker-compose.test.yml
|
|
# expecting deploy/test/scep_intune_e2e_test.go to exercise it. The
|
|
# test exists (//go:build integration) but was never wired into any
|
|
# CI job, AND the supporting fixtures (ra.crt + ra.key +
|
|
# intune_trust_anchor.pem) were documented in deploy/test/fixtures/
|
|
# README.md but never committed. Pre-Phase-5 (ci-pipeline-cleanup
|
|
# matrix collapse) the test stack didn't fully boot the certctl-server,
|
|
# so the gap was hidden. Post-collapse the boot validator at
|
|
# config.go::Validate() fired with CWE-306 (empty CHALLENGE_PASSWORD)
|
|
# and blocked deploy-vendor-e2e.
|
|
#
|
|
# That bundle's CI commit (this guard's predecessor commit) dropped the
|
|
# SCEP env vars + the fixtures volume mount from compose. This guard
|
|
# stops the same drift from ever recurring silently. To re-enable SCEP
|
|
# in test compose:
|
|
#
|
|
# 1. Restore the SCEP env vars (CERTCTL_SCEP_ENABLED=true +
|
|
# CERTCTL_SCEP_PROFILES + per-profile CHALLENGE_PASSWORD + ...).
|
|
# 2. Restore the volume mount `./test/fixtures:/etc/certctl/scep:ro`.
|
|
# 3. Commit the supporting fixtures (ra.crt, ra.key,
|
|
# intune_trust_anchor.pem) per deploy/test/fixtures/README.md.
|
|
# 4. Add a CI job that runs `go test -tags integration -run 'SCEPIntune'`
|
|
# against the same compose stack — without it, the SCEP plumbing
|
|
# in test compose is paying maintenance cost for zero benefit.
|
|
#
|
|
# All four must move together. This guard refuses any partial state.
|
|
#
|
|
# Per the contract documented in scripts/ci-guards/README.md:
|
|
# bare callable, no args, no env, exit 0 on clean.
|
|
|
|
set -e
|
|
|
|
GUARD_NAME="test-compose-scep-coherence"
|
|
COMPOSE_FILE="deploy/docker-compose.test.yml"
|
|
CI_FILE=".github/workflows/ci.yml"
|
|
FIXTURES_DIR="deploy/test/fixtures"
|
|
|
|
failed=0
|
|
|
|
# Phase 1: is SCEP enabled in test compose? Match `CERTCTL_SCEP_ENABLED:`
|
|
# followed by an optional quote then `true`.
|
|
if grep -qE '^\s*CERTCTL_SCEP_ENABLED:\s*"?true"?\s*$' "$COMPOSE_FILE"; then
|
|
echo "Detected CERTCTL_SCEP_ENABLED=true in $COMPOSE_FILE"
|
|
|
|
# Phase 2: is there a CI job that runs the SCEP integration test?
|
|
# Match either an explicit selector (-run 'SCEPIntune' or similar) or
|
|
# a direct reference to scep_intune_e2e_test.go.
|
|
if ! grep -qE "scep_intune|SCEPIntune|SCEPProfile.*E2E|-run.*[Ss]cep" "$CI_FILE"; then
|
|
echo "::error file=${CI_FILE}::CERTCTL_SCEP_ENABLED=true in ${COMPOSE_FILE} but no CI job runs the SCEP integration test. Add a job that invokes 'go test -tags integration -run SCEPIntune' against the same compose stack, OR remove the SCEP env vars from compose."
|
|
failed=1
|
|
fi
|
|
|
|
# Phase 3: are the required fixture files present?
|
|
for f in ra.crt ra.key intune_trust_anchor.pem; do
|
|
if [ ! -f "${FIXTURES_DIR}/${f}" ]; then
|
|
echo "::error file=${COMPOSE_FILE}::CERTCTL_SCEP_ENABLED=true in ${COMPOSE_FILE} but required SCEP fixture is missing: ${FIXTURES_DIR}/${f}. See ${FIXTURES_DIR}/README.md for the regeneration recipe."
|
|
failed=1
|
|
fi
|
|
done
|
|
|
|
# Phase 4: is the volume mount present? Without it, the cert/key
|
|
# paths inside the container resolve to nothing.
|
|
if ! grep -qE '^\s*-\s+\./test/fixtures:/etc/certctl/scep:ro\s*$' "$COMPOSE_FILE"; then
|
|
echo "::error file=${COMPOSE_FILE}::CERTCTL_SCEP_ENABLED=true but the './test/fixtures:/etc/certctl/scep:ro' volume mount is missing. SCEP profile would have no fixture access."
|
|
failed=1
|
|
fi
|
|
fi
|
|
|
|
if [ "$failed" -ne 0 ]; then
|
|
echo ""
|
|
echo "${GUARD_NAME}: FAILED — SCEP test config is incoherent across compose, CI workflow, and fixtures."
|
|
exit 1
|
|
fi
|
|
|
|
echo "${GUARD_NAME}: clean."
|