Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 11 additions & 132 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Check warning on line 1 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

1:81 [line-length] line too long (81 > 80 characters)
#
# CodeRabbit organization config for the `coreruleset` GitHub org.
#
Expand Down Expand Up @@ -29,7 +29,7 @@
# Tone guidance appended to every review prompt. Max 250 chars (silently
# truncated beyond that).
tone_instructions: >-
Be direct, with respect. Be concise. Assume positive intent. Flag bugs, security issues, false-positive risk and regressions, with a fix. Cite rule IDs, paranoia levels and affected variables. Skip style nits. No praise.

Check warning on line 32 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

32:81 [line-length] line too long (222 > 80 characters)

# Opt in to early-access / beta features org-wide.
early_access: true
Expand Down Expand Up @@ -68,138 +68,17 @@
# Abort in-progress review when the PR closes; avoids wasted compute.
abort_on_close: true

# NOTE: auto-labeling requires each label to already exist in the repo —
# CodeRabbit will not create them. Missing labels silently no-op, which is
# what makes an org-wide list of coreruleset-specific labels safe here.
suggested_labels: true
auto_apply_labels: true
# Two families of label, both literal names from coreruleset/coreruleset
# (emoji shortcode prefix included — copy them verbatim when adding more).
#
# 1. `release:*` — the changelog taxonomy. `.github/release.yml` groups the
# generated release notes by these, and excludes `release:ignore`
# entirely. They loosely mirror conventional-commit types, so the label
# should agree with the PR title's type. Exactly one per PR (enforced by
# mutually_exclusive_groups below); when nothing else fits, the answer is
# `release:ignore`, not "no label".
# 2. Topic labels — what the PR is about, for triage and search.
labeling_instructions:
# --- release:* (changelog taxonomy, exactly one) ---
- label: "release:new-detection"
instructions: >
Apply when the PR makes CRS detect something it did not detect before:
a new `SecRule` in `rules/*.conf`, a new branch in a
`regex-assembly/*.ra` pattern, or a new entry in a `*.data` file that
widens matching. Corresponds to a `feat:` title. Do NOT apply when the
payload was already detected by a sibling rule at any paranoia level —
that is `release:fix` or `release:refactor` at best.
- label: "release:new-feature"
instructions: >
Apply when the PR adds a capability rather than a detection: a new
`crs-setup.conf.example` option, a new plugin hook, a new
`crs-toolchain`/`go-ftw` subcommand or flag, a new CI capability.
Corresponds to a `feat:` title on non-rule code.
- label: "release:fix"
instructions: >
Apply when the PR corrects wrong behaviour: a false positive narrowed,
a false negative in an existing rule closed, a broken regex, a ReDoS
or RE2-compatibility fix, or a bug in the Go/Python tooling.
Corresponds to a `fix:` title. This is the label for a rule change
that adjusts an existing detection rather than adding a new one.
- label: "release:remove-rules"
instructions: >
Apply when the PR deletes one or more rule IDs from `rules/*.conf` or
`plugins/*.conf`. Operators may have exclusions naming those IDs, so
removals get their own changelog section.
- label: "release:refactor"
instructions: >
Apply when the PR restructures without changing behaviour: a
regex-assembly reorganisation that regenerates byte-identical output,
a rule split or merge with equivalent coverage, an internal rewrite in
the tooling. Corresponds to a `refactor:` title. If matching behaviour
changes at all, it is not a refactor.
- label: "release:breaking"
instructions: >
Apply when the change breaks something a deployment or a downstream
tool depends on: a removed or renumbered rule ID that operators may
name in an exclusion, a removed or renamed `tag:` that log pipelines
filter on, a `crs-setup.conf.example` key removed or renamed, or a
removed/renamed exported symbol, CLI flag, or config key in the Go and
Python tooling. `.github/release.yml` gives these their own section, so
prefer this over `release:important` when callers must change
something, not merely be aware of it. Pair it with a "Breaking changes"
section in the PR description.
- label: "release:important"
instructions: >
Apply when operators must act or be aware on upgrade: a changed
default in `crs-setup.conf.example`, a rule moved between paranoia
levels, or a change to the anomaly-scoring mechanism — but nothing
an operator must actively fix. If existing configuration stops working
(a removed rule ID, tag, or config key), use `release:breaking`
instead.
- label: "release:ignore"
instructions: >
The default when nothing above applies. Apply for chores, CI and
workflow changes, dependency bumps, documentation, test-only changes,
typo fixes, and any small fix with no user-visible effect —
corresponds to `chore:`, `ci:`, `docs:`, `test:`, `style:` titles.
`.github/release.yml` excludes these from the release notes entirely,
so applying it is how a PR is deliberately kept out of the changelog.
Never leave a PR with no `release:` label; use this one.

# --- topic labels (triage; independent of the release: family) ---
- label: ":heavy_plus_sign: False Positive"
instructions: >
Apply when the PR or issue is about a CRS rule matching legitimate
traffic — a narrowed pattern, a new exclusion, or a report of benign
input being blocked.
- label: ":heavy_minus_sign: False Negative - Evasion"
instructions: >
Apply when the PR or issue is about an attack payload that CRS fails
to detect, including encoding/obfuscation bypasses of an existing
rule.
- label: ":mage: regex-assembly"
instructions: >
Apply when the PR touches files under `regex-assembly/` (`.ra`
sources or `regex-assembly/include/`), or regenerates a rule regex
with `crs-toolchain regex update`.
- label: ":gem: re2-compat"
instructions: >
Apply when the change involves regex constructs whose RE2
(Coraza/Go and Rust) compatibility is in question — lookarounds,
backreferences, atomic groups, possessive quantifiers — or when it
fixes an existing incompatibility.
- label: ":test_tube: testcase"
instructions: >
Apply when the PR only adds, renumbers, or corrects go-ftw regression
tests under `tests/regression/tests/` without changing rule logic.
- label: ":jigsaw: plugin"
instructions: >
Apply when the PR adds or modifies a CRS plugin (`plugins/*.conf`,
`*-rule-exclusions-plugin` repos, or plugin registry entries).
- label: ":bomb: sqli"
instructions: >
Apply when the PR touches the 942xxx rule family, libinjection
behaviour, or SQL injection detection patterns.
- label: ":book: documentation"
instructions: >
Apply when the PR only changes Markdown, docs, or comments with no
rule, test, or code behaviour change. Pair with `release:ignore`.

# `.github/release.yml` assigns a PR to the first matching category, so two
# release: labels on one PR make the changelog section arbitrary. Keep them
# exclusive. `release:important` is in the group too: if a change is both
# important and, say, a fix, the changelog wants it under ⭐ once.
mutually_exclusive_groups:
release:
- "release:new-detection"
- "release:new-feature"
- "release:fix"
- "release:remove-rules"
- "release:refactor"
- "release:breaking"
- "release:important"
- "release:ignore"
# Labeling (suggested_labels, auto_apply_labels, labeling_instructions,
# mutually_exclusive_groups) is NOT configured here. Every label above was
# a literal name from coreruleset/coreruleset's own taxonomy, but
# go-ftw, crs-toolchain, and plugin-registry already have labels with the
# *same literal names* (release:fix, release:ignore, release:new-feature,
# :book: documentation) for their own, unrelated purposes — so an org-wide
# config would have CodeRabbit auto-applying coreruleset's changelog
# taxonomy to those repos' existing labels. There is no per-repository
# scoping field in the schema, so this is set instead in a repo-local
# `.coderabbit.yaml` in coreruleset/coreruleset (with `inheritance: true`
# to keep everything from this org config).

# Reviewer routing: CODEOWNERS remains the primary, deterministic mechanism.
# These are LLM-judgment safety nets and over-fire easily, so they stay off
Expand Down Expand Up @@ -367,7 +246,7 @@
`crs-toolchain regex update <id>`.

- path: "plugins/*.conf"
# CRS plugins: coreruleset/plugins/ and the *-rule-exclusions-plugin repos.

Check warning on line 249 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

249:81 [line-length] line too long (81 > 80 characters)
instructions: |
This is a CRS plugin's seclang. Every invariant that applies to core
rules applies here too: metadata completeness, approved tags, a
Expand Down Expand Up @@ -418,9 +297,9 @@
Changed default without justification — anomaly score thresholds
(`tx.inbound_anomaly_score_threshold`,
`tx.outbound_anomaly_score_threshold`), `tx.blocking_paranoia_level`,
`tx.detection_paranoia_level`, `tx.critical/error/warning/notice_anomaly_score`,

Check warning on line 300 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

300:81 [line-length] line too long (88 > 80 characters)
sampling percentage, `tx.enforce_bodyproc_urlencoded`, allowed methods,
allowed content types, request body limits, or `tx.crs_validate_utf8_encoding`.

Check warning on line 302 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

302:81 [line-length] line too long (87 > 80 characters)
Each of these is a behaviour change for every default deployment and
needs the reasoning in the PR description.

Expand Down Expand Up @@ -972,15 +851,15 @@
- name: "OWASP Security (Web, API & LLM)"
mode: warning
instructions: |
Flag ⚠️ WARNING: <description> — <fix> on any affected line or block for:

Check warning on line 854 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

854:81 [line-length] line too long (83 > 80 characters)

## Web (OWASP Top 10)

Broken Access Control — missing authorization checks, insecure direct object references,

Check warning on line 858 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

858:81 [line-length] line too long (98 > 80 characters)
CORS misconfiguration, privilege escalation paths, forced browsing to authenticated resources.

Check warning on line 859 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

859:81 [line-length] line too long (104 > 80 characters)

Cryptographic Failures — hardcoded secrets or API keys, weak algorithms (MD5, SHA1, DES),

Check warning on line 861 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

861:81 [line-length] line too long (99 > 80 characters)
unencrypted sensitive data in transit or at rest, weak or expired TLS configuration,

Check warning on line 862 in .coderabbit.yaml

View workflow job for this annotation

GitHub Actions / validate

862:81 [line-length] line too long (94 > 80 characters)
secrets committed to version control.

Identification and Authentication Failures — missing MFA on sensitive operations, weak
Expand Down
26 changes: 16 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,22 @@ PR conventions). Keep the two in sync when either changes.

## Things that will bite

- **Two label families.** `release:*` is the changelog taxonomy consumed by
`.github/release.yml` — it groups the generated release notes by these and excludes
`release:ignore` entirely. They loosely mirror conventional-commit types, exactly one per PR
(enforced via `mutually_exclusive_groups`), and the fallback is `release:ignore`, never "no
label". Topic labels (`:mage: regex-assembly`, `:bomb: sqli`, …) are independent of that
family. Do not invent `release:` values; the eight configured here are exactly the ones that
exist in the repo, and each maps to one `.github/release.yml` category.
- **Label names are literal, emoji shortcode included** (`":heavy_plus_sign: False Positive"`).
They must already exist in the repo — CodeRabbit never creates them, and a missing label
silently no-ops. That is what makes an org-wide list of coreruleset-only labels safe.
- **Labeling lives in coreruleset/coreruleset's own `.coderabbit.yaml`, not here.** `release:*`
is the changelog taxonomy consumed by `.github/release.yml` — it groups the generated release
notes by these and excludes `release:ignore` entirely. They loosely mirror conventional-commit
types, exactly one per PR (enforced via `mutually_exclusive_groups`), and the fallback is
`release:ignore`, never "no label". Topic labels (`:mage: regex-assembly`, `:bomb: sqli`, …)
are independent of that family. Do not invent `release:` values; the eight are exactly the
ones that exist in coreruleset/coreruleset, and each maps to one `.github/release.yml`
category. This config used to define `labeling_instructions` org-wide on the assumption that
a missing label silently no-ops; that assumption was false — `go-ftw`, `crs-toolchain`, and
`plugin-registry` already carry labels with the exact same literal names (`release:fix`,
`release:ignore`, `release:new-feature`, `:book: documentation`) for unrelated purposes, so
the org-wide config was actively mislabeling PRs there. The schema has no per-repository
scoping field, so labeling was moved to a repo-local `.coderabbit.yaml` in
coreruleset/coreruleset (`inheritance: true`, so it still layers on this org config). Label
names are literal, emoji shortcode included (`":heavy_plus_sign: False Positive"`), and must
already exist in that repo — CodeRabbit never creates them.
- **`inheritance: true`** is set. List fields (`custom_checks`, `path_filters`,
`path_instructions`, …) are **replaced, not merged**, when a repo defines the same key
locally; the repo must set `inheritance: true` in its own `.coderabbit.yaml` to layer rather
Expand Down
Loading