# QA Report: CrowdSec Hub Bootstrapping Fix **Date:** 2026-04-05 **Scope:** `.docker/docker-entrypoint.sh`, `configs/crowdsec/install_hub_items.sh`, `scripts/crowdsec_startup_test.sh` **Status:** PASS --- ## 1. Shell Script Syntax Validation (`bash -n`) | File | Result | |------|--------| | `.docker/docker-entrypoint.sh` | ✓ Syntax OK | | `configs/crowdsec/install_hub_items.sh` | ✓ Syntax OK | | `scripts/crowdsec_startup_test.sh` | ✓ Syntax OK | **Verdict:** PASS — All three scripts parse without errors. --- ## 2. ShellCheck Static Analysis (v0.9.0) | File | Findings | Severity | |------|----------|----------| | `.docker/docker-entrypoint.sh` | SC2012 (L243): `ls` used where `find` is safer for non-alphanumeric filenames | Info | | `configs/crowdsec/install_hub_items.sh` | None | — | | `scripts/crowdsec_startup_test.sh` | SC2317 (L70,71,84,85,87-90): Functions in `trap` handler flagged as "unreachable" (false positive — invoked indirectly via `trap cleanup EXIT`) | Info | | `scripts/crowdsec_startup_test.sh` | SC2086 (L85): `${CONTAINER_NAME}` unquoted in `docker rm -f` | Info | **Verdict:** PASS — All findings are informational (severity: info). No warnings or errors. The SC2317 findings are false positives (standard `trap` pattern). The SC2086 finding is pre-existing and non-exploitable (variable is set to a constant string `charon-crowdsec-startup-test` without user input). --- ## 3. Pre-commit Hooks (Lefthook v2.1.4) | Hook | Result | |------|--------| | check-yaml | ✓ Pass | | actionlint | ✓ Pass | | end-of-file-fixer | ✓ Pass | | trailing-whitespace | ✓ Pass | | dockerfile-check | ✓ Pass | | shellcheck | ✓ Pass | **Verdict:** PASS — All 6 applicable hooks passed successfully. --- ## 4. Security Review ### 4.1 Secrets and Credential Exposure | Check | Result | |-------|--------| | Hardcoded secrets in changed files | None found | | API keys/tokens in changed files | None found | | Gotify tokens in logs/output/URLs | None found | | Environment variable secrets exposed via `echo` | None — all `echo` statements output status messages only | **Verdict:** PASS ### 4.2 Shell Injection Vectors | Check | Result | |-------|--------| | User input used in commands | No user-controlled input enters any command. All variables are set from hardcoded paths | | `eval` usage | None | | Unquoted variable expansion in commands | All critical variables are quoted or hardcoded strings | | Command injection via hub item names | Not applicable — all `cscli` arguments are hardcoded collection/parser names | **Verdict:** PASS ### 4.3 `timeout` Usage Safety The entrypoint uses `timeout 60s cscli hub update 2>&1`: - `timeout` is the coreutils version (Alpine `busybox` timeout), sending SIGTERM after 60s - Prevents indefinite hang if hub CDN is unresponsive - 60s is appropriate for a single HTTPS request with potential DNS resolution - Failure is handled gracefully — logged as warning, startup continues **Verdict:** PASS ### 4.4 `--force` Flag Analysis All `--force` flags are on `cscli` install commands: - `--force` in `cscli` context means "re-download and overwrite if already installed" — functionally an upsert - Does NOT bypass integrity checks or signature verification - Does NOT skip CrowdSec's hub item hash validation - Ensures idempotent behavior on every startup **Verdict:** PASS ### 4.5 Error Visibility Changes The diff changes `2>/dev/null || true` patterns to `|| echo "⚠️ Failed to install ..."`: - **Before:** Errors silently swallowed - **After:** Errors logged with descriptive messages - This is a security improvement — silent failures can mask missing detection capabilities **Verdict:** PASS — Improved error visibility is a positive security change. ### 4.6 Deprecated Environment Variable Removal | Check | Result | |-------|--------| | `SECURITY_CROWDSEC_MODE` removed from entrypoint | ✓ env var gate deleted | | `CERBERUS_SECURITY_CROWDSEC_MODE=local` removed from startup test | ✓ removed from `docker run` | | No remaining references in changed files | ✓ only documentation files reference it (as deprecated) | | Backend config still reads `CERBERUS_SECURITY_CROWDSEC_MODE` | ✓ backend uses different var names via `getEnvAny()` | **Verdict:** PASS --- ## 5. Dockerfile Consistency ### 5.1 `install_hub_items.sh` Copy ```dockerfile COPY configs/crowdsec/install_hub_items.sh /usr/local/bin/install_hub_items.sh RUN chmod +x /usr/local/bin/install_hub_items.sh /usr/local/bin/register_bouncer.sh ``` Copy path matches entrypoint invocation path (`-x /usr/local/bin/install_hub_items.sh`). **Verdict:** PASS ### 5.2 Build-Time vs Runtime Conflict Check | Concern | Analysis | |---------|----------| | Build-time `cscli hub update` | Not performed in Dockerfile | | Build-time collection install | Not performed in Dockerfile | | Conflict with runtime approach | None — all hub operations deferred to container startup | **Verdict:** PASS ### 5.3 Entrypoint Reference ```dockerfile COPY .docker/docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh ``` **Verdict:** PASS --- ## 6. Related Tests and CI | Test | Location | Status | |------|----------|--------| | `scripts/crowdsec_startup_test.sh` | Modified in this PR | Updated — no longer passes deprecated env var | | Backend config tests | `backend/internal/config/config_test.go` | Unchanged, still valid | | CrowdSec-specific CI workflows | None exist | N/A | The startup test script is the primary validation mechanism for hub bootstrapping. The E2E Playwright suite covers CrowdSec UI but not hub bootstrapping directly. --- ## 7. Change Summary and Risk Assessment | Change | Risk | Rationale | |--------|------|-----------| | Unconditional `cscli hub update` on startup | Low | Adds ~2-5s. Prevents stale-index hash mismatch. `timeout 60s` prevents hangs. Failure is graceful. | | Removed `SECURITY_CROWDSEC_MODE` env var gate | Low | Env var was deprecated and never set. Collections are idempotent config files with zero runtime cost. | | Added `crowdsecurity/caddy` collection | Low | Standard CrowdSec collection for Caddy. Installed via `--force` (idempotent). | | Removed `2>/dev/null` from `cscli` install commands | Low (positive) | Errors now visible in container logs. | | Removed redundant `cscli hub update` from `install_hub_items.sh` | Low | Prevents double hub update (~3s saved). | | Removed deprecated env var from startup test | Low | Test matches actual container behavior. | --- ## 8. Overall Verdict | Category | Status | |----------|--------| | Shell syntax | ✅ PASS | | ShellCheck | ✅ PASS (info-only findings) | | Pre-commit hooks | ✅ PASS | | Security: secrets/credentials | ✅ PASS | | Security: injection vectors | ✅ PASS | | Security: `timeout` safety | ✅ PASS | | Security: `--force` flags | ✅ PASS | | Dockerfile consistency | ✅ PASS | | Deprecated env var cleanup | ✅ PASS | | CI/test coverage | ✅ PASS | **Overall: PASS — No blockers. Ready for merge.**