Skip to content

Commit a7ccf90

Browse files
Harden PQC drill guardrails for sprint closeout
1 parent d5e5bd1 commit a7ccf90

4 files changed

Lines changed: 92 additions & 1 deletion

File tree

Documentation/Security/QUANTUM_KEX_ROTATION_DRILL_RUNBOOK.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ The drill demonstrates three things in one auditable sequence:
4444
make quantum-kex-rotation-drill
4545
```
4646

47+
### Strict production guardrail path
48+
49+
```bash
50+
ENFORCE_NON_MOCK_BACKEND=true \
51+
FALLBACK_STARK_BACKEND=external_cmd \
52+
MOHAWK_STARK_VERIFY_CMD="/usr/local/bin/real-stark-verifier" \
53+
bash scripts/quantum-kex-rotation-drill.sh
54+
```
55+
4756
### Direct script path
4857

4958
```bash
@@ -88,6 +97,9 @@ Generated cross-run index files:
8897
- artifacts/quantum-kex-rotation/public-drill-index.json
8998
- artifacts/quantum-kex-rotation/public-drill-index.md
9099

100+
PQC readiness evidence file:
101+
- pqc-readiness-evidence.json
102+
91103
## Success Criteria
92104
- Readiness pre-check is true.
93105
- Hybrid verification accepted both before and after rotation tests.
@@ -96,6 +108,7 @@ Generated cross-run index files:
96108
- Ledger reconciliation healthy after the drill.
97109
- Ledger entry count increases by at least 2 during the drill.
98110
- All artifact files present and readable.
111+
- For production-mode claims, `production_pqc_ready` must be `true` and non-mock backend enforcement must be enabled.
99112

100113
## Public Disclosure Template
101114
Use the generated drill summary values and publish a concise statement:
@@ -116,6 +129,7 @@ Evidence bundle path: artifacts/quantum-kex-rotation/<drill-id>/
116129
- This drill is non-destructive and uses existing verification endpoints.
117130
- If auth fails, recheck token source and X-API-Role permissions.
118131
- If reconciliation fails, stop public messaging and open incident triage before rerun.
132+
- `winterfell_mock` remains valid for testnet rehearsal only; production posture requires strict non-mock backend enforcement.
119133

120134
## Retention and Compliance
121135
- Canonical policy: [QUANTUM_KEX_DRILL_RETENTION_POLICY.md](QUANTUM_KEX_DRILL_RETENTION_POLICY.md)

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ quantum-kex-rotation-drill:
220220
@echo "🔐 Running Genesis Testnet Quantum KEX Rotation Drill..."
221221
@bash scripts/quantum-kex-rotation-drill.sh
222222

223+
quantum-kex-rotation-drill-strict:
224+
@echo "🔐 Running Quantum KEX Rotation Drill (strict non-mock backend enforcement)..."
225+
@ENFORCE_NON_MOCK_BACKEND=true bash scripts/quantum-kex-rotation-drill.sh
226+
223227
# =============================================================================
224228
# Development Helpers
225229
# =============================================================================
@@ -286,5 +290,6 @@ help:
286290
@echo " make compose-service-drift-check - Detect stale compose service names in scripts"
287291
@echo " make quickstart-verify - Run onboarding-safe baseline verification targets"
288292
@echo " make quantum-kex-rotation-drill - Run public Genesis Testnet KEX rotation evidence drill"
293+
@echo " make quantum-kex-rotation-drill-strict - Run drill with enforced non-mock backend policy"
289294
@echo " make check - Run all checks"
290295
@echo ""

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ Run the drill:
7373
make quantum-kex-rotation-drill
7474
```
7575

76+
Run with strict non-mock backend enforcement:
77+
78+
```bash
79+
make quantum-kex-rotation-drill-strict
80+
```
81+
7682
Or run directly with explicit endpoint/token inputs:
7783

7884
```bash
@@ -89,6 +95,11 @@ Artifact output:
8995

9096
- `artifacts/quantum-kex-rotation/<drill-id>/`
9197

98+
Production posture note:
99+
100+
- Testnet drills may use mock/simulated fallback backends for rehearsal.
101+
- Production PQC readiness claims require strict non-mock enforcement and `production_pqc_ready=true` in `drill-summary.json`.
102+
92103
## New Contributor Fast Path
93104

94105
If you just cloned the repo and want to run tests quickly, use this sequence.

