Files
Charon/docs/testing/security-helpers.md
akanealw eec8c28fb3
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
changed perms
2026-04-22 18:19:14 +00:00

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:

  1. ACL blocks API requests → returns 403 Forbidden
  2. Global cleanup can't run → API blocked
  3. Auth setup fails → tests skip
  4. 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

  1. Always use test.afterAll for cleanup - it runs even when tests fail
  2. Capture state before modifying - enables precise restoration
  3. Enable Cerberus first - it's the master toggle for all security modules
  4. Don't toggle back in individual tests - let afterAll handle cleanup
  5. Use withSecurityEnabled for 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();
}