v1.3.32 -- Pre-public verification (no new feature scope)¶
A focused diagnostic release: ran every existing smoke against the live prod stack, identified coverage gaps in the v1.3.20+ EFFECT-smoke regime, and shipped 4 new smoke scripts to close the highest-priority ones. Zero feature changes; the panel binary at v1.3.32 is functionally identical to v1.3.31.
The output is a single-source verification matrix in docs/operations/verification-report.md that future releases can re-run before tagging. It maps every shipped feature to its smoke (or documents why no smoke exists), reaches a "ready for public" verdict, and locks in the gotchas mid- implementation surfaced (jq envelope shape, ListDecisions cache TTL, delete-response shape).
Why a release for this¶
Going public means the smoke regime becomes the operator- visible quality contract. Today's regime had blind spots: host CRUD wasn't smoke-tested even though it's the most-used panel surface; manual whitelist enforcement had no test at the parser-yaml level; the Banned IPs UI had no round-trip gate. Closing those before the GitHub stars start arriving is cheaper than discovering a regression in the Issues tab.
Verification matrix (12 PASS, 1 deferred, 1 legacy-skip)¶
| Feature | Smoke | Status |
|---|---|---|
| Sync-prod operator tooling | sync-prod.sh | PASS (5/5) |
| LAPI SQLite WAL (v1.3.28) | lapi-wal.sh | PASS (3/3) |
| Scenario descriptions (v1.3.30) | scenario-descriptions.sh | PASS (5/5) |
| Scenarios management (v1.3.25) | scenarios-toggle.sh | PASS (8/8) |
| AppSec tuning (v1.3.25) | appsec-tuning.sh | PASS (6/6) |
| Drift detection (v1.3.27) | drift-detection.sh | PASS (12/12) |
| True detect mode (v1.3.29) | true-detect-mode.sh | PASS (8/8) |
| Country expansion async (v1.3.31) | country-expansion-async.sh | PASS (4/4 happy) |
| Host CRUD + Caddy reconcile | host-crud.sh (new) | PASS (7/7) |
| Whitelist round-trip | whitelist-roundtrip.sh (new) | PASS (8/8) |
| Banned IPs round-trip | banned-ips-roundtrip.sh (new) | PASS (5/5) |
| Authentication lifecycle | auth-flow.sh (new) | DEFERRED (operator-cred gated) |
| Country expansion legacy | country-block.sh | SKIP (regression test for an upstream-broken path) |
What ships¶
Four new smoke scripts (operator-runnable; placeholder defaults; ASCII / sanitised)¶
auth-flow.sh: POST /api/auth/login -> 200 + cookie -> GET /me -> POST /logout -> GET /me 401. Detectsrequires_totpresponse and exits PASS-PARTIAL when 2FA is enabled. Operator passesARGOS_USERNAME+ARGOS_PASSWORD. Creates and disposes its own session; does NOT touch the operator's other-smoke session token.host-crud.sh: 7 phases. POST /api/hosts (placeholdertest-smoke-XXXXX.exampledomain bound to the first existing target group) -> GET echoes -> toggle flips enabled -> PUT updates auth_required -> DELETE -> 404 -> GET /api/caddy/status confirms the reconciler->Caddy chain reachable. Random suffix on the test domain so a crashed-mid-flight rerun doesn't UNIQUE-collide.whitelist-roundtrip.sh: 8 phases. POST adds a 198.51.100.42 (RFC 5737) entry -> GET shows it -> /shared/argos-whitelist-entries.txt sentinel updated -> setup-appsec.sh -> /etc/crowdsec/parsers/s02-enrich/argos- whitelist.yaml carries the IP -> DELETE -> sentinel + yaml both clean again. Pre-flight sweeps stale entries from prior crashed runs.banned-ips-roundtrip.sh: 5 phases. cscli decisions add -> wait 17s (Client.ListDecisions has a 15s cache TTL) -> GET /api/security/decisions lists with origin=cscli -> DELETE /api/security/decisions/{id} -> cscli decisions list confirms gone -> panel list also shows gone.
Verification report¶
docs/operations/verification-report.md is the new ops page. Maps every shipped feature to a smoke or to a documented coverage-gap rationale. Includes:
- Smoke matrix with per-script verifies-what summary
- Coverage gaps with explanations (why we didn't write a smoke for it; mitigation if any)
- "Ready for public" verdict
- Re-run instructions
- What this report does NOT prove (frontend visual rendering, load behaviour, cross-version migration)
Mid-implementation gotchas (caught + fixed pre-tag)¶
These are now documented in the smokes' comments + the verification report:
/api/security/whitelistreturns{"entries": [...]}envelope. Initialjq '.[]'errored "Cannot index array with string 'value'".crowdsec.Client.ListDecisions15s cache TTL. Initial smoke waited 1s after cscli add and saw an empty panel response (false negative). Bumped to 17s.- DELETE response shape:
{"deleted": 1, "id": <N>}(integer count, not boolean). Adjusted the assertion to.deleted >= 1 or .ok == true.
Coverage gaps NOT addressed in v1.3.32¶
Documented in the verification report; every gap has either "low incident risk + read-only" or "external dependency" rationale. Not blockers for going public:
- Recovery CLI (
reset-password,disable-2fa,migrate,restore) - Self-block detection / banner v2 (would break operator's connectivity to test)
- Activity / audit log (read-only)
- Dashboard widget (aggregated counters; verified implicitly)
- TOTP / 2FA enrollment, OIDC SSO end-to-end (operator- mediated)
- Backup + restore round-trip (operator-mediated; tearing down panel mid-test would conflict with parallel smokes)
- Notifications (would spam real channels)
- Reverse-proxy healthcheck propagation (would need a stub backend; out of scope for single-stack homelab smoke)
Recommendation¶
Zero blockers preventing public release. All in-scope smokes PASS. The deferred auth-flow smoke is committed and ready for the operator to invoke with their credentials; the underlying handlers are exercised indirectly by every other session-bearing smoke.
The repo is functionally ready for gh repo edit --visibility public.
Files changed¶
scripts/smoke/auth-flow.sh(new)scripts/smoke/host-crud.sh(new)scripts/smoke/whitelist-roundtrip.sh(new)scripts/smoke/banned-ips-roundtrip.sh(new)docs/operations/verification-report.md(new)backend/cmd/argos/main.go+frontend/package.json(version 1.3.31 -> 1.3.32)CHANGELOG.md,mkdocs.ymldocs/release-notes/v1.3.32.md(this file)
Not changed¶
- All v1.3.31 backend / frontend / migration code unchanged.
- All other smokes unchanged.
- Panel binary functionally identical to v1.3.31; the version string bump is the only diff.
Upgrade¶
This release is operator-tooling only (smokes + docs + version bump). Pull + sync; no panel rebuild required for the smokes alone, but bump the panel image so the version string reflects the verified state:
cd ~/argos-edge && git pull
make sync-prod # picks up the 4 new smokes
# + the verification report
cd ~/argos-prod
docker build -f backend/Dockerfile -t argos-prod-argos:v1.3.32 .
# update docker-compose.override.yml: image: argos-prod-argos:v1.3.32
docker compose up -d --force-recreate --no-deps argos
Then re-run the verification matrix:
SESSION=$(docker run --rm -v argos_prod_data:/data alpine sh -c \
"apk add --no-cache sqlite >/dev/null 2>&1
sqlite3 /data/argos.db \"SELECT token FROM sessions
WHERE expires_at > datetime('now')
ORDER BY id DESC LIMIT 1;\"")
for s in scripts/smoke/*.sh; do
case "$(basename $s)" in
country-block.sh|auth-flow.sh) continue ;; # operator-mediated
esac
ARGOS_SESSION_TOKEN="${SESSION}" \
PANEL_BASE_URL=http://localhost:9180 \
CROWDSEC_CONTAINER=argos-prod-crowdsec \
COMPOSE_DIR=$HOME/argos-prod \
SKIP_FAILURE_PATH=1 \
TEST_HOST=your-test-host.example.com \
TEST_SCENARIO=crowdsecurity/CVE-2017-9841 \
"$s" || echo "FAILED: $s"
done