test(preprod): two-host routing simulation, drill suite, CI security scanning
- infra/scripts/simulate-two-host/: real two-Docker-network simulation (Gateway genuinely isolated from any Lab bridge network) proving the Lab Host Router fix - 13/13 real assertions (HTTP+WebSocket through the Router, Alice/Bob isolation, garbage/destroyed tokens, mTLS-only Router access). - infra/scripts/drills/: Lab Host loss/rebuild (9/9), deployment rollback, CI-fails-closed (6 required failure modes), fake cohort dress rehearsal (14/14, one continuous narrative through the real app). - infra/ci/gitea-workflows/build-and-test.yml: new security-scan job (npm audit, gitleaks, hadolint, shellcheck, trivy - all free/open-source), severity policy in docs/SECURITY_SCANNING.md (CRITICAL/HIGH blocks, MEDIUM/LOW reported only). Gates build-images alongside regression. Found and fixed two real pre-existing bugs via the CI-fails-closed drill: staging-smoke-test.sh and production-smoke-test.sh both had a classic set -e gotcha (curl ... && echo "OK" as one statement - a failing command that isn't last in an && chain doesn't trigger -e) that let an unreachable/broken endpoint fall through silently instead of failing the smoke test. platform/test/e2e-phase3a.js updated for the new paginated /api/admin/audit-events response shape (Phase 4.1 pagination work).
This commit is contained in:
@@ -160,12 +160,16 @@ async function main() {
|
||||
});
|
||||
|
||||
await test('audit log: security events were actually recorded', async () => {
|
||||
// Phase 4.1 §16 — /api/admin/audit-events is now paginated (see platform/api/src/pagination.js);
|
||||
// the events land on the most recent page, but this test has produced fewer than one
|
||||
// page's worth by this point, so page 1's items are still every event so far.
|
||||
const { body } = await owner.request('GET', '/api/admin/audit-events');
|
||||
const actions = body.map((e) => e.action);
|
||||
const items = body.items;
|
||||
const actions = items.map((e) => e.action);
|
||||
assert.ok(actions.includes('login'));
|
||||
assert.ok(actions.includes('authz_denied'));
|
||||
assert.ok(actions.includes('instructor_update'));
|
||||
assert.ok(body.every((e) => !JSON.stringify(e.metadata || {}).match(/password/i)), 'audit metadata must never contain password material');
|
||||
assert.ok(items.every((e) => !JSON.stringify(e.metadata || {}).match(/password/i)), 'audit metadata must never contain password material');
|
||||
});
|
||||
|
||||
// ── Student session hardening ──────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user