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
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 2
updates:
# Keep the actions referenced by the workflow and composite action current.
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
commit-message:
prefix: ci

# Keep the Node script dependencies (Anthropic SDK) current.
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
commit-message:
prefix: deps
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Changelog

All notable changes to SecureCheck are documented here. The format is based on
[Keep a Changelog](https://keepachangelog.com/), and the project aims to follow
semantic versioning.

## [Unreleased]

### Added
- Composite action (`action.yml`) so SecureCheck can be used as
`- uses: w1ck3ds0d4/SecureCheck@<ref>` and listed on the GitHub Marketplace.
- SARIF output from Gitleaks, Semgrep and Trivy, uploaded to GitHub code
scanning (Security tab plus inline PR annotations). Requires the calling job
to grant `security-events: write`.
- Configurable severity gate via the `fail-on` input
(`none` | `low` | `medium` | `high` | `critical`). Detected secrets are always
treated as critical.
- Caching for pip, npm and the Trivy database, and a `concurrency` group (in the
reusable workflow) to cancel superseded runs.
- `gitleaks-version` input to pin the Gitleaks release.
- Findings-by-severity summary written to the job summary.
- Example consumer workflows under `examples/`.
- Dependabot configuration to keep pinned action versions current.

### Changed
- The reusable workflow (`.github/workflows/scan.yml`) is now a thin wrapper that
calls the composite action, so the scan logic lives in a single place.
- `notify.mjs` reads reports from the run's reports directory instead of a
hardcoded `/tmp` path.

### Removed
- The em-dash (U+2014) style check that previously failed builds. It was a
personal style rule, not a security control.
87 changes: 64 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# SecureCheck

Reusable GitHub Actions workflow that runs a multi-scanner security pipeline on every push and pull request and posts a single, severity-coloured summary to Discord.
GitHub **composite action** (and reusable workflow) that runs a multi-scanner security pipeline on every push and pull request: it uploads results to GitHub code scanning as SARIF, can fail the build on a severity threshold, and optionally posts a severity-coloured summary to Discord and runs an AI review of the PR diff.

---

## Features

- **Usable as a Marketplace action or a reusable workflow** - drop in a single `- uses: w1ck3ds0d4/SecureCheck@v1` step, or call the reusable workflow
- **SARIF + GitHub code scanning** - Gitleaks, Semgrep and Trivy findings upload to the Security tab and appear as inline PR annotations
- **Severity gate** - `fail-on` blocks merges at a chosen threshold (low/medium/high/critical); detected secrets always count as critical
- **Centralised scanner stack** - scanners and rules live in one repo; each consumer repo contains a thin caller, so updates propagate without touching every project
- **Gitleaks** - hardcoded secrets in the working tree and history, on every push and PR
- **Semgrep** - pattern-based SAST using the curated `auto` ruleset
Expand All @@ -30,12 +33,12 @@ Reusable GitHub Actions workflow that runs a multi-scanner security pipeline on
- A Discord channel with an **incoming webhook** (channel settings, Integrations, Webhooks, New Webhook, Copy Webhook URL)
- *Optional:* an Anthropic API key if you want the Claude review step to run on pull requests

### Add the caller workflow
### Add the workflow

Create `.github/workflows/security.yml` in the consumer repo:
Create `.github/workflows/security.yml` in the consumer repo. Recommended (composite action):

```yaml
name: Security Scan
name: Security

on:
push:
Expand All @@ -44,13 +47,37 @@ on:

permissions:
contents: read
security-events: write # required to upload SARIF to code scanning

jobs:
scan:
securecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history for gitleaks + PR diff
- uses: w1ck3ds0d4/SecureCheck@main # pin to a release tag for production
with:
fail-on: high
```

Prefer to have the whole job managed for you? Use the reusable workflow instead:

```yaml
permissions:
contents: read
security-events: write

jobs:
securecheck:
uses: w1ck3ds0d4/SecureCheck/.github/workflows/scan.yml@main
with:
fail-on: high
secrets: inherit
```

More copy-paste templates live in [`examples/`](examples/).

### Configure secrets

Set the webhook secret on the consumer repo:
Expand Down Expand Up @@ -79,6 +106,14 @@ Scans run, findings are tallied, and the Discord notifier stays silent unless at

The same scan pipeline runs, and the embed is always posted (green when clean, coloured when not) so the reviewer has a clear signal before approving. The optional Claude review runs only on pull requests; pushes skip it to save API calls.

### Failure gate

By default SecureCheck reports without failing (`fail-on: none`). Set `fail-on` to `low`, `medium`, `high`, or `critical` to fail the run (and block the merge) when a finding meets or exceeds that severity. Detected secrets always count as critical. A findings-by-severity table is written to the job summary.

### Code scanning (SARIF)

Gitleaks, Semgrep, and Trivy results upload to GitHub code scanning, so findings appear in the repo's **Security** tab and as inline annotations on the pull request. This needs `security-events: write` in the calling job (already set in the reusable workflow and the examples). Set `upload-sarif: false` to disable.

### Severity colour

| State | Colour |
Expand All @@ -96,36 +131,42 @@ When the optional Claude step runs and reports critical or high severity issues,

Every run uploads a `security-reports` artifact containing the raw JSON from each scanner (gitleaks, semgrep, trivy, claude) with 14-day retention. Useful when the embed count is non-zero and you want the full picture without re-running locally.

### Overriding defaults
### Inputs

The reusable workflow accepts three optional inputs:
| Input | Default | Description |
|---|---|---|
| `fail-on` | `none` | Minimum severity that fails the build: `none`, `low`, `medium`, `high`, `critical`. Secrets always count as critical. |
| `upload-sarif` | `true` | Upload SARIF to GitHub code scanning (needs `security-events: write`). |
| `run-claude` | `auto` | Optional Claude PR review: `auto` (PRs with a key), `true`, or `false`. |
| `node-version` | `20` | Node.js version for JS/TS tooling. |
| `python-version` | `3.11` | Python version for Semgrep / ruff / lizard. |
| `dotnet-version` | `10.0.x` | .NET SDK version (only used when a .NET project is detected). |
| `gitleaks-version` | `8.24.3` | Pinned Gitleaks release. |
| `anthropic-api-key` | `''` | Enables the Claude review when set. Pass `${{ secrets.ANTHROPIC_API_KEY }}`. |
| `discord-webhook` | `''` | Enables Discord notifications when set. Pass `${{ secrets.DISCORD_WEBHOOK_URL }}`. |

```yaml
jobs:
scan:
uses: w1ck3ds0d4/SecureCheck/.github/workflows/scan.yml@main
secrets: inherit
with:
node_version: '22'
python_version: '3.12'
dotnet_version: '10.0.x'
```
For the **reusable workflow**, pass the API key and webhook as repository secrets (`ANTHROPIC_API_KEY`, `DISCORD_WEBHOOK_URL`) together with `secrets: inherit`, rather than as `with:` inputs.

---

## Project Structure

```
SecureCheck/
action.yml Composite action (primary entry point; Marketplace-ready)
.github/
workflows/
scan.yml Reusable workflow; checkout, scanners, notify, upload
scan.yml Reusable workflow wrapper around the action
dependabot.yml Keeps action + npm versions current
scripts/
notify.mjs Builds the Discord embed from scanner counts and posts it
claude-review.mjs Sends the PR diff to Claude and emits structured findings
package.json @anthropic-ai/sdk dependency for the optional Claude step
LICENSE AGPL v3
COMMERCIAL.md Commercial license terms
notify.mjs Builds the Discord embed from scanner counts and posts it
claude-review.mjs Sends the PR diff to Claude and emits structured findings
gate.mjs Buckets findings by severity and enforces fail-on
examples/ Copy-paste consumer workflows
package.json @anthropic-ai/sdk dependency for the optional Claude step
CHANGELOG.md
LICENSE AGPL v3
COMMERCIAL.md Commercial license terms
```

---
Expand Down
20 changes: 20 additions & 0 deletions examples/security-reusable.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SecureCheck via the reusable workflow (handles checkout/permissions/concurrency
# for you). Prefer the composite action (see security.yml) unless you specifically
# want the whole job managed.
name: Security

on:
push:
branches: [main]
pull_request:

permissions:
contents: read
security-events: write

jobs:
securecheck:
uses: w1ck3ds0d4/SecureCheck/.github/workflows/scan.yml@main # pin to a tag for production
with:
fail-on: high
secrets: inherit
27 changes: 27 additions & 0 deletions examples/security-with-claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SecureCheck with the optional Claude PR review and Discord notifications.
# Set ANTHROPIC_API_KEY and DISCORD_WEBHOOK_URL as repository secrets first.
name: Security

on:
push:
branches: [main]
pull_request:

permissions:
contents: read
security-events: write

jobs:
securecheck:
name: SecureCheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: w1ck3ds0d4/SecureCheck@main # pin to a release tag for production
with:
fail-on: high
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
discord-webhook: ${{ secrets.DISCORD_WEBHOOK_URL }}
25 changes: 25 additions & 0 deletions examples/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Minimal SecureCheck setup using the composite action (recommended).
# Copy to .github/workflows/security.yml in your repo.
name: Security

on:
push:
branches: [main]
pull_request:

permissions:
contents: read
security-events: write # required so findings upload to the Security tab

jobs:
securecheck:
name: SecureCheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history for gitleaks + PR diff

- uses: w1ck3ds0d4/SecureCheck@main # pin to a release tag for production
with:
fail-on: high # block on high/critical; use 'none' to report only