From 54085680c5a7b766a1c85753df66713ba3f161e4 Mon Sep 17 00:00:00 2001 From: jdv Date: Wed, 22 Apr 2026 20:33:24 +0200 Subject: [PATCH 01/18] home refresh v0.1 --- .gitignore | 3 +- .../src/components/integration-tile.tsx | 101 +++ crowdsec-docs/src/pages/index.tsx | 616 +++++++++++++++--- .../static/img/blaas/logo-checkpoint.png | Bin 0 -> 15620 bytes crowdsec-docs/static/img/blaas/logo-cisco.png | Bin 0 -> 17492 bytes .../static/img/blaas/logo-default.png | Bin 0 -> 20632 bytes crowdsec-docs/static/img/blaas/logo-f5.png | Bin 0 -> 32048 bytes .../static/img/blaas/logo-fortinet.png | Bin 0 -> 6117 bytes .../static/img/blaas/logo-juniper.png | Bin 0 -> 7648 bytes .../static/img/blaas/logo-mikrotik.png | Bin 0 -> 10153 bytes .../static/img/blaas/logo-opnsense.png | Bin 0 -> 16531 bytes .../static/img/blaas/logo-paloalto.png | Bin 0 -> 10676 bytes .../static/img/blaas/logo-pfsense.png | Bin 0 -> 13310 bytes .../static/img/blaas/logo-sophos.png | Bin 0 -> 13001 bytes .../unversioned/integrations/intro.mdx | 39 +- 15 files changed, 638 insertions(+), 121 deletions(-) create mode 100644 crowdsec-docs/src/components/integration-tile.tsx create mode 100644 crowdsec-docs/static/img/blaas/logo-checkpoint.png create mode 100644 crowdsec-docs/static/img/blaas/logo-cisco.png create mode 100644 crowdsec-docs/static/img/blaas/logo-default.png create mode 100644 crowdsec-docs/static/img/blaas/logo-f5.png create mode 100644 crowdsec-docs/static/img/blaas/logo-fortinet.png create mode 100644 crowdsec-docs/static/img/blaas/logo-juniper.png create mode 100644 crowdsec-docs/static/img/blaas/logo-mikrotik.png create mode 100644 crowdsec-docs/static/img/blaas/logo-opnsense.png create mode 100644 crowdsec-docs/static/img/blaas/logo-paloalto.png create mode 100644 crowdsec-docs/static/img/blaas/logo-pfsense.png create mode 100644 crowdsec-docs/static/img/blaas/logo-sophos.png diff --git a/.gitignore b/.gitignore index 62551d255..4c236fefd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vscode node_modules -.history \ No newline at end of file +.history +ai-session \ No newline at end of file diff --git a/crowdsec-docs/src/components/integration-tile.tsx b/crowdsec-docs/src/components/integration-tile.tsx new file mode 100644 index 000000000..388f79dfd --- /dev/null +++ b/crowdsec-docs/src/components/integration-tile.tsx @@ -0,0 +1,101 @@ +import React from 'react'; +import useBaseUrl from '@docusaurus/useBaseUrl'; + +interface IntegrationTileProps { + name: string; + slug: string; + href: string; + desc?: string; + color: string; + children?: React.ReactNode; +} + +export const firewallIntegrations = [ + { name: 'Checkpoint', slug: 'checkpoint', href: '/u/integrations/checkpoint', desc: 'Custom Intelligence (IoC) Feeds', color: '#cc0000' }, + { name: 'Cisco', slug: 'cisco', href: '/u/integrations/cisco', desc: 'Security Intelligence feeds', color: '#1ba0d8' }, + { name: 'F5', slug: 'f5', href: '/u/integrations/f5', desc: 'External IP blocklist / Feed lists', color: '#e4002b' }, + { name: 'Fortinet', slug: 'fortinet', href: '/u/integrations/fortinet', desc: 'IP address Threat Feeds', color: '#ee3124' }, + { name: 'Juniper', slug: 'juniper', href: '/u/integrations/juniper', desc: 'Security Dynamic Address feeds', color: '#84b135' }, + { name: 'Mikrotik', slug: 'mikrotik', href: '/u/integrations/mikrotik', desc: 'IP blocklist ingestion', color: '#9f1d20' }, + { name: 'OPNsense', slug: 'opnsense', href: '/u/integrations/opnsense', desc: 'URL Table (IPs) aliases', color: '#d94f00' }, + { name: 'Palo Alto', slug: 'paloalto', href: '/u/integrations/paloalto', desc: 'External Dynamic Lists (EDL)', color: '#fa582d' }, + { name: 'pfSense', slug: 'pfsense', href: '/u/integrations/pfsense', desc: 'URL Table (IPs) aliases', color: '#212d6e' }, + { name: 'Sophos', slug: 'sophos', href: '/u/integrations/sophos', desc: 'Third-Party Threat Feeds', color: '#1f6bff' }, +]; + +export default function IntegrationTile({ name, slug, href, desc, color, children }: IntegrationTileProps) { + const logoSrc = useBaseUrl(`/img/blaas/logo-${slug}.png`); + const fallbackSrc = useBaseUrl('/img/blaas/logo-default.png'); + + return ( +
{ + (e.currentTarget as HTMLDivElement).style.boxShadow = `0 4px 12px ${color}30`; + (e.currentTarget as HTMLDivElement).style.borderColor = `${color}70`; + }} + onMouseLeave={e => { + (e.currentTarget as HTMLDivElement).style.boxShadow = 'none'; + (e.currentTarget as HTMLDivElement).style.borderColor = 'var(--ifm-color-emphasis-200)'; + }} + > +
+ +
+ {`${name} { + (e.currentTarget as HTMLImageElement).onerror = null; + (e.currentTarget as HTMLImageElement).src = fallbackSrc; + }} + style={{ width: '32px', height: '32px', objectFit: 'contain', pointerEvents: 'none', userSelect: 'none' }} + /> +
+
+ + {name} + + + {children || desc} + +
+
+
+ ); +} diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 0fecb7733..00d94e2f5 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -1,75 +1,396 @@ import Link from "@docusaurus/Link"; import Layout from "@theme/Layout"; import SearchBar from "@theme/SearchBar"; -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { Button } from "../ui/button"; +// ── Intent card ────────────────────────────────────────────────────────────── + +type IntentCardProps = { + icon: string; + title: string; + desc: string; + pill: string; + accent: string; + href: string; +}; + +const IntentCard = ({ icon, title, desc, pill, accent, href }: IntentCardProps) => ( + { + const el = e.currentTarget as HTMLAnchorElement; + el.style.borderColor = accent; + el.style.boxShadow = `0 0 0 1px ${accent}`; + el.style.transform = "translateY(-1px)"; + }} + onMouseLeave={e => { + const el = e.currentTarget as HTMLAnchorElement; + el.style.borderColor = "var(--ifm-color-emphasis-200)"; + el.style.boxShadow = "none"; + el.style.transform = "none"; + }} + > +
+
{icon}
+
+
{title}
+
{desc}
+ → {pill} +
+
+
+
+); + +// ── Schema / path block ─────────────────────────────────────────────────────── + +type Step = { + num: number; + icon: string; + title: string; + desc: string; + optional?: boolean; + optionalLabel?: string; + perks?: string[]; +}; + +type SchemaBlockProps = { + id: string; + color: string; + eyebrowIcon: string; + eyebrow: string; + title: string; + ctaLabel: string; + ctaHref: string; + steps: Step[]; + open: boolean; + onToggle: () => void; +}; + +const SchemaBlock = ({ id, color, eyebrowIcon, eyebrow, title, ctaLabel, ctaHref, steps, open, onToggle }: SchemaBlockProps) => ( +
+ {/* left accent strip */} +
+ {/* subtle radial glow */} +
+ + {/* header — always visible, clickable to toggle */} + + + {/* collapsible step flow */} + {open && ( +
+ {steps.map((step, i) => ( +
+ {i > 0 && ( +
+ )} + {step.optional && ( +
{step.optionalLabel || "Optional"}
+ )} +
{step.num}
+
{step.icon}
+
{step.title}
+
{step.desc}
+ {step.perks && ( +
    + {step.perks.map((p, j) => ( +
  • + + {p} +
  • + ))} +
+ )} +
+ ))} +
+ )} +
+); + +// ── Product card ────────────────────────────────────────────────────────────── + type ProductCardProps = { title: string; description: string; icon: React.ReactNode; link: string; features: string[]; - bestFor: string; }; -const ProductCard = ({ title, description, icon, link, features, bestFor }: ProductCardProps): React.JSX.Element => ( +const ProductCard = ({ title, description, icon, link, features }: ProductCardProps): React.JSX.Element => (
-
+
{icon}
-

- {title} -

+

{title}

-

{description}

-

{bestFor}

-
)}
{step.num}
{step.icon}
{step.title}
@@ -259,22 +261,27 @@ const BLUE = "#60a5fa"; const intents: IntentCardProps[] = [ { - icon: "🛡️", accent: ORANGE, + icon: Security Engine, + accent: ORANGE, title: "Detect and block attacks on systems I run", desc: "You operate servers, VMs, or containers and want active threat detection — not just a blocklist.", - pill: "Security Engine", href: "/security-engine", + pill: "Security Engine", + href: "/security-engine", }, { - icon: "🚫", accent: GREEN, + icon: Blocklists, + accent: GREEN, title: "Push a threat feed into my firewall, router, or CDN", desc: "You manage network perimeter devices and want a URL to subscribe to — no agent to install.", - pill: "Blocklist Feed Endpoints", href: "/blocklists", + pill: "Blocklist Feed Endpoints", + href: "/blocklists", }, { - icon: "🔍", accent: BLUE, + icon: CTI, + accent: BLUE, title: "Look up an IP or enrich my security tools", desc: "You're a security analyst or developer who wants IP context — in a browser or via REST API.", - pill: "IP Reputation & CTI", pillColor: BLUE, + pill: "IP Reputation & CTI", href: "/cti", }, ]; @@ -296,17 +303,17 @@ const schemas: Omit[] = [ ], }, { - num: 2, icon: "🛡️", optional: true, + num: 2, icon: "🛡️", hint: "RECOMMENDED", title: "Activate the Web Application Firewall", desc: "Layer in the AppSec component to inspect HTTP traffic and block web exploits before they reach your app.", }, { - num: 3, icon: "📋", optional: true, + num: 3, icon: "📋", hint: "OPTIONAL", title: "Subscribe to additional blocklists", desc: "Add curated threat feeds on top of the community blocklist — by category, use case, or vendor.", }, { - num: 4, icon: "✍️", optional: true, + num: 4, icon: "✍️", hint: "OPTIONAL", title: "Craft your own detection rules", desc: "Write custom scenarios for your stack, then share them back with the community on the Hub.", }, @@ -351,12 +358,12 @@ const schemas: Omit[] = [ desc: "No setup. Search instantly — get reputation score, behaviors, attack history, and CVE links.", }, { - num: 2, icon: "🔑", optional: true, optionalLabel: "For integrations", + num: 2, icon: "🔑", hint: "For integrations", title: "Generate a CTI API key", desc: "Unlock programmatic access to the same data. Free tier included — no credit card needed.", }, { - num: 3, icon: "⚙️", optional: true, optionalLabel: "For integrations", + num: 3, icon: "⚙️", hint: "Enrich", title: "Connect to your SIEM or security tool", desc: "Native integrations for Splunk, Sentinel, QRadar, TheHive, OpenCTI, MISP, and more.", }, @@ -457,11 +464,11 @@ const HomePage = () => { }}>Already running CrowdSec?
{[ - { label: "🖥️ Open the Console", href: "https://app.crowdsec.net" }, + { label: "🖥️ Open the Console", href: "https://app.crowdsec.net", external: true }, { label: "📋 Manage alerts & decisions", href: "/u/console/intro" }, { label: "🔄 Remediation sync", href: "/u/bouncers/intro" }, { label: "❓ Troubleshooting", href: "/docs/next/troubleshooting/security_engine" }, - ].map(({ label, href }) => ( + ].map(({ label, href, external }) => ( { textDecoration: "none", transition: "border-color .15s, color .15s", }} - >{label} + >{label}{external && } ))}
@@ -543,10 +550,14 @@ const HomePage = () => {
- + - +
@@ -566,11 +577,11 @@ const HomePage = () => { { label: "🖥️ Console", href: "/u/console/intro" }, { label: "🛡️ AppSec / WAF", href: "/docs/next/appsec/intro" }, { label: "💻 CLI Reference", href: "/docs/next/cscli/" }, - { label: "📖 Docs AI Assistant", href: "https://chatgpt.com/g/g-682c3a61a78081918417571116c2b563-crowdsec-documentation" }, + { label: "📖 Docs AI Assistant", href: "https://chatgpt.com/g/g-682c3a61a78081918417571116c2b563-crowdsec-documentation", external: true }, { label: "🔑 CTI API Keys", href: "/cti" }, { label: "❓ Troubleshooting", href: "/docs/next/troubleshooting/security_engine" }, - { label: "🌐 About CrowdSec", href: "https://www.crowdsec.net" }, - ].map(({ label, href }) => ( + { label: "🌐 About CrowdSec", href: "https://www.crowdsec.net", external: true }, + ].map(({ label, href, external }) => ( { textDecoration: "none", transition: "color .15s, border-color .15s", }} - >{label} + >{label}{external && } ))}
From af47bb6bb868a84b4915486fb43a42b07ee7809b Mon Sep 17 00:00:00 2001 From: jdv Date: Wed, 22 Apr 2026 20:46:03 +0200 Subject: [PATCH 03/18] removing by products section --- crowdsec-docs/src/pages/index.tsx | 79 +------------------------------ 1 file changed, 1 insertion(+), 78 deletions(-) diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 4b85c8192..24fd01381 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -219,40 +219,6 @@ const SchemaBlock = ({ id, color, eyebrowIcon, eyebrow, title, ctaLabel, ctaHref ); -// ── Product card ────────────────────────────────────────────────────────────── - -type ProductCardProps = { - title: string; - description: string; - icon: React.ReactNode; - link: string; - features: string[]; -}; - -const ProductCard = ({ title, description, icon, link, features }: ProductCardProps): React.JSX.Element => ( - -
-
-
- {icon} -
-

{title}

-
-

{description}

-
    - {features.map((f) => ( -
  • - {f} -
  • - ))} -
-
- Explore product → -
-
- -); - // ── Data ────────────────────────────────────────────────────────────────────── const ORANGE = "#f97316"; @@ -371,29 +337,6 @@ const schemas: Omit[] = [ }, ]; -const products: ProductCardProps[] = [ - { - title: "Security Engine", - description: "Analyze your logs to detect attacks, block malicious IPs, and protect web applications.", - icon: Security Engine, - link: "/security-engine", - features: ["Behavior-based detection", "Community threat sharing", "AppSec / WAF for web apps", "Open source"], - }, - { - title: "Blocklists", - description: "Deploy curated threat intel feeds to protect your network without running detection yourself.", - icon: Blocklists, - link: "/blocklists", - features: ["Curated IP lists, auto-updated", "Ready-to-deploy feeds", "Multiple threat categories", "Works standalone or with Engine"], - }, - { - title: "CTI", - description: "Query CrowdSec threat intelligence to enrich investigations, automate lookups, and integrate with tools.", - icon: CTI, - link: "/cti", - features: ["REST API access", "IP reputation scores", "Attack context", "SIEM integrations"], - }, -]; // ── Page ────────────────────────────────────────────────────────────────────── @@ -514,27 +457,7 @@ const HomePage = () => { - {/* Browse by product */} -
-
-
-
- or browse by product -
-
-
- {products.map(p => )} -
-
-
- - {/* Not sure / fallback */} +{/* Not sure / fallback */}
Date: Wed, 22 Apr 2026 20:50:14 +0200 Subject: [PATCH 04/18] biome fix --- .../src/components/integration-tile.tsx | 200 +++--- crowdsec-docs/src/pages/index.tsx | 591 ++++++++++++------ 2 files changed, 509 insertions(+), 282 deletions(-) diff --git a/crowdsec-docs/src/components/integration-tile.tsx b/crowdsec-docs/src/components/integration-tile.tsx index 388f79dfd..7ff35de31 100644 --- a/crowdsec-docs/src/components/integration-tile.tsx +++ b/crowdsec-docs/src/components/integration-tile.tsx @@ -1,101 +1,119 @@ -import React from 'react'; -import useBaseUrl from '@docusaurus/useBaseUrl'; +import useBaseUrl from "@docusaurus/useBaseUrl"; +import React from "react"; interface IntegrationTileProps { - name: string; - slug: string; - href: string; - desc?: string; - color: string; - children?: React.ReactNode; + name: string; + slug: string; + href: string; + desc?: string; + color: string; + children?: React.ReactNode; } export const firewallIntegrations = [ - { name: 'Checkpoint', slug: 'checkpoint', href: '/u/integrations/checkpoint', desc: 'Custom Intelligence (IoC) Feeds', color: '#cc0000' }, - { name: 'Cisco', slug: 'cisco', href: '/u/integrations/cisco', desc: 'Security Intelligence feeds', color: '#1ba0d8' }, - { name: 'F5', slug: 'f5', href: '/u/integrations/f5', desc: 'External IP blocklist / Feed lists', color: '#e4002b' }, - { name: 'Fortinet', slug: 'fortinet', href: '/u/integrations/fortinet', desc: 'IP address Threat Feeds', color: '#ee3124' }, - { name: 'Juniper', slug: 'juniper', href: '/u/integrations/juniper', desc: 'Security Dynamic Address feeds', color: '#84b135' }, - { name: 'Mikrotik', slug: 'mikrotik', href: '/u/integrations/mikrotik', desc: 'IP blocklist ingestion', color: '#9f1d20' }, - { name: 'OPNsense', slug: 'opnsense', href: '/u/integrations/opnsense', desc: 'URL Table (IPs) aliases', color: '#d94f00' }, - { name: 'Palo Alto', slug: 'paloalto', href: '/u/integrations/paloalto', desc: 'External Dynamic Lists (EDL)', color: '#fa582d' }, - { name: 'pfSense', slug: 'pfsense', href: '/u/integrations/pfsense', desc: 'URL Table (IPs) aliases', color: '#212d6e' }, - { name: 'Sophos', slug: 'sophos', href: '/u/integrations/sophos', desc: 'Third-Party Threat Feeds', color: '#1f6bff' }, + { + name: "Checkpoint", + slug: "checkpoint", + href: "/u/integrations/checkpoint", + desc: "Custom Intelligence (IoC) Feeds", + color: "#cc0000", + }, + { name: "Cisco", slug: "cisco", href: "/u/integrations/cisco", desc: "Security Intelligence feeds", color: "#1ba0d8" }, + { name: "F5", slug: "f5", href: "/u/integrations/f5", desc: "External IP blocklist / Feed lists", color: "#e4002b" }, + { name: "Fortinet", slug: "fortinet", href: "/u/integrations/fortinet", desc: "IP address Threat Feeds", color: "#ee3124" }, + { name: "Juniper", slug: "juniper", href: "/u/integrations/juniper", desc: "Security Dynamic Address feeds", color: "#84b135" }, + { name: "Mikrotik", slug: "mikrotik", href: "/u/integrations/mikrotik", desc: "IP blocklist ingestion", color: "#9f1d20" }, + { name: "OPNsense", slug: "opnsense", href: "/u/integrations/opnsense", desc: "URL Table (IPs) aliases", color: "#d94f00" }, + { name: "Palo Alto", slug: "paloalto", href: "/u/integrations/paloalto", desc: "External Dynamic Lists (EDL)", color: "#fa582d" }, + { name: "pfSense", slug: "pfsense", href: "/u/integrations/pfsense", desc: "URL Table (IPs) aliases", color: "#212d6e" }, + { name: "Sophos", slug: "sophos", href: "/u/integrations/sophos", desc: "Third-Party Threat Feeds", color: "#1f6bff" }, ]; export default function IntegrationTile({ name, slug, href, desc, color, children }: IntegrationTileProps) { - const logoSrc = useBaseUrl(`/img/blaas/logo-${slug}.png`); - const fallbackSrc = useBaseUrl('/img/blaas/logo-default.png'); + const logoSrc = useBaseUrl(`/img/blaas/logo-${slug}.png`); + const fallbackSrc = useBaseUrl("/img/blaas/logo-default.png"); - return ( -
{ - (e.currentTarget as HTMLDivElement).style.boxShadow = `0 4px 12px ${color}30`; - (e.currentTarget as HTMLDivElement).style.borderColor = `${color}70`; - }} - onMouseLeave={e => { - (e.currentTarget as HTMLDivElement).style.boxShadow = 'none'; - (e.currentTarget as HTMLDivElement).style.borderColor = 'var(--ifm-color-emphasis-200)'; - }} - > - - ); + return ( +
+ + ); } diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 24fd01381..c12411438 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -1,9 +1,9 @@ import Link from "@docusaurus/Link"; import Layout from "@theme/Layout"; import SearchBar from "@theme/SearchBar"; +import { ExternalLink } from "lucide-react"; import React, { useEffect, useState } from "react"; import { Button } from "../ui/button"; -import { ExternalLink } from "lucide-react"; // ── Intent card ────────────────────────────────────────────────────────────── @@ -21,47 +21,73 @@ const IntentCard = ({ icon, title, desc, pill, accent, href }: IntentCardProps) href={href} className="hover:no-underline group flex" style={{ textDecoration: "none", color: "inherit" }} - onMouseEnter={e => { + onMouseEnter={(e) => { const el = e.currentTarget as HTMLAnchorElement; el.style.borderColor = accent; el.style.boxShadow = `0 8px 24px ${accent}22, 0 0 0 1px ${accent}`; el.style.transform = "translateY(-2px)"; el.style.borderRadius = "14px"; }} - onMouseLeave={e => { + onMouseLeave={(e) => { const el = e.currentTarget as HTMLAnchorElement; el.style.borderColor = ""; el.style.boxShadow = ""; el.style.transform = ""; }} > -
+
-
{icon}
+
+ {icon} +
{title}
-
{desc}
+
+ {desc} +
- → {pill} + + → {pill} +
@@ -105,35 +131,61 @@ const SchemaBlock = ({ id, color, eyebrowIcon, eyebrow, title, ctaLabel, ctaHref }} > {/* left accent strip */} -
+
{/* subtle radial glow */} -
+
{/* header — always visible, clickable to toggle */} {/* collapsible step flow */} {open && ( -
+
{steps.map((step, i) => ( -
+
{i > 0 && ( -
+
+ → +
)} {step.hint && ( -
{step.hint}
+
+ {step.hint} +
)} -
{step.num}
+
+ {step.num} +
{step.icon}
{step.title}
{step.desc}
{step.perks && ( -
diff --git a/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx b/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx index 1840144ba..42653d5ee 100644 --- a/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx +++ b/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx @@ -56,31 +56,31 @@ export const PURPLE = "#a78bfa"; - {/* Quota sub-tiles */} -
+ {/* Quota rows — plain text, not interactive */} +
{[ - { label: "Community", quota: "40", unit: "/ month", desc: "Ad-hoc lookups, proof of concept", color: GREEN }, - { label: "Premium", quota: "120", unit: "/ month", desc: "Regular enrichment, small integrations", color: BLUE }, - { label: "Premium Options", quota: "5K–100K", unit: "/ month", desc: "Production SIEMs, SOARs, high-volume pipelines", color: PURPLE }, - ].map(({ label, quota, unit, desc, color }) => ( -
-
{label}
-
- {quota} {unit} -
-
{desc}
+ { label: "Community", quota: "40 / month", desc: "ad-hoc lookups, proof of concept", color: GREEN }, + { label: "Premium", quota: "120 / month", desc: "regular enrichment, small integrations", color: BLUE }, + { label: "Premium Options", quota: "5K–100K / month", desc: "production SIEMs, SOARs, high-volume pipelines", color: PURPLE }, + ].map(({ label, quota, desc, color }) => ( +
+ {label} + {" — "} + {quota} + {" · "} + {desc}
))}
-
- API quotas are separate from Web UI quotas. Web UI searches consume their own quota: 100 searches/week when not logged in (1 quota per results page or report viewed); 40/month for logged-in Community accounts, 100/month for Premium. API key usage does not count against Web UI quotas, and vice versa. +
+ API quotas are separate from Web UI quotas. Web UI searches consume their own quota: 100/week unauthenticated (1 quota per results page or report); 40/month for Community, 100/month for Premium accounts.
-
- Create an API key → - Data Taxonomy → - API Reference +
+ Create an API key → + Data Taxonomy → + API Reference
From 35481b60ca01c63c49d4894e25478919f950f3fe Mon Sep 17 00:00:00 2001 From: jdv Date: Tue, 28 Apr 2026 11:45:31 +0200 Subject: [PATCH 13/18] homepage text changes --- crowdsec-docs/src/pages/index.tsx | 49 +++++-------------------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 2a38f14a8..806ebafe7 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -101,7 +101,6 @@ type Step = { title: string; desc: string; hint?: string; - perks?: string[]; }; type SchemaBlockProps = { @@ -300,35 +299,6 @@ const SchemaBlock = ({ id, color, eyebrowIcon, eyebrow, title, ctaLabel, ctaHref
{step.icon}
{step.title}
{step.desc}
- {step.perks && ( -
    - {step.perks.map((p) => ( -
  • - - {p} -
  • - ))} -
- )}
))}
@@ -383,11 +353,7 @@ const schemas: Omit[] = [ num: 1, icon: "⚡", title: "Install the Security Engine", - desc: "Runs on your server, detects attack patterns in real time.", - perks: [ - "Immediately protected from incoming attacks", - "Automatically receives global threat intel from the CrowdSec network", - ], + desc: "Runs on your server, detects attack patterns in real time — immediately protected, and continuously updated with CrowdSec Community Blocklist.", }, { num: 2, @@ -425,7 +391,7 @@ const schemas: Omit[] = [ num: 1, icon: "🔌", title: "Create a blocklist integration endpoint", - desc: "Generate a dedicated URL in the Console — one per target device or environment.", + desc: "Generates a dedicated URL and credentials to serve blocklists to your perimeter devices.", }, { num: 2, @@ -437,8 +403,7 @@ const schemas: Omit[] = [ num: 3, icon: "🔗", title: "Plug it in as an external threat feed", - desc: "Point your firewall, CDN, or WAF at the endpoint. It auto-refreshes — no further maintenance needed.", - perks: ["Works with pfSense, OPNsense, Cloudflare, nginx, HAProxy, and more", "No agent to install or maintain"], + desc: "Point your firewall, CDN, or WAF at the endpoint. Use the feed to protect your infrastructure.", }, ], }, @@ -455,20 +420,20 @@ const schemas: Omit[] = [ num: 1, icon: "🖥️", title: "Look up any IP in the Console", - desc: "No setup. Search instantly — get reputation score, behaviors, attack history, and CVE links.", + desc: "Search instantly from our Web UI— get reputation score, behaviors, attack history, and CVE links.", }, { num: 2, icon: "🔑", - hint: "For integrations", + hint: "Integrate", title: "Generate a CTI API key", - desc: "Unlock programmatic access to the same data. Free tier included — no credit card needed.", + desc: "Unlock programmatic access to 30+ data points on IPs detected by CrowdSec Network.", }, { num: 3, icon: "⚙️", hint: "Enrich", - title: "Connect to your SIEM or security tool", + title: "Connect to your SIEM/SOAR/TIP", desc: "Native integrations for Splunk, Sentinel, QRadar, TheHive, OpenCTI, MISP, and more.", }, ], From 4278020ff6a17c1f989600dd28071fa61599c068 Mon Sep 17 00:00:00 2001 From: jdv Date: Tue, 28 Apr 2026 14:22:32 +0200 Subject: [PATCH 14/18] text update in all pages --- crowdsec-docs/sidebarsUnversioned.ts | 10 +-- crowdsec-docs/src/pages/index.tsx | 10 +-- .../ip_reputation/api_keys_premium.mdx | 67 +++++++++++++-- .../console/ip_reputation/intro.mdx | 85 ++++++++----------- .../unversioned/console/stackhealth.mdx | 3 +- crowdsec-docs/unversioned/cti_api/intro.mdx | 10 +-- 6 files changed, 116 insertions(+), 69 deletions(-) diff --git a/crowdsec-docs/sidebarsUnversioned.ts b/crowdsec-docs/sidebarsUnversioned.ts index 25d46c21c..8dd5c3ef6 100644 --- a/crowdsec-docs/sidebarsUnversioned.ts +++ b/crowdsec-docs/sidebarsUnversioned.ts @@ -420,6 +420,11 @@ const sidebarsUnversionedConfig: SidebarConfig = { label: "Advanced Search", id: "console/ip_reputation/search_ui_advanced", }, + { + type: "doc", + label: "IP Reputation Report", + id: "console/ip_reputation/ip_report", + }, { type: "link", label: "Search Queries Syntax", @@ -430,11 +435,6 @@ const sidebarsUnversionedConfig: SidebarConfig = { }, ], }, - { - type: "doc", - label: "IP Reputation Report", - id: "console/ip_reputation/ip_report", - }, { type: "category", label: "API Keys", diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 806ebafe7..17ae4039d 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -531,7 +531,7 @@ const HomePage = () => { {
{[ { label: "🖥️ Open the Console", href: "https://app.crowdsec.net", external: true }, - { label: "📋 Manage alerts & decisions", href: "/u/console/intro" }, - { label: "🔄 Remediation sync", href: "/u/bouncers/intro" }, - { label: "❓ Troubleshooting", href: "/docs/next/troubleshooting/security_engine" }, + { label: "🛡️ Activate the WAF", href: "/docs/next/appsec/intro" }, + { label: "📊 Measure what is being Blocked", href: "/u/console/remediation_metrics" }, + { label: "🩺 Check my Stack Health", href: "/u/console/stackhealth" }, ].map(({ label, href, external }) => ( { gap: "6px", padding: "5px 12px", borderRadius: "7px", - fontSize: "12.5px", + fontSize: "11px", color: "var(--ifm-color-emphasis-700)", border: "1px solid var(--ifm-color-emphasis-200)", background: "var(--ifm-background-color)", diff --git a/crowdsec-docs/unversioned/console/ip_reputation/api_keys_premium.mdx b/crowdsec-docs/unversioned/console/ip_reputation/api_keys_premium.mdx index 0073f6889..7abd7788b 100644 --- a/crowdsec-docs/unversioned/console/ip_reputation/api_keys_premium.mdx +++ b/crowdsec-docs/unversioned/console/ip_reputation/api_keys_premium.mdx @@ -1,15 +1,72 @@ --- id: api_keys_premium -title: Premium CTI API Keys +title: CTI API Access & Quotas sidebar_position: 2 --- -A [Premium Plan](/u/console/premium_upgrade) unlocks two benefits for CTI API access: +import Link from "@docusaurus/Link"; -- **Increased free quota** — the complimentary CTI key included with every account has a higher quota on a Premium plan than on the free Community plan. -- **Purchasable high-quota keys** — Premium organizations can buy additional CTI API keys with larger monthly quotas (5K, 25K, or 100K queries/month) to support production integrations, automated enrichment pipelines, and high-volume use cases. +export const GREEN = "#22d3a0"; +export const BLUE = "#60a5fa"; +export const PURPLE = "#a78bfa"; -For current quota tiers and pricing, go to **Settings → CTI API Keys** in the Console and click **+ New Key** — all available options and their costs are shown there. +Every CrowdSec account — free or Premium — includes a complimentary CTI API key. The right tier depends on what you're doing with the data. + +{/* ── Tier cards ─────────────────────────────────────────────────────────── */} + +
+ + {/* Community */} +
+
+ Community Plan + Free · 40 queries / month +
+
+ Included with every account at no cost. Suited for testing a CTI integration end-to-end, enriching alerts on personal homelab or hobby servers, or doing occasional ad-hoc IP lookups during an investigation. Not designed for production pipelines that query continuously. +
+
Free key · no credit card needed · resets monthly
+
+ + {/* Premium */} +
+
+ Premium Plan + 120 queries / month +
+
+ For practitioners with growing CTI enrichment needs — small SOC teams, security engineers running regular automation, or analysts who enrich SIEM alerts on a recurring basis. The 3× quota increase over Community covers light-to-moderate production use without committing to a paid quota add-on. +
+
Included with Premium Plan · resets monthly
+
+ + {/* Extended */} +
+
+ Extended Quota Options + 5K · 25K · 100K queries / month +
+
+ Purchasable add-ons available to Premium organizations. Designed for production SIEMs, SOARs, and high-volume enrichment pipelines — cases where every incoming alert or event triggers an IP lookup. Available in three sizes to match your actual throughput rather than forcing an all-or-nothing commitment. +
+
Requires Premium Plan · pricing shown in Console under Settings → CTI API Keys
+
+ +
+ +{/* ── Quota note ─────────────────────────────────────────────────────────── */} + +
+ API quotas are separate from Web UI quotas. Searching IPs through the Console web interface consumes its own quota and does not count against your API key. Unused API quota does not roll over to the next month. +
+ +## Purchasing a high-quota key + +Extended quota keys are available in the Console under **Settings → CTI API Keys → + New Key**. All available options and their costs are shown there. + +## Lucene search via API + +The [Advanced Search](/u/console/ip_reputation/search_ui_advanced) Lucene query interface available in the Console is a **Web UI feature only** — it is not accessible through self-service API keys. If you need programmatic access to Lucene-style bulk querying or advanced filtering at scale, this requires an Advanced CTI plan. [Contact our team](https://www.crowdsec.net/contact-crowdsec?message=Advanced%20CTI%20plan%20discussion) to discuss your use case. :::warning CTI API Keys and trials - Purchasing a CTI API Key does **not** grant access to a Premium Plan trial. diff --git a/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx b/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx index 42653d5ee..3c379568b 100644 --- a/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx +++ b/crowdsec-docs/unversioned/console/ip_reputation/intro.mdx @@ -15,73 +15,62 @@ export const PURPLE = "#a78bfa"; Query behavioral intelligence on any IP — reputation scores, attack patterns, linked CVEs, and activity history — sourced from hundreds of thousands of real CrowdSec deployments worldwide.

-{/* ── Row 1: Search + IP Report ───────────────────────────────────────── */} +{/* ── Row 1: two cards side by side ──────────────────────────────────── */} -
+
+ {/* Card 1: Web UI exploration (merged Search + IP Report) */}
🔍
-
Explore IP Reputation
+
Explore in the Web UI
- Search any IP or run Lucene queries with live faceted filters — reputation, country, AS, behaviors, classifications. The homepage also surfaces a Top 10 Most Aggressive IPs leaderboard updated every 24h. + No setup needed. Search any IP directly from your browser — run Lucene queries with live faceted filters (reputation, country, AS, behaviors, classifications) and open any result to see its full report: threat score, behaviors mapped to MITRE ATT&CK, linked CVEs, and time-windowed activity. The homepage also surfaces a Top 10 Most Aggressive IPs leaderboard updated every 24h.
-
+
IP Search → Advanced Search → - Query Reference → + IP Report → + Lucene Query Reference →
+ {/* Card 2: Enrich your Alerts (API Key) */}
-
📋
-
Understand an IP Report
-
- Click any IP to open its full report: threat reputation score, observed attack behaviors mapped to MITRE ATT&CK, linked CVEs, classifications, and time-windowed activity details showing whether the threat is rising, stable, or decaying. +
🔑
+
Enrich your Alerts
+
+ Unlock programmatic access to 30+ enrichment fields per IP — reputation, behaviors, CVEs, attack context, MITRE mappings, and more. Use it to enrich SIEM alerts, automate lookups, or feed threat intel platforms. Free tier included, no credit card needed.
- IP Report → -
- -
-{/* ── Row 2: API Key ──────────────────────────────────────────────────── */} - -
-
-
🔑
-
-
Create an API Key
-
- Unlock programmatic access to 30+ enrichment fields per IP — reputation, behaviors, CVEs, attack context, MITRE mappings, and more. Use it to enrich SIEM alerts, automate lookups, or feed threat intel platforms. Free tier included, no credit card needed. -
+ {/* Quota rows */} +
+ {[ + { label: "Community", quota: "40 / month", desc: "ad-hoc lookups, proof of concept", color: GREEN }, + { label: "Premium", quota: "120 / month", desc: "regular enrichment, small integrations", color: BLUE }, + { label: "Premium Options", quota: "5K–100K / month", desc: "production SIEMs, SOARs, high-volume pipelines", color: PURPLE }, + ].map(({ label, quota, desc, color }) => ( +
+ {label} + {" — "} + {quota} + {" · "} + {desc} +
+ ))}
-
- {/* Quota rows — plain text, not interactive */} -
- {[ - { label: "Community", quota: "40 / month", desc: "ad-hoc lookups, proof of concept", color: GREEN }, - { label: "Premium", quota: "120 / month", desc: "regular enrichment, small integrations", color: BLUE }, - { label: "Premium Options", quota: "5K–100K / month", desc: "production SIEMs, SOARs, high-volume pipelines", color: PURPLE }, - ].map(({ label, quota, desc, color }) => ( -
- {label} - {" — "} - {quota} - {" · "} - {desc} -
- ))} -
+
+ API quotas are separate from Web UI quotas. Unused quota does not roll over. +
-
- API quotas are separate from Web UI quotas. Web UI searches consume their own quota: 100/week unauthenticated (1 quota per results page or report); 40/month for Community, 100/month for Premium accounts. +
+ Create an API key → + Quotas & plans → + Data Taxonomy → + API Reference +
-
- Create an API key → - Data Taxonomy → - API Reference -
{/* ── You might also be interested in: LET ───────────────────────────── */} diff --git a/crowdsec-docs/unversioned/console/stackhealth.mdx b/crowdsec-docs/unversioned/console/stackhealth.mdx index 3410b8ed4..a79276f24 100644 --- a/crowdsec-docs/unversioned/console/stackhealth.mdx +++ b/crowdsec-docs/unversioned/console/stackhealth.mdx @@ -4,7 +4,8 @@ title: Stack Health --- The **Stack Health** Feature is a monitoring tool within the CrowdSec Console helping you keep your infrastructure operational and properly configured. -Its primary goal is to identify configuration issues, connectivity problems, or potential misconfigurations that could impact your detection capabilities. +Its primary goal is to identify configuration issues, connectivity problems, or potential misconfigurations that could impact your detection capabilities. +*You can also do a manual health check of your stack by following this post installation [Health-Check guide](/u/getting_started/health_check).* --- diff --git a/crowdsec-docs/unversioned/cti_api/intro.mdx b/crowdsec-docs/unversioned/cti_api/intro.mdx index b15b43a3b..d2989506e 100644 --- a/crowdsec-docs/unversioned/cti_api/intro.mdx +++ b/crowdsec-docs/unversioned/cti_api/intro.mdx @@ -15,7 +15,7 @@ export const PURPLE = "#a78bfa"; {/* ── Hero ─────────────────────────────────────────────────────────────── */}

- Know who's attacking you — and why. + Understand the IPs behind attacks

CrowdSec tracks malicious IPs across hundreds of thousands of real deployments worldwide. @@ -41,19 +41,19 @@ export const PURPLE = "#a78bfa"; {[ { badge: "🔍 No setup needed", icon: "🖥️", accent: BLUE, - title: "Investigate in the Console", + title: "Web UI investigation - in the Console", desc: "Search any IP instantly. Explore threat history and the top aggressive IPs in the last 24h — no API key needed.", links: [{ label: "Web UI guide →", href: "/u/console/ip_reputation/intro" }, { label: "IP Report →", href: "/u/console/ip_reputation/ip_report" }], }, { badge: "⚙️ Developer / SecOps", icon: "🔌", accent: ORANGE, - title: "Integrate via API", - desc: "Enrich SIEM alerts, build enrichment pipelines, or plug into Splunk, Sentinel, QRadar, TheHive, and more.", + title: "Enrich Alerts via API", + desc: "Use the CTI API to add CrowdSec IP context to SIEM alerts, SOAR workflows, TIPs, scripts, and internal tools.", links: [{ label: "API quickstart →", href: "/u/cti_api/api_introduction" }, { label: "All integrations →", href: "/u/cti_api/api_integration/integration_intro" }], }, { badge: "🎯 Threat hunter", icon: "🚨", accent: PURPLE, - title: "Hunt for threat patterns", + title: "Hunt active threats", desc: "Advanced Search with live faceted filters — behavior, country, AS, CVE — to find campaigns or build blocklists.", links: [{ label: "Advanced search →", href: "/u/console/ip_reputation/search_ui_advanced" }, { label: "Live Exploit Tracker →", href: "/u/tracker_api/intro" }], }, From b486430e742e56d7294d17cf088bf2a4da2bf9f0 Mon Sep 17 00:00:00 2001 From: jdv Date: Tue, 28 Apr 2026 14:23:07 +0200 Subject: [PATCH 15/18] biome fix --- crowdsec-docs/src/pages/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 17ae4039d..9b8c5a2c3 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -471,7 +471,7 @@ const HomePage = () => { />

- Find the right + Find the right
CrowdSec tool for you

From bec28fc613f8731f7552c86c8dd582b4ef162f46 Mon Sep 17 00:00:00 2001 From: jdv Date: Tue, 28 Apr 2026 15:09:18 +0200 Subject: [PATCH 16/18] mention lucene queries not available via api --- crowdsec-docs/unversioned/cti_api/intro.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crowdsec-docs/unversioned/cti_api/intro.mdx b/crowdsec-docs/unversioned/cti_api/intro.mdx index d2989506e..a51919f31 100644 --- a/crowdsec-docs/unversioned/cti_api/intro.mdx +++ b/crowdsec-docs/unversioned/cti_api/intro.mdx @@ -82,10 +82,10 @@ export const PURPLE = "#a78bfa";

{[ - { icon: "🌍", title: "Crowdsourced from live attacks", desc: "Signals from active CrowdSec installs globally. When an IP appears here, hundreds of machines saw it in action." }, + { icon: "🌍", title: "Real-world attack signals", desc: "CrowdSec intelligence is built from signals shared by real deployments across the Internet." }, { icon: "🧠", title: "Behavioral, not just reputation", desc: "Brute-force, CVE exploitation, scan, credential stuffing — mapped to MITRE ATT&CK." }, { icon: "⚡", title: "Real-time, not cached lists", desc: "Continuously updated with time-windowed scores showing if a threat is rising, stable, or decaying." }, - { icon: "🔬", title: "CVE-level exploit tracking", desc: "The Live Exploit Tracker shows which CVEs are actively exploited, with momentum and opportunity scores." }, + { icon: "🔬", title: "CVE-level exploit tracking", desc: "Live Exploit Tracker shows which CVEs are actively exploited, with momentum, opportunity, and malicious IP context." }, ].map(({ icon, title, desc }) => (
{icon} From 41be2bd0dc69668453b6f7be434e49c89ebf2393 Mon Sep 17 00:00:00 2001 From: jdv Date: Tue, 28 Apr 2026 15:23:01 +0200 Subject: [PATCH 17/18] adding Aka tags on home --- crowdsec-docs/src/pages/index.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 9b8c5a2c3..6b58306ee 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -14,9 +14,10 @@ type IntentCardProps = { pill: string; accent: string; href: string; + aka?: string[]; }; -const IntentCard = ({ icon, title, desc, pill, accent, href }: IntentCardProps) => ( +const IntentCard = ({ icon, title, desc, pill, accent, href, aka }: IntentCardProps) => (
+ {aka && aka.length > 0 && ( +
+ aka + {aka.map((tag) => ( + {tag} + ))} +
+ )}
); @@ -320,6 +329,7 @@ const intents: IntentCardProps[] = [ desc: "Locally identify and ban bad behaving IPs observed in your logs and requests with CrowdSec Detection Scenarios, and Virtual-Patching Collections.", pill: "Security Engine", href: "/security-engine", + aka: ["IDPS", "WAF", "CrowdSec FOSS"], }, { icon: Blocklists, @@ -328,6 +338,7 @@ const intents: IntentCardProps[] = [ desc: "You manage network perimeter devices and want a URL to subscribe to — no agent to install.", pill: "Blocklist Integration Endpoint", href: "/blocklists", + aka: ["Threat Feeds", "IOC Streams", "Deny-list"], }, { icon: CTI, @@ -336,6 +347,7 @@ const intents: IntentCardProps[] = [ desc: "You're a security analyst or developer who wants IP context — in a browser or via REST API.", pill: "IP Reputation & CTI", href: "/u/cti_api/intro", + aka: ["IoC Lookup", "Threat Intel"], }, ]; @@ -669,7 +681,7 @@ const HomePage = () => { external: true, }, { label: "🔑 CTI API Keys", href: "/cti" }, - { label: "❓ Troubleshooting", href: "/docs/next/troubleshooting/security_engine" }, + { label: "❓ Troubleshooting", href: "/u/troubleshooting/intro" }, { label: "🌐 About CrowdSec", href: "https://www.crowdsec.net", external: true }, ].map(({ label, href, external }) => ( Date: Tue, 28 Apr 2026 18:00:41 +0200 Subject: [PATCH 18/18] biome fix --- crowdsec-docs/src/pages/index.tsx | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/crowdsec-docs/src/pages/index.tsx b/crowdsec-docs/src/pages/index.tsx index 6b58306ee..3d21dc0a1 100644 --- a/crowdsec-docs/src/pages/index.tsx +++ b/crowdsec-docs/src/pages/index.tsx @@ -92,9 +92,33 @@ const IntentCard = ({ icon, title, desc, pill, accent, href, aka }: IntentCardPr
{aka && aka.length > 0 && (
- aka + + aka + {aka.map((tag) => ( - {tag} + + {tag} + ))}
)}