diff --git a/changelog.mdx b/changelog.mdx index edec564..56455aa 100644 --- a/changelog.mdx +++ b/changelog.mdx @@ -49,7 +49,7 @@ rss: true **API access through MCP protocol**: Connect external tools and scripts to Hacktron's finding-triage toolset through a new remote MCP server endpoint with OAuth and API key authentication. - **Skip scans with repository configuration**: Use `.hacktron/config.yaml` to skip pull request scans based on file patterns, keywords in titles, or labels. + **Exclude scans with repository configuration**: Use `.hacktron/config.yaml` to exclude pull request scans based on file patterns, keywords in titles, or labels. **[Secure your account with MFA →](/platform/account-settings)** · **[See MCP integration →](/mcp/get-started)** · **[Configure repository scanning →](/code-review/config)** diff --git a/code-review/config.mdx b/code-review/config.mdx index 26298be..aa77e84 100644 --- a/code-review/config.mdx +++ b/code-review/config.mdx @@ -5,11 +5,25 @@ description: "Use .hacktron/config.yaml to control which pull and merge requests Add a `.hacktron/config.yaml` file to your repository to control Hacktron's Code Review behavior: -- **Skip** specific pull and merge requests so they aren't scanned. +- **Exclude** specific pull and merge requests so they aren't scanned. +- **Include** specific pull and merge requests to be scanned. - **Fail** the Hacktron check when a finding meets a severity threshold, so risky changes can't merge. This is separate from [`.hacktron/rules.md`](/code-review/rules), which shapes the *quality* of a review. `config.yaml` controls *whether* a PR is scanned and *whether* its check passes. + + Want to override these rules for a single PR? Comment `@hacktronai review` to force a scan. + + +## Configuration hierarchy + +Each category (`exclude.*`, `include.*`, `fail_on.severity`) is resolved independently, not the whole file at once: + +1. **`config.yaml`** — used if the repo sets this category. +2. **[Organization settings](/platform/organization-settings#scan-filters)** — used otherwise. + +See the [FAQ](#faq) for worked examples of how repo and org settings combine. + ## File location Place the file at the root of the repository, inside the `.hacktron` directory: @@ -38,89 +52,137 @@ Either `.hacktron/config.yaml` or `.hacktron/config.yml` is accepted. If both ex ```yaml # .hacktron/config.yaml -# Skip a PR/MR from being scanned when any rule below matches. -skip: +# Exclude a PR/MR from being scanned when any rule below matches. +exclude: labels: - - hacktron-skip + - hacktron-exclude keywords: - - "[skip hacktron]" + - "[exclude hacktron]" paths: - "vendor/**" - "**/*.md" + authors: + - dependabot[bot] # Fail the Hacktron check when a finding is at or above this severity. fail_on: severity: high ``` -Every key is optional. An empty or absent `config.yaml` means Hacktron behaves as it does today: it scans all covered PRs and the check stays green unless the scan itself errors. +Every key is optional. An empty or absent `config.yaml` doesn't disable filtering; see [Configuration hierarchy](#configuration-hierarchy) for how org-wide filters still apply. With no repo or org filters set, Hacktron scans all covered PRs and the check stays green unless the scan itself errors. -## Skip scans +## Exclude scans -Use the `skip` block to tell Hacktron not to scan a pull or merge request. When a PR matches, Hacktron records a **skipped** check on the PR/MR and posts a short comment naming the rule that matched. No scan runs, and **no developer seat is used**. +The `exclude` block tells Hacktron not to scan a pull or merge request. A match records a **skipped** check with a comment naming the rule, and uses no developer seat. -Rules are evaluated in this order; the first match wins: +Rules are evaluated in this order, first match applies: | Key | Matches when | Match style | |---|---|---| -| `skip.labels` | the PR/MR carries one of these labels | exact, case-insensitive | -| `skip.keywords` | the PR/MR **title** contains one of these strings | case-insensitive substring | -| `skip.paths` | **every** changed file matches one of these patterns | gitignore-style globs | +| `exclude.branches` | the PR/MR targets one of these branches | case-insensitive glob | +| `exclude.labels` | the PR/MR carries one of these labels | case-insensitive exact match| +| `exclude.keywords` | the PR/MR **title** contains one of these strings | case-insensitive substring | +| `exclude.paths` | **every** changed file matches one of these patterns | case-insensitive glob | +| `exclude.authors` | the PR/MR was opened by one of these usernames | case-insensitive exact match| +| any key set to `[]` | clears the org-wide default for that key ([Configuration hierarchy](#configuration-hierarchy)) | - | ```yaml -skip: +exclude: + branches: + - "release/legacy/**" # exclude PRs targeting a legacy release branch labels: - - hacktron-skip # label the PR "hacktron-skip" to skip it + - hacktron-exclude # label the PR "hacktron-exclude" to exclude it keywords: - - "[skip hacktron]" # put this anywhere in the PR/MR title to skip it + - "[exclude hacktron]" # put this anywhere in the PR/MR title to exclude it paths: - - "docs/**" # skip when the PR only touches these paths + - "docs/**" # exclude when the PR only touches these paths - "**/*.md" + authors: + - "dependabot[bot]" # exclude all PRs opened by dependabot ``` - `skip.paths` skips a scan **only when every changed file matches** one of the + `exclude.paths` excludes a scan **only when every changed file matches** one of the patterns. If even one changed file falls outside the patterns, the PR is - scanned as usual. Patterns use the same syntax as `.gitignore` — for example - `vendor/**`, `**/*.md`, or `docs/`. + scanned as usual. Patterns use the same glob syntax as `exclude.branches` — for + example `vendor/**`, `**/*.md`, or `docs/**`. -A manual `@hacktronai review` comment always runs a scan, even when a `skip` rule would otherwise match — use it to force a one-off review of an otherwise-skipped PR. + + `exclude.branches`, `exclude.paths`, and `include.branches` (and their org-wide + equivalents) accept glob patterns mixed with literals: `*`, `**`, `?`, and + `{a,b}` brace expansion. Matching is case-insensitive. `[`, `]`, and a + leading `!` are literal, not special syntax. Each category allows up to 50 entries. + + + + `*` matches within one path segment; `**` also crosses `/`. + + | Pattern | Matches | Doesn't match | + |---|---|---| + | `release/*` | `release/foo` | `release/foo/bar` | + | `release/**` | `release/foo`, `release/foo/bar` | — | + | `release/legacy/**` | `release/legacy/1`, `release/legacy/1/hotfix` | `release/other/1` | + + Use `release/*` for one-level branches (e.g. `release/2.4`). Use `release/**` + to cover any depth. Add a literal segment like `release/legacy/**` to target + just that subtree. + + Combine `exclude` and `include` to exclude a subtree: `include.branches: + ["release/**"]` with `exclude.branches: ["release/legacy/**"]` scans all + release branches except `release/legacy/**`. + + +## Include scans + +Use the include block to scan **only** pull and merge requests that match specific rules. Hacktron records a skip check comment on PRs/MRs it doesn't scan. + +```yaml +include: + branches: + - "main" + - "release/**" # only scan PRs targeting main or a release branch + labels: + - security-review # only scan PRs labelled "security-review" + authors: + - alice # ...and were opened by Alice or Bob + - bob + keywords: + - "please review" # ...and title contains "please review" +``` + +| Key | Matches when | +|---|---| +| `include.branches` | the PR/MR targets one of these branches (case-insensitive glob) | +| `include.labels` | the PR/MR carries at least one of these labels (case-insensitive exact match) | +| `include.authors` | the PR/MR was opened by one of these usernames (case-insensitive exact match) | +| `include.keywords` | the PR/MR title contains one of these strings (case-insensitive substring) | +| any key set to `[]` | clears the org-wide default for that key ([Configuration hierarchy](#configuration-hierarchy)) | + +`include.labels: [feature, bugfix]` matches either label. Across categories, `include` requires matching all: `include.branches: [main]` + `include.authors: [alice]` only scans Alice's PRs to `main`. + + + `exclude` and `include` can target the same category. See [glob matching](/code-review/config#matching-nested-branches-with-vs) for pattern syntax. + ## Fail the check on findings By default, the Hacktron check is green as long as the scan completes. Findings are posted as inline comments but don't block the merge. Configure a severity threshold to turn the check **red** when a finding is at or above that level. -When a finding triggers the gate, the GitHub check run (or GitLab commit status) is marked failed. - ![Failed check example](/images/fail_on_failure_example.png) The threshold is **inclusive**: `high` fails the check on `high` *and* `critical` findings, while `critical` fails only on `critical`. - Triaging a finding updates the existing check directly. A finding only counts toward the threshold while it's still **open or confirmed valid**; triaging it as anything else removes it from the gate and immediately recomputes the check. + Only **open or confirmed valid** findings count toward the threshold. [Triaging](/code-review/findings-feedback#triage-comments) one recomputes the check immediately. -You can set the threshold org-wide from the settings page, or per repository in `config.yaml`. The repository config always takes precedence. +You can set the threshold org-wide from the settings page, or per repository in `config.yaml` (see [Configuration hierarchy](#configuration-hierarchy)). - Set a default for all repositories in your organization: - - - - Select your organization, then go to **Settings**. - - - Locate **Severity threshold**, above the SLA Thresholds card. - - ![Severity threshold settings card](/images/severity_threshold.png) - - - Pick a severity from the dropdown: **Critical**, **High**, **Medium**, or **Low**. Select **Off** to disable the gate org-wide. - - + Set a default for all repositories in your organization from [Organization settings](/platform/organization-settings#check-gate). @@ -141,12 +203,45 @@ You can set the threshold org-wide from the settings page, or per repository in ## How invalid config is handled -Hacktron is **fail-open** about configuration — a config problem never silently blocks your development: +Hacktron is **fail-open** about configuration: - A missing, empty, or malformed `config.yaml` is ignored. Hacktron scans normally and the check stays green. - Unknown keys are ignored, so a config can carry settings for future features without breaking today's scans. - A type mismatch on a known key (for example `fail_on.severity: 7`) causes the **whole file** to be ignored. Keep values in the shapes shown above. +## FAQ + + + + Org default: `include.labels: [security-review]` (only PRs labelled + `security-review` get scanned). + + A repo can set its own `include.labels: [needs-review]` in `config.yaml` + to require a different label instead, or set `include.labels: []` to + remove the requirement entirely and scan PRs regardless of label. Either + way, the repo's setting **replaces** the org rule rather than merging + with it. + + + + Org default: `fail_on.severity: critical`. + + A repo handling payment code wants to fail on more than just critical + findings, so it sets `fail_on.severity: high` in `config.yaml`. That + repo's check now turns red on `high` or `critical` findings; every other + repo keeps using `critical`. + + + + No, each filter category (`exclude.branches`, `exclude.labels`, `include.branches`, and so on) is inherited independently. + + Org default: `exclude.labels: [wip]`. A repo adds `exclude.branches: + [release/legacy/**]` but doesn't set `exclude.labels`. That repo now excludes + legacy release branches **and** still excludes `wip`-labelled PRs. The org's + label rule keeps applying because the repo never overrode it. + + + ## Related diff --git a/code-review/findings-feedback.mdx b/code-review/findings-feedback.mdx index 992bc3e..7c4583c 100644 --- a/code-review/findings-feedback.mdx +++ b/code-review/findings-feedback.mdx @@ -66,6 +66,7 @@ so reviews get sharper, with fewer false positives and more of the bugs that act - `!fp ` to mark the finding as a false positive - `!accepted_risk ` to mark the finding as an accepted risk - `!valid ` to mark the finding as a true positive + - `!fixed ` to mark the finding as resolved Triage comments diff --git a/code-review/rules.mdx b/code-review/rules.mdx index 63dd420..952cde2 100644 --- a/code-review/rules.mdx +++ b/code-review/rules.mdx @@ -46,6 +46,6 @@ Commit `.hacktron/rules.md` to the branch Hacktron reviews, such as your default - Use `.hacktron/config.yaml` to skip scans and fail the check on findings. + Use `.hacktron/config.yaml` to exclude scans and fail the check on findings. diff --git a/code-review/setup.mdx b/code-review/setup.mdx index 6770d9c..cefbeda 100644 --- a/code-review/setup.mdx +++ b/code-review/setup.mdx @@ -41,12 +41,11 @@ You also need permission to connect your Git provider. For more details, choose - For each repository, choose whether Hacktron should review pull requests or - merge requests targeting all branches or only specific branches such as - `main` or `production`. - - Branches - + Hacktron reviews all branches by default. Restrict this org-wide in + [Organization settings](/platform/organization-settings#scan-filters), or + per repository via `exclude.branches` / `include.branches` in + `.hacktron/config.yaml`. See [Repository + configuration](/code-review/config) for the syntax. Go to an existing pull request or merge request and comment `@hacktronai review`. diff --git a/docs.json b/docs.json index 102437a..4d29841 100644 --- a/docs.json +++ b/docs.json @@ -73,7 +73,8 @@ "group": "Account", "pages": [ "platform/account-settings", - "platform/security-settings" + "platform/security-settings", + "platform/organization-settings" ] }, { diff --git a/images/scan_filters.png b/images/scan_filters.png new file mode 100644 index 0000000..7504b86 Binary files /dev/null and b/images/scan_filters.png differ diff --git a/platform/dashboard.mdx b/platform/dashboard.mdx index 6628d20..249aec7 100644 --- a/platform/dashboard.mdx +++ b/platform/dashboard.mdx @@ -18,22 +18,11 @@ by clicking on **Export**. ## Resolution Health - From the settings page, you can configure SLA tresholds for remediating findings of different severities. - - SLA thresholds - - This is used to track your resolution health. Hacktron calculates your Mean Time to Resolution (MTTR), - and the percentage of findings that are resolved within the SLA tresholds. + Hacktron calculates your Mean Time to Resolution (MTTR) and the percentage of findings resolved within your SLA thresholds. Resolution health - ## Check gate - - From the settings page, you can also set an org-wide **Severity threshold**. - - Severity threshold settings card - - See [Fail the check on findings](/code-review/config#fail-the-check-on-findings) for details and per-repository overrides. + Configure the resolution window and compliance target per severity in [Organization settings](/platform/organization-settings#sla-thresholds). diff --git a/platform/organization-settings.mdx b/platform/organization-settings.mdx new file mode 100644 index 0000000..617a99e --- /dev/null +++ b/platform/organization-settings.mdx @@ -0,0 +1,85 @@ +--- +title: "Organization settings" +description: "Configure scan filters, the check gate, and SLA thresholds for your organization." +--- + +Organization settings apply to every repository unless a repository's `.hacktron/config.yaml` overrides them. Only organization admins and owners can change these settings. + + + + Select your organization, then go to **Settings**. + + + +## Scan filters + +Choose which pull and merge requests Hacktron scans by default, across four categories: branches, labels, authors, and keywords. + + + + Locate **Filters**. + + + Select **Add filter**. Choose a category and a direction, then enter one or more values. + + Filters card + + + +| Category | Match style | +|---|---| +| Branches | Glob pattern, case-insensitive (e.g. `release/*`) | +| Labels | Exact name, case-insensitive | +| Authors | Exact username, case-insensitive | +| Keywords | Substring in the PR/MR title, case-insensitive | + + + **Include** and **Exclude** can both be set for the same category: Exclude takes priority within that category. Setting a filter for one category has no effect on the others. + + +Want per-repo control? Override any category in `.hacktron/config.yaml`. See [Repository configuration](/code-review/config) for the glob syntax, limits, and how repo config overrides org defaults. + +## Check gate + +Set an org-wide severity threshold that fails a PR or MR check when a finding meets or exceeds it. + + + + Locate **Severity threshold**. + + Severity threshold settings card + + + Pick a severity: **Critical**, **High**, **Medium**, or **Low**. Select **Off** to disable the gate org-wide. + + + +See [Fail the check on findings](/code-review/config#fail-the-check-on-findings) for the full severity table and per-repository overrides. + +## SLA thresholds + +Set the resolution window and minimum compliance target for each severity. + + + + Locate **SLA Thresholds**. + + SLA thresholds settings card + + + For each severity, set the number of days findings have to be resolved in, and the minimum percentage that should meet it. + + + +These values drive the Resolution Health widget on the [dashboard](/platform/dashboard#resolution-health), including Mean Time to Resolution (MTTR) and SLA compliance. + +## Related + + + + Connect a Git provider, enable repositories, and choose covered branches. + + + Use `.hacktron/config.yaml` to override scan filters and the check gate per repository. + +