Skip to content

Fix lab automation: 8 bugs blocking make lab-up + verified C2 boot#42

Merged
AndrewAltimit merged 1 commit into
mainfrom
automation-review
May 14, 2026
Merged

Fix lab automation: 8 bugs blocking make lab-up + verified C2 boot#42
AndrewAltimit merged 1 commit into
mainfrom
automation-review

Conversation

@AndrewAltimit
Copy link
Copy Markdown
Owner

Summary

Audit of the Makefile, requirements files, CI, and lab images turned up eight bugs that prevented a clean checkout from booting the lab. All are fixed and verified end-to-end by building images and hitting the C2 operator API from the host.

  • tools/idol/01-credential-harvest.py:134NameError: name 'targets' is not defined. Extracted _credential_targets() helper. Hidden because tools/idol/tests/ was not wired into CI; now it is.
  • 5 mock-* Dockerfiles (mock-imds, mock-entra, mock-slack, mock-oauth, mock-graph) COPYed requirements.txt files deleted in the uv-workspace migration (commit 1bdeeeb). Replaced with inline pip install matching the existing Dockerfile.beacon / Dockerfile.c2-server pattern.
  • Dockerfile.c2-server and Dockerfile.exploit-serveruseradd operator failed because python:*-slim has the Debian-legacy operator:x:37 system group. Use -g operator operator to reuse it.
  • Dockerfile.c2-server missing depstools/c2/server.py imports cryptography and pyjwt; only flask requests was installed.
  • ContainmentGuard.assert_loopback rejected 0.0.0.0, blocking the server from binding inside the container. Now allowed only when in_docker() is true; host port mapping remains loopback-only.
  • docker-compose.lab.yml declared internal: true and ports: on every service — Docker silently drops the publication. Added a lab-bridge network for user-facing services; beacons stay on lab-internal only. ContainmentGuard continues enforcing loopback/RFC1918 at the tool layer.
  • make lab-arc-up / lab-arc-down referenced infra/lab/mock-imds/Dockerfile and mock_imds.py, neither of which exists. The existing mock-imds server already serves the Azure Arc MSI endpoint unconditionally — target now just ensures the compose service is up.
  • 6 ci/check_*.py gates were advertised in tool READMEs as CI gates but never invoked by either workflow. Wired all six into the Repo hygiene step.

While here: bumped python:3.12-slim to python:3.14-slim across the 9 Dockerfiles and the phishing compose fragment.

Test plan

  • Branched off main, no merge conflicts
  • uv sync --all-packages clean
  • All 9 hygiene checks pass (tools/ci/check_*.py and ci/check_*.py)
  • pytest — 108 passed, 3 skipped (was 44; tools/idol/tests/ adds 64)
  • Rust workspace builds + all tests pass (cargo test --workspace -- --test-threads=1)
  • Dashboard builds (reports/databricks-apps-assessment/build.py)
  • All Dockerfiles build cleanly (docker compose build)
  • docker compose up -d c2-server publishes 127.0.0.1:8443->8443/tcp
  • curl http://127.0.0.1:8443/api/status from host returns HTTP 401 {"error":"unauthorized"} (AuthGuard correctly rejecting unauthenticated call)
  • CI run on this branch is green

Generated with Claude Code

Audit of the Makefile, requirements files, CI, and lab images uncovered
eight bugs that prevented a clean checkout from booting the lab. All are
fixed and verified by building images and curling the C2 operator API
from the host.

- tools/idol/01-credential-harvest.py: NameError on `targets` (out of
  scope after a refactor). Extracted _credential_targets() helper and
  wired tools/idol/tests/ into both CI workflows so a future regression
  is caught.
- 5 mock-* Dockerfiles (mock-imds, mock-entra, mock-slack, mock-oauth,
  mock-graph) COPYed requirements.txt files that were deleted in the
  uv-workspace migration. Replaced with inline pip install matching the
  Dockerfile.beacon / c2-server pattern.
- Dockerfile.c2-server and Dockerfile.exploit-server: `useradd operator`
  fails because python:*-slim has a Debian-legacy `operator:x:37` system
  group. Use `-g operator operator` to reuse it.
- Dockerfile.c2-server was missing cryptography and pyjwt, both used by
  tools/c2/server.py at import time.
- ContainmentGuard.assert_loopback rejected 0.0.0.0, blocking the server
  from binding inside the container. Allow 0.0.0.0 only when in_docker()
  is true; the host port mapping is still loopback-only.
- docker-compose.lab.yml declared `internal: true` AND `ports:` on every
  service, which docker silently drops. Added a lab-bridge network for
  the user-facing services so host port publication works; beacons stay
  on lab-internal only. ContainmentGuard continues to enforce
  loopback/RFC1918 at the tool layer.
- make lab-arc-up/down referenced infra/lab/mock-imds/Dockerfile and
  mock_imds.py, neither of which exists. The mock-imds server already
  serves the Azure Arc MSI endpoint unconditionally, so the target now
  just ensures the existing compose service is up.
- The six ci/check_*.py gates were advertised in tool READMEs as CI
  gates but never invoked by either workflow. Wired all six into the
  Repo hygiene step.

While here, bumped python:3.12-slim to python:3.14-slim across all
nine Dockerfiles and the phishing compose fragment.

Verified end-to-end: docker compose up -d c2-server publishes
127.0.0.1:8443, and `curl http://127.0.0.1:8443/api/status` from the
host returns HTTP 401 {"error":"unauthorized"} — AuthGuard rejecting
the unauthenticated operator API call, which is the expected behavior.
Pytest 108 passed / 3 skipped, all 9 hygiene checks pass, Rust workspace
builds and tests pass, dashboard builds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AndrewAltimit AndrewAltimit merged commit a0b9219 into main May 14, 2026
2 checks passed
@AndrewAltimit AndrewAltimit deleted the automation-review branch May 14, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant