Skip to content

feat: list installed CrowdSec hub items in exports and offer to install missing ones after an import - #1561

Merged
Wikid82 merged 8 commits into
developmentfrom
feat/crowdsec-hub-items-restore
Oct 11, 2026
Merged

Wikid82 merged 8 commits into
developmentfrom
feat/crowdsec-hub-items-restore

Conversation

@Wikid82

@Wikid82 Wikid82 commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Summary

Completes the CrowdSec export/import follow-ups from #1549/#1553 in one PR. The commits are ordered fixes first, then the feature.

Closes #1545, closes #1546, closes #1547

  • chore: translate the CrowdSec export success and failure toasts #1547: the export and import toasts and the export file-name prompt are translated in all five locales; promptCrowdsecFilename(t, defaultName) takes the translation function like rateLimit.ts.
  • chore: review notification settings in the CrowdSec export and check for missing notification files before import #1546: an import is refused before anything is changed when a profile names a notification that no notification file in the archive defines. The check follows what the bundled CrowdSec (v1.8.1) actually does: matching is by the name: field inside the file, multi-document files define every name, and only lowercase .yaml/.yml files directly in notifications/ count. It skips instead of refusing when it cannot decide (unparsable files, redirected paths, oversized entries, no profiles file). Refusal returns a fixed 422 message listing at most 10 sorted names. Redaction of notification values stays a follow-up (feat: redact sensitive values in notification files when exporting a CrowdSec configuration #1551).
  • chore: restore the installed CrowdSec hub item set when moving a configuration to a different host #1545: an export now records the installed hub items by name and type in a small manifest (charon-hub-items.json, derived from the installed links, no cscli call, never extracted to disk). An import reports hub_items.missing (items in the export that this system lacks). A new admin action POST /api/v1/admin/crowdsec/hub-items/restore installs them from the official hub, one item at a time: strict mixed-case owner/name validation and a type allowlist, literal cscli with no shell, a single-flight guard (409), the data lock held for one hub operation at a time with a per-item time bound, verified installs, retryable not_attempted items with a remaining count, and a best-effort reload on a detached context. The CrowdSec page shows an inline, non-intrusive panel after an import (button "Install missing hub items", "Install remaining").
  • Shared helpers: ValidHubItemName (mixed case) for the manifest and restore, with the strict lowercase ValidPresetItemName kept for curated presets; verifyItem extracted as an exported function; ParseYAMLDocuments moved into the crowdsec package.

Testing

  • Backend coverage 91.4% statements / 90.4% lines; frontend 91.52% lines; patch coverage 94.8% (637/672 changed lines). Full golangci-lint config clean (backend and agent); go test -race on the touched packages and -count=2/3 on the new tests; the full handlers package passes (387 s). Local CodeQL: Go "4 suppressed, 0 blocking" (existing entries only), JS 0.
  • E2E (--project=security-tests, no fixme left): the hub-items, import, config, diagnostics, file-editor and zzz import specs pass on a fresh charon-e2e. Valid restore requests and the 409 are covered by Go tests with a fake executor, because the E2E container's hub reachability is environment-dependent and a real restore installs items.
  • A QA audit (docs/reports/qa_report.md) found no critical, high or medium issues. It verified the endpoint live: unauthenticated 401, user role 403, hostile names (flags, .., NUL, newlines, look-alike characters, =, spaces, over-long) all 400, oversized body 413, alias-expansion documents rejected in 1-2 ms.

Manual check in throwaway containers (not the live proxy), real hub, HEAD before the final docs/QA commits

Step Result
Restore on A: 2 real items + 1 bogus name 200 in 0.81 s; both real items installed (plus 3 dependency links), bogus item reported not_found, reloaded: true, CrowdSec kept running (same PID)
Export from A 200, 22 KB, 61-item manifest, no hub/runtime/credential entries
Import into fresh B 200; hub_items.missing listed the 5 extra items; B's links unchanged (import installs nothing)
Restore on B with exactly missing 200 in 0.59 s; B's collections hash equals A's (61 links each); a second restore reports everything already_installed
Ten real collections on B 34.5 s, 10 installed; a parallel restore got 409 in 4 ms; an import during it lost nothing (all links survived)
Notification check with a real archive 422 in 6 ms, config hashes and file count unchanged, no backup created; the same archive plus the notification file: 200
Offline restart (--network none) the non-fatal hub-update failure was logged, CrowdSec started, links and collections hash unchanged; a restore while offline returned 502 in 59 ms, nothing changed

Notes

An import whose profiles reference notifications that the archive does not
define is now refused before anything is changed.
An export now lists the installed hub items by name and type, and an import
reports which of them are not installed on the target system.
A new admin action installs hub items that an imported configuration lists but
the system does not have, one item at a time, and reports what happened.
After an import, the CrowdSec page lists the hub items the export names but this
system does not have, and offers to install them with a clear result.
Explain the installed hub item list in an export, the action that installs
missing items after an import, and the check on notification references.
@github-advanced-security

Copy link
Copy Markdown
Contributor

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Supply Chain Verification Results

✅ PASSED

📦 SBOM Summary

  • Components: 1870

🔍 Vulnerability Scan

Severity Count
🔴 Critical 0
🟠 High 0
🟡 Medium 0
🟢 Low 0
Total 0

📎 Artifacts

  • SBOM (CycloneDX JSON) and Grype results available in workflow artifacts

Generated by Supply Chain Verification workflow • View Details

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants