Project Argus — Phase 1 Verification Checklist & Evidence Pack
Card: 226 — Define Phase 1 verification checklist and evidence pack
Milestone: Access & Segmentation
Generated: 2026-07-07T23:50:04.929331+00:00
Status: 4/18 items complete (22.2%)
Phase Objective
Tighten the loose inter-VLAN rules, get MAB and MPSK live, stand up the CA. Ensure MAB-allowed ports are strictly bound by OPNsense firewall constraints.
How to use this document
- Work through each PENDING item top to bottom.
- For each item, capture the listed evidence under
posts/drafts/project-argus/evidence/phase1/<id>-*.{md,json,csv,pem,log}. - Update the item status in
verification-checklist.jsononce the evidence is captured. - Re-run the Section F audit jobs after Phase 1 cutover to confirm no regressions.
- Raise a Phase 1 close-out MR with this checklist + the evidence pack as the body once every item is COMPLETE.
A. Discovery & Planning
A1: Live network flows captured
Status: COMPLETE
Source: Card 216 (Done)
What: Run ansible-discover-network-flows CI job and produce per-host artifacts covering listening sockets, established connections, Docker containers, komodo stacks, and TrueNAS shares.
Evidence to capture:
GitLab CI job URL: <run-job>evidence/network-flows/*.json artifacts in CI jobposts/drafts/project-argus/data/argus-phase1-digest.json contains aggregated live state
Verification: Job status=success; 11 host JSON files present with non-empty raw, listening, and komodo_stacks fields.
A2: Inferred allowlist produced
Status: COMPLETE
Source: Phase 1 prep
What: Pre-audit allowlist derived from source configs and design docs.
Evidence to capture:
posts/drafts/project-argus/data/argus-phase1-allowlist.md
Verification: File exists with sections for required inter-VLAN paths.
A3: Live OPNsense + MikroTik state captured
Status: COMPLETE
Source: Card 216 (Done)
What: OPNsense REST API audit of filter rules, interfaces, routes, DHCP; MikroTik API-SSL audit of VLAN ports, bridge, IPs.
Evidence to capture:
posts/drafts/project-argus/data/opnsense-filter-rules.jsonposts/drafts/project-argus/data/mikrotik-state.jsonposts/drafts/project-argus/data/argus-phase1-diff.md
Verification: Both files exist; diff document identifies every temporary/broad rule and legacy bridge IP.
A4: Firewall rules plan written
Status: COMPLETE
Source: Card 217 (Done — closed by user, work retained)
What: Documented the proposed per-service ruleset to replace the broad temporary rules, plus a roll-out sequence and inter-VLAN matrix.
Evidence to capture:
posts/drafts/project-argus/planning/phase1/firewall-rules.mdposts/drafts/project-argus/planning/phase1/firewall-rules.json
Verification: Files exist; 43 proposed rules covering 31 public services and 12 inter-VLAN paths.
B. Firewall Policy Implementation
B1: All broad TEMPORARY rules removed
Status: PENDING
Depends on: A4
Source: planning/phase1/firewall-rules.md
What: Every “Temporary allow all - migration” rule on every internal interface in OPNsense is deleted. Explicit allowlist rules are in their place.
Evidence to capture:
OPNsense API: GET /api/firewall/filter/searchRule — must return zero rules with description containing "temporary" or "migration"OPNsense API diff: rule count drops by 8 (the broad rules)
Verification: curl -sk -u $OPN_KEY:$OPN_SECRET https://10.67.45.1/api/firewall/filter/searchRule | jq "[.rows[] | select(.description | test("temporary|migration"; "i"))] | length" returns 0
B2: All 31 public services still respond 200
Status: PENDING
Depends on: B1
Source: planning/phase1/firewall-rules.md#proposed-firewall-rules
What: Each public hostname exposed via Traefik returns 200 OK over HTTPS after the new rules take effect.
Evidence to capture:
Reachability matrix CSV: 31 rows, all status=200Curl commands: for host in traefik-routers; do curl -sI -o /dev/null -w "%{http_code} $host\n" https://$host; done
Verification: Reachability test script exits 0; log archived under evidence/phase1/b2-reachability.csv
B3: Inter-VLAN reachability matrix passes
Status: PENDING
Depends on: B1
Source: planning/phase1/firewall-rules.md#inter-vlan-matrix
What: Each required inter-VLAN path in the proposed ruleset succeeds; each non-allowed path is denied.
Evidence to capture:
evidence/phase1/b3-inter-vlan-matrix.csv — 12 positive rows (allowed) all PASS, 6 negative rows (denied) all FAIL
Verification: nmap/nc from each source VLAN to each destination/port matches the matrix.
B4: MikroTik untagged VLAN 45 ports reviewed
Status: PENDING
Source: argus-phase1-diff.md observations
What: VLAN 45 (Management) has 4 untagged access ports (ether1, ether5, ether9, ether12). Confirm they are intentional, not legacy. Document the decision per port.
Evidence to capture:
mikrotik-state.json — /interface/bridge/vlan/print sectionevidence/phase1/b4-mikrotik-vlan-45-decision.md — per-port decision table
Verification: Each of the 4 ports is annotated as “intentional management access” or “remove and reassign”.
B5: MikroTik legacy bridge IP removed
Status: PENDING
Source: argus-phase1-diff.md observations
What: The 10.0.1.34/16 address on the MikroTik bridge is non-routable legacy config. Remove or reassign.
Evidence to capture:
mikrotik-state.json — /ip/address/printOPNsense API: confirm no host route for 10.0.1.0/16
Verification: /ip/address/print shows no 10.0.1.34/16 entry.
B6: Hermes read-only users created on OPNsense + MikroTik
Status: PENDING
Source: Card 308 (Backlog)
What: A dedicated hermes user exists on each device with read-only/API-read permissions so future audits do not need temporary admin access.
Evidence to capture:
evidence/phase1/b6-hermes-users.md — creation steps + credentials location in OpenBao
Verification: Login as hermes to each device with the read-only API; confirm a write attempt is rejected with permission error.
B7: OPNsense live log shows zero unexpected denies over 7 days
Status: PENDING
Depends on: B1, B2, B3
Source: planning/phase1/firewall-rules.md#evidence-required
What: After the new rules are live, watch the OPNsense live log for 7 days. Any “default deny” hit on the new ruleset indicates a missing rule or a service not yet documented.
Evidence to capture:
OPNsense API: GET /api/diagnostics/log/firewall?limit=... filtered by 7-day windowevidence/phase1/b7-deny-analysis.md — table of every deny hit, root cause, rule added or marked-as-acceptable
Verification: Every deny hit in the 7-day window has a documented disposition in b7-deny-analysis.md.
C. Wired NAC (MAB)
C1: First MikroTik MAB-protected wired port profile implemented
Status: PENDING
Depends on: B1
Source: Card 222 (Backlog)
What: At least one MikroTik port uses MAB (MAC Authentication Bypass). The port authenticates devices via RADIUS fallback to VLAN assignment.
Evidence to capture:
MikroTik config snippet: /interface bridge port print, /radius configurationevidence/phase1/c1-mab-port-config.md
Verification: Plug a test device into the chosen port; it lands in the expected VLAN within 30s. Disconnect/reconnect: re-auth succeeds.
C2: MAB-connected ports are demonstrably constrained by firewall policy
Status: PENDING
Depends on: C1, B3
Source: project-argus.md Phase 1 exit criteria
What: MAC checks alone are not trusted. Even on MAB-authenticated ports, OPNsense must restrict which subnets the port can reach.
Evidence to capture:
OPNsense ruleset snippet showing per-MAB-VLAN restrictionsevidence/phase1/c2-mab-firewall-constraints.md
Verification: Test device in MAB VLAN cannot reach a subnet it should not (e.g. Storage from a Guest MAB port).
D. Wireless (RADIUS / MPSK)
D1: Validate wireless AP support for RADIUS-driven MPSK
Status: PENDING
Source: Card 218 (To Do)
What: Confirm whether the current AP platform (Omada) supports the intended RADIUS-driven MPSK design. Record any limitations.
Evidence to capture:
evidence/phase1/d1-ap-radius-support.md
Verification: Document records Omada controller version, RADIUS support, and any vendor quirks/fallbacks.
D2: First RADIUS-backed wireless authentication path validated
Status: PENDING
Depends on: D1
Source: project-argus.md Phase 1 exit criteria / Card 219
What: At least one wireless client successfully authenticates via RADIUS and lands in the intended VLAN.
Evidence to capture:
RADIUS server log: 1 successful auth + VLAN assignmentClient device: 1 wifi connection + 1 ip in expected VLANevidence/phase1/d2-radius-wireless-test.md
Verification: Test client gets an IP in the expected RADIUS-assigned VLAN within 30s of association.
E. PKI / Certificate Authority
E1: Certificate authority is operational for the first intended use case
Status: PENDING
Source: project-argus.md Phase 1 exit criteria / Card 225
What: Stand up the CA (OpenBao PKI or step-ca) and issue at least one certificate to a real service that uses it.
Evidence to capture:
CA cert chain (root + intermediate) in evidence/phase1/e1-ca-chain.pemIssued cert + service consuming it (e.g. Traefik dashboard, dbackup, or Infisical)evidence/phase1/e1-ca-first-use.md
Verification: Service successfully serves HTTPS with a certificate issued by the new CA, verifiable via openssl s_client -showcerts.
F. Audit & Verification Automation
F1: Re-run ansible-discover-network-flows to confirm no new unexplained ports
Status: PENDING
Depends on: B1, B7
Source: planning/phase1/firewall-rules.md#evidence-required
What: After Phase 1 firewall changes are live, re-run the discovery job. Diff the new artifacts against the baseline; any new port must have a documented owner.
Evidence to capture:
GitLab CI job URL: <re-run>evidence/phase1/f1-port-diff.md — table of new vs removed ports
Verification: Every new listening port in the post-cutover job has an entry in f1-port-diff.md explaining its purpose.
F2: OPNsense API audit job flags any new broad rules within 24h
Status: PENDING
Depends on: B6
Source: planning/phase1/firewall-rules.md#next-steps
What: A scheduled job (cron + ansible) checks OPNsense for any rules matching “any any”, “allow all”, or “temporary” patterns. Alert via ntfy if found.
Evidence to capture:
Cron job config + last 7 days of "clean" runsevidence/phase1/f2-audit-job-config.md
Verification: A test that re-adds a broad rule is detected and reported within 24h.
Summary
- Total items: 18
- Complete: 4
- Pending: 14
- Blocked: 0
- Percent complete: 22.2%
Tools & Credentials Required
- ansible-playbook (machines/ansible-playbooks)
- OPNsense REST API credentials (in OpenBao after Card 308)
- MikroTik API-SSL credentials (in OpenBao after Card 308)
- OpenBao or equivalent secret store for new credentials
Remediation Workflow
- For each PENDING item: run the verification step, capture evidence under evidence/phase1/-*.{md,json,csv,pem,log}
- Update the item status to COMPLETE in this file once evidence is captured
- Re-run Section F audit jobs to confirm no regressions
- Once all items COMPLETE, raise the Phase 1 close-out MR with this checklist + evidence pack as the body
Verify this post
This page is published as a PGP clearsigned document. You can verify it like this:
gpg --keyserver hkps://keys.openpgp.org --recv-keys CA98D5946FA3A374BA7E2D8FB254FBF3F060B796
curl -fsSL 'https://eddiequinn.xyz/sigs/posts/drafts/project-argus/planning/phase1/verification-checklist.txt' | gpg --verify