Files
Charon/docs/reports/qa_crowdsec_hub_bootstrapping.md

6.9 KiB

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

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

COPY .docker/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

Verdict: PASS


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.