2026-05-21 20:10:47 +02:00
|
|
|
# Spec decisions log
|
|
|
|
|
|
|
|
|
|
This file tracks implementation arbitrations *on top* of the frozen spec
|
|
|
|
|
(`Projects/Mimic — Spec.md` in the RT-SecondBrain vault).
|
|
|
|
|
|
|
|
|
|
Format: one entry per decision, newest first.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 2026-05-21 — Team kickoff decisions
|
|
|
|
|
|
|
|
|
|
### D-001 — SOC collaboration hypothesis
|
|
|
|
|
**Context.** Devils-advocate flagged the sociological assumption that SOC analysts
|
|
|
|
|
will cote in the live cockpit.
|
|
|
|
|
**Decision.** Hypothesis accepted as-is. No paper PoC. Risk owned by lead RT.
|
|
|
|
|
|
|
|
|
|
### D-002 — Mimic deployment location
|
|
|
|
|
**Context.** Spec §6 NF-network did not pin where Mimic is physically deployed.
|
|
|
|
|
**Decision.** Mimic runs on RT infrastructure. SOC client connects through the
|
|
|
|
|
existing RT reverse proxy (Caddy, out of Mimic scope). Mimic → Mythic / Home C2
|
|
|
|
|
through outbound VPN. RT R&D (TTP library, stealthy variants) never sits on
|
|
|
|
|
client premises.
|
|
|
|
|
|
|
|
|
|
### D-003 — Authentication strategy
|
|
|
|
|
**Context.** Spec mentions OIDC Keycloak but lab onboarding cost is high.
|
|
|
|
|
**Decision.** v1 ships **local auth** (username/password, bcrypt, Flask server-side
|
|
|
|
|
sessions). v2 adds Keycloak OIDC. The RBAC model is **group-based from day one**,
|
|
|
|
|
so OIDC will map claims to existing groups without touching application code.
|
|
|
|
|
SOC sessions remain a distinct mechanism (`soc_session.token_opaque` bcrypt hash,
|
|
|
|
|
clear token out-of-band).
|
|
|
|
|
|
|
|
|
|
### D-004 — C2 credential storage (T2)
|
|
|
|
|
**Context.** Engagement.config_json (encrypted JSON column) vs dedicated table.
|
|
|
|
|
**Decision.** Dedicated table `c2_credential (id, engagement_id, c2_type,
|
|
|
|
|
config_json_fernet, version, created_at, retired_at)`. Active row per engagement =
|
|
|
|
|
`retired_at IS NULL`, highest version. Rotation = insert + retire previous.
|
|
|
|
|
Fernet key in env, never in DB.
|
|
|
|
|
|
|
|
|
|
### D-005 — Cleanup template variable sources (T3)
|
|
|
|
|
**Context.** Jinja `{{outputs.X}}` source ambiguity.
|
|
|
|
|
**Decision.** Two accessors:
|
|
|
|
|
- `{{outputs.text}}` → `run_step.output_text` (stdout/UTF-8 text).
|
|
|
|
|
- `{{outputs.blob("<key>")}}` → reads from `output_blob_ref`, hard cap **10 MB**
|
|
|
|
|
(consistent with F8 evidence limit), UTF-8 decoding with latin-1 fallback,
|
|
|
|
|
silent refusal + log entry if the blob is non-decodable.
|
|
|
|
|
`regex_extract` always operates on the resulting string.
|
|
|
|
|
|
|
|
|
|
### D-006 — SOC session token storage (T4)
|
|
|
|
|
**Context.** `soc_session.token_opaque` storage form.
|
|
|
|
|
**Decision.** bcrypt hash. Clear token generated server-side at session creation,
|
|
|
|
|
returned **once** in the API response, delivered out-of-band to the SOC analyst.
|
|
|
|
|
Never re-displayable.
|
|
|
|
|
|
|
|
|
|
### D-007 — Reverse proxy scope
|
|
|
|
|
**Context.** Mimic exposure to internet for SOC client access.
|
|
|
|
|
**Decision.** Reverse proxy (Caddy + TLS + IP allowlist) handled by existing RT
|
|
|
|
|
infrastructure. Mimic ships an HTTP listener on localhost only; the deployment
|
|
|
|
|
playbook wires it behind the existing proxy.
|
2026-05-21 20:13:14 +02:00
|
|
|
|
|
|
|
|
### D-008 — Group-based RBAC vs spec F11 fixed roles
|
|
|
|
|
**Context.** Spec F11 declares 3 fixed roles (`rt_operator`, `rt_lead`,
|
|
|
|
|
`soc_analyst`) with an explicit permission matrix. Sprint 0 plan (B0.6, D-003)
|
|
|
|
|
introduces `group` / `permission` / `group_permission` / `user_group` tables to
|
|
|
|
|
prepare OIDC v2 claim-to-group mapping without code change.
|
|
|
|
|
**Decision.** Group-based model accepted as an implementation *layout*, **not** a
|
|
|
|
|
scope extension:
|
|
|
|
|
- The 3 spec roles MUST exist as the 3 seeded groups at bootstrap
|
|
|
|
|
(`rt_operator`, `rt_lead`, `soc_analyst`).
|
|
|
|
|
- The F11 permission matrix is the canonical source: groups receive exactly the
|
|
|
|
|
permissions of their matching role; no custom permissions UI v1.
|
|
|
|
|
- Custom groups, group editing UI, or per-engagement group overrides = OUT of v1.
|
|
|
|
|
- Any drift between seeded group permissions and the F11 matrix is a spec
|
|
|
|
|
violation, not a configuration choice.
|
|
|
|
|
|
chore: tighten gitignore, align README stack, formalize D-010 (Ansible)
- .gitignore: add Keycloak/Mythic/Fernet secret patterns (pfx, p12, token, kdbx,
credentials.json, secrets.json, service-account*.json), MSVC artifacts
(lib, exp, idb, ilk, tlog), dedup dist/build/ between Python and Node blocks.
- README.md: align Storage line on H38 (testcontainers Postgres for Postgres-
specific behavior, incl. unit tests of audit log / RBAC / write-only role).
- README.md: align Deploy line on D-007/D-010 — Docker + Ansible playbook,
reverse proxy explicitly out-of-Mimic.
- README.md: add proprietary internal use notice.
- CHANGELOG.md: convert markdown link to inline URL (no dangling reference).
- tasks/spec-decisions.md: add D-010 (Ansible for deployment playbook).
Addresses code-reviewer M1/M2/M3 + N2/N3/N4/N6 on commit 047583e.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 20:16:40 +02:00
|
|
|
### D-010 — Ansible for the deployment playbook
|
|
|
|
|
**Context.** Spec §7 names `Docker` only on the deploy line, but D-007 references
|
|
|
|
|
a "deployment playbook" wiring Mimic behind the existing reverse proxy. The RT
|
|
|
|
|
team uses Ansible for infrastructure automation across projects.
|
|
|
|
|
**Decision.** Deployment artifacts are Docker images (built in repo) plus an
|
|
|
|
|
Ansible playbook (lives outside the application repo, in the RT infra repo).
|
|
|
|
|
Mimic itself ships only the Dockerfile and a sample compose for dev; production
|
|
|
|
|
roll-out is Ansible-driven. The README stack line is updated accordingly.
|
|
|
|
|
|
2026-05-21 20:13:14 +02:00
|
|
|
### D-009 — `ttp_version` table forbidden (H32 reaffirmed)
|
|
|
|
|
**Context.** Sprint 0 plan (B0.2) lists `ttp_version` among the initial tables.
|
|
|
|
|
Spec hypothesis **H32** explicitly excludes this: *"Snapshot de rejouabilité =
|
|
|
|
|
`run.snapshot_json` uniquement (pas de table `ttp_version` séparée —
|
|
|
|
|
simplification MVP)"*.
|
|
|
|
|
**Decision.** Drop `ttp_version` from the initial migration. The `ttp.version`
|
|
|
|
|
column (informational, §8) is kept. Replayability lives **solely** on
|
|
|
|
|
`run.snapshot_json`. Re-introducing `ttp_version` requires explicit spec amendment
|
|
|
|
|
through the team-lead.
|