scripts/quantum-kex-rotation-drill.sh

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ MOHAWK_API_TOKEN="${MOHAWK_API_TOKEN:-}"
1111
MOHAWK_API_TOKEN_FILE="${MOHAWK_API_TOKEN_FILE:-/run/secrets/mohawk_api_token}"
1212
MOHAWK_API_ROLE="${MOHAWK_API_ROLE:-verifier}"
1313
MOHAWK_NEGATIVE_TEST_ROLE="${MOHAWK_NEGATIVE_TEST_ROLE:-observer}"
14+
DRILL_MODE="${DRILL_MODE:-testnet}"
15+
FALLBACK_STARK_BACKEND="${FALLBACK_STARK_BACKEND:-winterfell_mock}"
16+
ENFORCE_NON_MOCK_BACKEND="${ENFORCE_NON_MOCK_BACKEND:-false}"
17+
PQC_KEM_SUITE="${PQC_KEM_SUITE:-declared-hybrid-target:x25519+mlkem768}"
18+
PQC_SIGNATURE_SUITE="${PQC_SIGNATURE_SUITE:-declared-target:mldsa65}"
1419
DRILL_ID="${DRILL_ID:-kex-rotation-$(date -u +%Y%m%dT%H%M%SZ)}"
1520
ARTIFACT_ROOT="${ARTIFACT_ROOT:-${ARTIFACTS_BASE_DIR}/${DRILL_ID}}"
1621
DRILL_RETENTION_DAYS="${DRILL_RETENTION_DAYS:-2555}"
@@ -35,6 +40,19 @@ require_cmd() {
3540
command -v "$1" >/dev/null 2>&1 || die "missing required command: $1"
3641
}
3742

