Some checks are pending
Go Benchmark / Performance Regression Check (push) Waiting to run
Cerberus Integration / Cerberus Security Stack Integration (push) Waiting to run
Upload Coverage to Codecov / Backend Codecov Upload (push) Waiting to run
Upload Coverage to Codecov / Frontend Codecov Upload (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (go) (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Waiting to run
CrowdSec Integration / CrowdSec Bouncer Integration (push) Waiting to run
Docker Build, Publish & Test / build-and-push (push) Waiting to run
Docker Build, Publish & Test / Security Scan PR Image (push) Blocked by required conditions
Quality Checks / Auth Route Protection Contract (push) Waiting to run
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Waiting to run
Quality Checks / Backend (Go) (push) Waiting to run
Quality Checks / Frontend (React) (push) Waiting to run
Rate Limit integration / Rate Limiting Integration (push) Waiting to run
Security Scan (PR) / Trivy Binary Scan (push) Waiting to run
Supply Chain Verification (PR) / Verify Supply Chain (push) Waiting to run
WAF integration / Coraza WAF Integration (push) Waiting to run
4.2 KiB
Executable File
4.2 KiB
Executable File
Security Test Helpers
Helper utilities for managing security module state during E2E tests.
Overview
The security helpers module (tests/utils/security-helpers.ts) provides utilities for:
- Capturing and restoring security module state
- Toggling individual security modules (ACL, WAF, Rate Limiting, CrowdSec)
- Ensuring test isolation without ACL deadlock
Problem Solved
During E2E testing, if ACL is left enabled from a previous test run (e.g., due to test failure), it creates a deadlock:
- ACL blocks API requests → returns 403 Forbidden
- Global cleanup can't run → API blocked
- Auth setup fails → tests skip
- Manual intervention required to reset volumes
The security helpers solve this by using Playwright's test.afterAll() fixture to guarantee cleanup even when tests fail.
Usage
Capture and Restore Pattern
import { captureSecurityState, restoreSecurityState } from '../utils/security-helpers';
import { request } from '@playwright/test';
let originalState;
test.beforeAll(async ({ request: reqFixture }) => {
originalState = await captureSecurityState(reqFixture);
});
test.afterAll(async () => {
const cleanup = await request.newContext({ baseURL: '...' });
try {
await restoreSecurityState(cleanup, originalState);
} finally {
await cleanup.dispose();
}
});
Toggle Security Module
import { setSecurityModuleEnabled } from '../utils/security-helpers';
await setSecurityModuleEnabled(request, 'acl', true);
await setSecurityModuleEnabled(request, 'waf', false);
With Guaranteed Cleanup
import { withSecurityEnabled } from '../utils/security-helpers';
test.describe('ACL Tests', () => {
let cleanup: () => Promise<void>;
test.beforeAll(async ({ request }) => {
cleanup = await withSecurityEnabled(request, { acl: true, cerberus: true });
});
test.afterAll(async () => {
await cleanup();
});
test('should enforce ACL', async ({ page }) => {
// ACL is now enabled, test enforcement
});
});
Functions
| Function | Purpose |
|---|---|
getSecurityStatus |
Fetch current security module states |
setSecurityModuleEnabled |
Toggle a specific module on/off |
captureSecurityState |
Snapshot all module states |
restoreSecurityState |
Restore to captured snapshot |
withSecurityEnabled |
Enable modules with guaranteed cleanup |
disableAllSecurityModules |
Emergency reset |
API Endpoints Used
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/security/status |
GET | Returns current state of all security modules |
/api/v1/settings |
POST | Toggle settings with { key: "...", value: "true/false" } |
Settings Keys
| Key | Values | Description |
|---|---|---|
security.acl.enabled |
"true" / "false" |
Toggle ACL enforcement |
security.waf.enabled |
"true" / "false" |
Toggle WAF enforcement |
security.rate_limit.enabled |
"true" / "false" |
Toggle Rate Limiting |
security.crowdsec.enabled |
"true" / "false" |
Toggle CrowdSec |
feature.cerberus.enabled |
"true" / "false" |
Master toggle for all security |
Best Practices
- Always use
test.afterAllfor cleanup - it runs even when tests fail - Capture state before modifying - enables precise restoration
- Enable Cerberus first - it's the master toggle for all security modules
- Don't toggle back in individual tests - let
afterAllhandle cleanup - Use
withSecurityEnabledfor the cleanest pattern
Troubleshooting
ACL Deadlock Recovery
If the test suite is stuck due to ACL deadlock:
# Check current security status
curl http://localhost:8080/api/v1/security/status
# Manually disable ACL (requires auth)
curl -X POST http://localhost:8080/api/v1/settings \
-H "Content-Type: application/json" \
-d '{"key": "security.acl.enabled", "value": "false"}'
Complete Reset
Use disableAllSecurityModules in global setup to ensure clean slate:
import { disableAllSecurityModules } from './utils/security-helpers';
async function globalSetup() {
const context = await request.newContext({ baseURL: '...' });
await disableAllSecurityModules(context);
await context.dispose();
}