Skip to content
Docs/Platforms/SecureLab
Edit on GitHub

SecureLab

SecureLab is the attack simulation and detection validation platform in the opensecstack (SIN) ecosystem. It answers the question that detection stacks cannot answer themselves: do your deployed defences actually fire when the technique is executed? Scenarios are mapped to MITRE ATT&CK, run inside isolated Docker networks, and every run emits immutable evidence to CITADEL.

Safety notice: SecureLab contains offensive tooling. It must only be used against explicitly authorised test environments in an isolated network segment. Running attack scenarios against unauthorised systems is illegal and unethical. Read docs/safety-controls.md before executing any scenario.

Overview

Detection rules degrade silently. Log pipelines change, field names are renamed, and a rule that matched in 2025 can fail with zero alert in 2027 without anyone noticing. SecureLab closes this gap with three complementary capabilities:

  • Continuous detection validation. After each scenario run the detection validator polls OpenScrub, APIGuard, and ThreatFlow for expected alert events within a configurable window, returning a per-step detected / not_detected / inconclusive verdict.
  • ATT&CK coverage measurement. The MITRE ATT&CK mapper builds a coverage matrix from executed scenarios — coverage is measured by execution outcome, not by rule existence.
  • Immutable audit trail. Every live run emits a securelab.run_completed event (HMAC-SHA256 signed) to CITADEL, providing an externally verifiable record of all simulation activity including timed-out and blocked runs.

SecureLab is licensed under Apache 2.0. Offensive tooling embedded in the platform does not grant authorisation to test systems you do not own or have explicit written permission to test.

Key features

ModuleDescription
Scenario EngineAuthor, version, and execute multi-step YAML attack scenarios; content-hashed on write so every execution references an immutable scenario version
Attack Library15 built-in attack primitives tagged with MITRE ATT&CK technique IDs, tactics, and target platforms; extensible via YAML
MITRE ATT&CK MapperMaps scenarios to techniques and sub-techniques; generates a coverage heatmap and gap analysis from execution history
Detection ValidatorPolls OpenScrub (/api/v1/alerts), APIGuard (/api/v1/anomalies), and ThreatFlow (/api/v1/ioc-matches) read-only over HMAC-signed requests; returns per-step verdicts within a configurable detection window
Payload FuzzerRust payload-generation crate (called via PyO3 / subprocess) generating encoding variants, byte mutations, and fuzzing campaigns to stress-test detection rule boundaries
CITADEL Evidence EmitterAsync securelab.run_completed events to CITADEL WORM; dry-run executions do not emit; circuit breaker marks runs evidence_pending if emission fails
IRFlow IntegrationPushes execution results and ATT&CK coverage gaps to IRFlow via POST /api/v1/securelab/results for incident-response correlation
Safety controlsTarget URL blocklist, --internal Docker networks, per-attack-type rate caps, hard 30-minute scenario timeouts, admin-only environment creation, append-only audit log (Postgres row-level security), and pre-execution audit record creation — all non-bypassable at the platform level

Architecture

The v1.0.0 backend is written in Go (chi router, pgx, zap) and runs on :8080. The scenario engine and detection monitor run inside the same process; async scenario execution uses background goroutines with Redis-backed task state. The Rust payload-gen crate is compiled as a standalone library and invoked from Go via subprocess or shared-library binding.

Test target environments are provisioned on Docker bridge networks with internal: true — target containers have no outbound internet access and cannot reach any host outside the isolated test network. This cannot be overridden via the SecureLab API.

The platform enforces a strict security boundary: the API port (8080) and dashboard port (3000) must not be reachable from the public internet. Outbound from the Celery worker or detection monitor to integration endpoints must be allow-listed by IP and port at the firewall level.

The audit_log table is INSERT-only at the database level (Postgres row-level security with USING (false) on UPDATE/DELETE for the API service role). Every scenario run is recorded before execution begins, so blocked and timed-out runs also have a complete audit trail.

executions.evidence_hash stores a BLAKE3 hash of the canonical evidence body submitted to CITADEL, enabling independent audit verification.

Ports & endpoints

PortService
8080SecureLab REST API (Go — v1.0.0)
3000React operator dashboard (nginx in production)
8087SecureLab REST API (Python/FastAPI — scaffold reference)
3007React operator dashboard (scaffold reference)
MethodPathPurpose
GET/api/v1/healthLiveness + DB ping
GET/api/v1/scenariosList scenarios with ATT&CK mapping
POST/api/v1/scenariosCreate scenario (YAML body, content-hashed on write)
POST/api/v1/scenarios/{id}/executeExecute scenario — dry_run: true for plan-only
GET/api/v1/executions/{exec_id}Execution status and result
GET/api/v1/executions/{exec_id}/detectionsPer-step detection verdicts
GET/api/v1/coverageATT&CK technique coverage matrix
GET/api/v1/coverage/{technique_id}Coverage detail for one technique
GET/api/v1/attack-libraryList all attack primitives

Integration

SecureLab authenticates dashboard users via sinauth SSO using the OAuth 2.0 authorization_code + PKCE (S256) flow. The API validates RS256-signed tokens against the sinauth JWKS endpoint at https://auth.sin.to/.well-known/jwks.json.

Minimum required environment variables:

.env
Bash
SECURELAB_DB_URL=postgres://securelab:securelab@postgres:5432/securelab
SECURELAB_REDIS_URL=redis://redis:6379/0
SECURELAB_CITADEL_API_URL=https://citadel.internal
SECURELAB_CITADEL_KEY_SECRET=<hmac secret>
SECURELAB_OPENSCRUB_API_URL=https://openscrub.internal
SECURELAB_APIGUARD_API_URL=https://apiguard.internal
SECURELAB_THREATFLOW_API_URL=https://threatflow.internal
SECURELAB_IRFLOW_API_URL=https://irflow.internal
SECURELAB_ISOLATION_MODE=strict
SECURELAB_CITADEL_DRY_RUN=false

Quick start with Docker Compose:

Bash
git clone https://github.com/opensecstack/opensecstack
cd opensecstack/securelab

cp .env.example .env
docker compose up -d

"cm"># Health check
curl http://localhost:8080/api/v1/health

"cm"># List available scenarios
curl -H "Authorization: Bearer $TOKEN" \
     http://localhost:8080/api/v1/scenarios

"cm"># Dry-run a scenario (no payloads sent — plan only)
curl -X POST http://localhost:8080/api/v1/scenarios/api-bola-basic/execute \
     -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"dry_run": true}'

A YAML scenario maps each step to an attack primitive from the library with MITRE ATT&CK technique IDs:

scenarios/api/bola-basic.yaml
YAML
name: bola-basic
description: "BOLA via sequential integer ID enumeration on REST objects"
mitre_technique_ids: ["T1078"]
tags: [api, owasp-a1, bola]
severity: high
timeout: 3m
steps: - kind: bola
    params: endpoint: /api/v1/users/{id}
      id_range: [1, 100]
      auth_token_param: low_privilege_jwt

Full documentation

The complete SecureLab reference — scenario specification, attack library, detection validation guide, safety controls, MITRE ATT&CK mapping, CITADEL integration, and operator handbook — is in the repository:

github.com/opensecstack/opensecstack/tree/main/securelab/docs

SIN — Security Intelligence Network — Open-source cybersecurity & compliance for the EU Digital Decade.

Apache-2.0 & AGPL-3.0 · GitHub · Contribute