43+
is_mock_backend() {
44+
local backend_name
45+
backend_name="$(echo "$1" | tr '[:upper:]' '[:lower:]')"
46+
case "${backend_name}" in
47+
*mock*|simulated_*|test_*)
48+
return 0
49+
;;
50+
*)
51+
return 1
52+
;;
53+
esac
54+
}
55+
3856
expect_bool_true() {
3957
local actual="$1"
4058
local error_message="$2"
@@ -118,10 +136,17 @@ fi
118136
API_TOKEN="$(resolve_api_token)"
119137
[[ -n "${API_TOKEN}" ]] || die "resolved API token is empty"
120138

139+
if [[ "${DRILL_MODE}" == "production" ]]; then
140+
ENFORCE_NON_MOCK_BACKEND=true
141+
fi
142+
121143
START_TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
122144
info "drill id: ${DRILL_ID}"
123145
info "artifact root: ${ARTIFACT_ROOT}"
124146
info "target node-agent: ${NODE_AGENT_BASE_URL}"
147+
info "drill mode: ${DRILL_MODE}"
148+
info "fallback stark backend: ${FALLBACK_STARK_BACKEND}"
149+
info "enforce non-mock backend: ${ENFORCE_NON_MOCK_BACKEND}"
125150

126151
curl -fsS "${READINESS_URL}" >"${ARTIFACT_ROOT}/readiness_pre.json"
127152
READY_PRE="$(json_field "${ARTIFACT_ROOT}/readiness_pre.json" "ready")"
@@ -171,10 +196,11 @@ domain_sep = b"winterfell-v1:"
171196
transcript = b"winterfell-fallback-drill-transcript-v1-20260408-extended-window"
172197
root = hashlib.sha256(domain_sep + transcript).digest()
173198
stark_proof = root + transcript
199+
backend = "${FALLBACK_STARK_BACKEND}"
174200
payload = {
175201
"mode": "any",
176202
"encoding": "base64",
177-
"stark_backend": "winterfell_mock",
203+
"stark_backend": backend,
178204
"snark_proof": base64.b64encode(b"invalid-snark-placeholder").decode("ascii"),
179205
"stark_proof": base64.b64encode(stark_proof).decode("ascii"),
180206
}
@@ -187,6 +213,10 @@ FALLBACK_ACCEPTED="$(json_field "${ARTIFACT_ROOT}/hybrid_verify_fallback_backend
187213
FALLBACK_BACKEND="$(json_field "${ARTIFACT_ROOT}/hybrid_verify_fallback_backend.json" "backend")"
188214
expect_bool_true "${FALLBACK_ACCEPTED}" "fallback backend rehearsal failed"
189215

216+
if [[ "${ENFORCE_NON_MOCK_BACKEND}" == "true" ]] && is_mock_backend "${FALLBACK_BACKEND}"; then
217+
die "non-mock backend enforcement enabled, but backend '${FALLBACK_BACKEND}' is mock/simulated"
218+
fi
219+
190220
# Negative role-failure check proves policy enforcement (expects 401/403).
191221
NEGATIVE_STATUS="$(curl -sS -o "${ARTIFACT_ROOT}/role_failure_negative_response.txt" -w '%{http_code}' \
192222
"${LEDGER_URL}" \
@@ -228,6 +258,24 @@ fi
228258

229259
END_TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
230260
DRILL_OUTCOME="pass"
261+
PQC_PRIMITIVES_WIRED=false
262+
PQC_PRODUCTION_READY=false
263+
if [[ "${ENFORCE_NON_MOCK_BACKEND}" == "true" ]] && ! is_mock_backend "${FALLBACK_BACKEND}"; then
264+
PQC_PRODUCTION_READY=true
265+
fi
266+
267+
cat >"${ARTIFACT_ROOT}/pqc-readiness-evidence.json" <<EOF
268+
{
269+
"drill_mode": "${DRILL_MODE}",
270+
"pqc_kem_suite": "${PQC_KEM_SUITE}",
271+
"pqc_signature_suite": "${PQC_SIGNATURE_SUITE}",
272+
"primitives_wired_in_runtime": ${PQC_PRIMITIVES_WIRED},
273+
"fallback_backend": "${FALLBACK_BACKEND}",
274+
"enforce_non_mock_backend": ${ENFORCE_NON_MOCK_BACKEND},
275+
"production_pqc_ready": ${PQC_PRODUCTION_READY},
276+
"notes": "production_pqc_ready is true only when non-mock backend enforcement is enabled and the runtime backend is non-mock"
277+
}
278+
EOF
231279

232280
cat >"${ARTIFACT_ROOT}/retention-policy.json" <<EOF
233281
{
@@ -279,6 +327,13 @@ cat >"${ARTIFACT_ROOT}/drill-summary.json" <<EOF
279327
"backend": "${FALLBACK_BACKEND}",
280328
"accepted": ${FALLBACK_ACCEPTED}
281329
},
330+
"pqc_readiness": {
331+
"drill_mode": "${DRILL_MODE}",
332+
"pqc_kem_suite": "${PQC_KEM_SUITE}",
333+
"pqc_signature_suite": "${PQC_SIGNATURE_SUITE}",
334+
"primitives_wired_in_runtime": ${PQC_PRIMITIVES_WIRED},
335+
"production_pqc_ready": ${PQC_PRODUCTION_READY}
336+
},
282337
"negative_role_failure_test": {
283338
"role": "${MOHAWK_NEGATIVE_TEST_ROLE}",
284339
"status_code": ${NEGATIVE_STATUS},
@@ -300,6 +355,7 @@ cat >"${ARTIFACT_ROOT}/drill-summary.json" <<EOF
300355
"crypto_rotation_test.log",
301356
"hybrid_verify_post_rotation.json",
302357
"hybrid_verify_fallback_backend.json",
358+
"pqc-readiness-evidence.json",
303359
"role_failure_negative_response.txt",
304360
"role_failure_negative_test.json",
305361
"ledger_post.json",
@@ -329,6 +385,11 @@ cat >"${ARTIFACT_ROOT}/drill-summary.md" <<EOF
329385
- Post-rotation hybrid verify accepted: ${POST_ACCEPTED}
330386
- Fallback backend rehearsal (${FALLBACK_BACKEND}) accepted: ${FALLBACK_ACCEPTED}
331387
- Negative role-failure status (${MOHAWK_NEGATIVE_TEST_ROLE}): ${NEGATIVE_STATUS}
388+
- Drill mode: ${DRILL_MODE}
389+
- Declared PQC KEM suite: ${PQC_KEM_SUITE}
390+
- Declared PQC signature suite: ${PQC_SIGNATURE_SUITE}
391+
- PQC primitives wired in runtime: ${PQC_PRIMITIVES_WIRED}
392+
- Production PQC ready: ${PQC_PRODUCTION_READY}
332393
- Ledger reconcile healthy after drill: ${RECONCILE_HEALTHY}
333394
- Ledger entry count before: ${LEDGER_PRE_COUNT}
334395
- Ledger entry count after: ${LEDGER_POST_COUNT}

0 commit comments

Comments
 (0)