Knacky 7c011db6d9 test(e2e): sprint 5 acceptance tests — US-26 → US-28 + dropdown adaptations
Add three new spec files:
- us26-templates-crud: API CRUD (AC-26.3–26.7) + UI list/form/delete/redirect (AC-26.8)
- us27-instantiate-from-template: template_id copy + name override + 404 + decoupling
  (AC-27.1–27.3) + no auto-transition/engagement-activate (AC-27.4–27.5) + dropdown
  UI + picker modal + empty state + SOC gate (AC-27.6–27.7)
- us28-templates-nav: Templates link admin+redteam only, SOC redirect, form editable (AC-28.1–28.3)

Adapt sprint 2/3 e2e for sprint 5 dropdown:
- us4-engagements: getByRole link "New simulation" → getByTestId "new-simulation-btn"
- us7-simulation-create: same — split-button dropdown replaced the link

Suite: 201 passed (1 pre-existing flaky in us3 re DB state, unrelated to sprint 5).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 07:15:04 +02:00
2026-05-25 19:34:22 +02:00

Mimic

Mimic is a Breach and Attack Simulation (BAS) web UI built on the MITRE ATT&CK matrix. It replaces the flat Excel spreadsheets that red-teams and SOC analysts pass around at the end of an engagement, providing a shared workspace for Purple Team handoffs.

Status: Sprint 4 — UI polish + workflow tightening + dark mode + process hygiene. The Purple Team workflow is now tighter (Done is terminal, Reopen returns to Review required, engagements auto-flip Planned → Active on first in-progress simulation), simulations can be tagged with both techniques AND tactics (TA-ids), the MITRE matrix modal fits the viewport without horizontal scroll, the app supports light / dark / system theming, and PR creation is one Make target away.


Quick start

Prerequisites: Docker (or Podman) + GNU Make. Linux/macOS host.

# 1. Configure secrets
cp .env.example .env
# Edit .env and set MIMIC_JWT_SECRET to a strong random value:
#   sed -i "s|replace-me-with-a-strong-random-secret|$(openssl rand -hex 32)|" .env

# 2. Build and start the container
make build
make start

# 3. Bootstrap the first admin (run once, the container must be up)
make create-admin USER=alice PASS=changeme8

# 4. Open the UI
xdg-open http://localhost:5000     # Linux
# or visit http://localhost:5000 manually

Log in with the credentials from step 3. The admin can create additional users (redteam / soc) from /admin/users.

To stop or restart:

make stop
make restart      # stop + start, preserves the SQLite volume
make logs         # tail container logs

To override the host port:

make start PORT=8080

Architecture

Single-container deployment. A multistage Dockerfile builds the Vite frontend, then copies the static assets into the Flask backend image so Flask serves both the API (under /api/*) and the SPA (everything else).

┌───────────────────────────────────────────┐
│ Container: mimic:latest                   │
│                                           │
│  Flask (Python 3.12)                      │
│   ├── /api/* ── blueprints (auth, users,  │
│   │              engagements, simulations,│
│   │              mitre)                   │
│   └── /     ── SPA fallback → React build │
│                                           │
│  SQLAlchemy ── SQLite at /data/mimic.sqlite │
│                       (volume: mimic-data)│
└───────────────────────────────────────────┘
  • Auth: JWT Bearer tokens (HS256, 60-min TTL). Stateless — no refresh tokens, no server-side session.
  • Roles: admin (super-user — cumulates redteam rights on engagements/simulations), redteam (CRUD engagements + simulations, full field access), soc (read everything, write-only on the SOC half of simulations once the redteam marks them review_required).
  • Password hashing: argon2 via argon2-cffi.
  • Migrations: Alembic, applied automatically by the container entrypoint (flask db upgrade && flask run).
  • MITRE ATT&CK: STIX 2.1 Enterprise bundle committed at backend/data/mitre/enterprise-attack.json and indexed at app boot. make update-mitre re-fetches the latest bundle and (if the container is running) restarts it to reload the index. The endpoint GET /api/mitre/techniques?q= powers the autocomplete on simulations.
  • Simulation workflow: Pending → In progress (auto-transition when redteam saves any non-empty field) → Review required (manual, redteam) → Done (manual, redteam or SOC). The state machine is enforced server-side; the UI surfaces the appropriate transition button per role + current state.

See SPEC.md § "Décisions techniques" for the full architecture rationale and DESIGN.md for the UI design system.


Project layout

mimic/
├── backend/         # Flask app, SQLAlchemy models, Alembic migrations, pytest suite
├── frontend/        # Vite + React + Tailwind + TanStack Query, Vitest suite
├── e2e/             # Playwright acceptance tests (one spec per user story)
├── docker/          # Dockerfile (multistage) + entrypoint.sh
├── tasks/           # Sprint plans (tasks/todo.md) and lessons (tasks/lessons.md)
├── .claude/agents/  # Sub-agent definitions for the team (read-only at runtime)
├── Makefile         # all operational entry points
├── SPEC.md          # functional + technical spec
├── DESIGN.md        # UI design system (palette, typography, components)
└── CHANGELOG.md

Make targets

Target What it does
make build Build the mimic:latest container image (multistage: Node → Python). Uses docker if installed, otherwise podman — override with make build CONTAINER_CMD=podman
make start Start the container (port from PORT, default 5000; mounts mimic-data volume)
make stop Stop and remove the container
make restart make stop && make start — preserves the SQLite volume
make update git pull && make build && make restart
make logs docker logs -f mimic
make create-admin USER=… PASS=… Run flask create-admin inside the container
make update-mitre Fetch the latest MITRE STIX 2.1 Enterprise bundle into backend/data/mitre/; auto-restart the container if running. Commit the resulting file change manually.
make test-backend pytest -q inside the container
make test-frontend npm run test -- --run in frontend/
make test-e2e Playwright acceptance suite (container must be running)
make clean Remove container + volume + Python/Node caches
make open-pr TITLE="…" BODY=path Open a PR on the Gitea repo for the current branch via the REST API. Reads credentials from ~/.git-credentials (same source as git push) — no token in env. Wraps scripts/open-pr.sh. Defaults BASE=main.

Development (without Docker)

Backend:

cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export MIMIC_JWT_SECRET=dev-secret
export MIMIC_DB_PATH=./mimic.sqlite
flask --app backend.app:create_app db upgrade
flask --app backend.app:create_app run --port 5000

Frontend:

cd frontend
npm install
npm run dev          # http://localhost:5173 with /api proxied to :5000

Tests:

cd backend && pytest -q                # 193 tests
cd frontend && npm run test -- --run   # 92 tests
cd e2e && npx playwright test          # 158 tests (needs container up — use MIMIC_BASE_URL=http://127.0.0.1:5000 if localhost resolves to IPv6)

Documentation


License

Internal project — not yet open-sourced.

Description
No description provided
Readme 9.2 MiB
Languages
TypeScript 59.7%
Python 39%
CSS 0.5%
Shell 0.4%
Makefile 0.2%
Other 0.1%