Skip to content

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. Detects requires_totp response and exits PASS-PARTIAL when 2FA is enabled. Operator passes ARGOS_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 (placeholder test-smoke-XXXXX.example domain 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/whitelist returns {"entries": [...]} envelope. Initial jq '.[]' errored "Cannot index array with string 'value'".
  • crowdsec.Client.ListDecisions 15s 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.yml
  • docs/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