Skip to content
Merged
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
42 changes: 29 additions & 13 deletions .github/workflows/reusable-dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ on:
required: false
default: false
type: boolean
gate_repository:
description: Repository containing Security Gate scripts and dashboard assets
required: false
default: hel-isa/security-gate
type: string
gate_ref:
description: Git ref for Security Gate scripts and dashboard assets
required: false
default: v2
Comment on lines +21 to +24
type: string

permissions:
contents: read
Expand All @@ -22,13 +32,13 @@ permissions:
jobs:
dashboard:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

steps:
- name: Checkout repository
- name: Checkout Security Gate assets
uses: actions/checkout@v4
with:
repository: ${{ inputs.gate_repository }}
ref: ${{ inputs.gate_ref }}
path: security-gate
Comment on lines +36 to +41

- name: Download security artifacts
uses: actions/download-artifact@v4
Expand All @@ -41,17 +51,17 @@ jobs:
run: |
set -euo pipefail
mkdir -p reports/normalized
python scripts/aggregate_results.py \
python security-gate/scripts/aggregate_results.py \
--input-dir reports/raw \
--output-file reports/normalized/dashboard-data.json \
--repo-name "${{ inputs.repo_name || github.repository }}"

- name: Build static dashboard package
run: |
set -euo pipefail
python scripts/generate_dashboard.py \
python security-gate/scripts/generate_dashboard.py \
--data-file reports/normalized/dashboard-data.json \
--dashboard-dir dashboard \
--dashboard-dir security-gate/dashboard \
--output-dir reports/dashboard

- name: Verify dashboard output
Expand All @@ -67,17 +77,23 @@ jobs:
path: reports/dashboard
if-no-files-found: error

- name: Configure Pages
if: inputs.deploy_pages
uses: actions/configure-pages@v5

- name: Upload Pages artifact
if: inputs.deploy_pages
uses: actions/upload-pages-artifact@v3
with:
path: reports/dashboard

deploy-pages:
runs-on: ubuntu-latest
needs: dashboard
if: inputs.deploy_pages
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Configure Pages
uses: actions/configure-pages@v5

- name: Deploy to GitHub Pages
if: inputs.deploy_pages
id: deployment
uses: actions/deploy-pages@v4
119 changes: 119 additions & 0 deletions .github/workflows/reusable-security-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Reusable - Security Gate

on:
workflow_call:
inputs:
mode:
description: Gate mode. Use audit for non-blocking scans or strict to fail on findings.
required: false
default: audit
type: string
semgrep_config:
description: Semgrep config or ruleset.
required: false
default: auto
type: string
gitleaks_config_path:
description: Path to a Gitleaks config file in the scanned repository.
required: false
default: .gitleaks.toml
type: string
sbom_scan_path:
description: Path to scan for SBOM generation.
required: false
default: .
type: string
repo_name:
description: Repository name override for dashboard output.
required: false
default: ''
type: string
deploy_pages:
description: Deploy the dashboard to GitHub Pages on eligible runs.
required: false
default: false
type: boolean
gate_repository:
description: Repository containing Security Gate scripts and dashboard assets.
required: false
default: hel-isa/security-gate
type: string
gate_ref:
description: Git ref for Security Gate scripts and dashboard assets.
required: false
default: v2
Comment on lines +42 to +44
type: string

permissions:
contents: read
pages: write
id-token: write
Comment on lines +47 to +50

jobs:
validate:
name: Validate Gate Configuration
runs-on: ubuntu-latest
outputs:
fail_on_findings: ${{ steps.mode.outputs.fail_on_findings }}
steps:
- name: Resolve mode
id: mode
run: |
set -euo pipefail
case "${{ inputs.mode }}" in
audit|non-strict)
echo "fail_on_findings=false" >> "$GITHUB_OUTPUT"
;;
strict)
echo "fail_on_findings=true" >> "$GITHUB_OUTPUT"
;;
*)
echo "Unsupported security gate mode: ${{ inputs.mode }}"
echo "Use audit, non-strict, or strict."
exit 1
;;
esac

secrets:
name: Secrets Detection
needs: validate
uses: ./.github/workflows/reusable-secrets.yml
with:
fail_on_findings: ${{ needs.validate.outputs.fail_on_findings == 'true' }}
config_path: ${{ inputs.gitleaks_config_path }}

sast:
name: SAST Scan
needs: validate
uses: ./.github/workflows/reusable-sast.yml
with:
fail_on_findings: ${{ needs.validate.outputs.fail_on_findings == 'true' }}
config: ${{ inputs.semgrep_config }}

sca:
name: SCA Scan
needs: validate
uses: ./.github/workflows/reusable-sca.yml
with:
fail_on_findings: ${{ needs.validate.outputs.fail_on_findings == 'true' }}

sbom:
name: SBOM Generation
uses: ./.github/workflows/reusable-sbom.yml
with:
scan_path: ${{ inputs.sbom_scan_path }}

dashboard:
name: Security Dashboard
needs:
- secrets
- sast
- sca
- sbom
if: always()
Comment on lines +109 to +113
uses: ./.github/workflows/reusable-dashboard.yml
with:
repo_name: ${{ inputs.repo_name }}
deploy_pages: ${{ inputs.deploy_pages }}
gate_repository: ${{ inputs.gate_repository }}
gate_ref: ${{ inputs.gate_ref }}
41 changes: 7 additions & 34 deletions .github/workflows/security-baseline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,11 @@ permissions:
id-token: write

jobs:
secrets:
name: Secrets Detection
uses: hel-isa/security-gate/.github/workflows/reusable-secrets.yml@main
security-gate:
name: Security Gate
uses: ./.github/workflows/reusable-security-gate.yml
with:
fail_on_findings: true

sast:
name: SAST Scan
uses: hel-isa/security-gate/.github/workflows/reusable-sast.yml@main
with:
fail_on_findings: true
config: auto

sca:
name: SCA Scan
uses: hel-isa/security-gate/.github/workflows/reusable-sca.yml@main
with:
fail_on_findings: true

sbom:
name: SBOM Generation
uses: hel-isa/security-gate/.github/workflows/reusable-sbom.yml@main

dashboard:
name: Security Dashboard
needs:
- secrets
- sast
- sca
- sbom
if: always()
uses: hel-isa/security-gate/.github/workflows/reusable-dashboard.yml@main
with:
repo_name: ${{ github.repository }}
deploy_pages: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
mode: audit
semgrep_config: auto
repo_name: ${{ github.repository }}
deploy_pages: false
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog

## v2.0.0 - Initial Product Release

Stable release for approved repositories that need a reusable Security Gate workflow.

### Added

- Product-level reusable workflow: `.github/workflows/reusable-security-gate.yml`.
- Audit and strict presets through the `mode` input.
- Copy-paste consumer workflow examples for audit and strict rollout.
- Onboarding, preset, and architecture documentation for approved consumers.
- Dashboard asset checkout through `gate_repository` and `gate_ref` so consumers do not need local dashboard scripts.

### Release Notes

Approved consumers should pin both the reusable workflow reference and `gate_ref` to `v2.0.0`.
70 changes: 57 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
# Security Guardrails as a Service (v1)
# Security Gate (v2)

A GitHub-native, reusable, modular DevSecOps baseline that uses only free/open-source tools and does **not** depend on GitHub Advanced Security.
A GitHub-native, reusable security gate that lets approved repositories scan code with a practical default workflow. It uses free/open-source tools and does **not** depend on GitHub Advanced Security.

## Project Purpose
This project provides a production-minded starting point for security checks in CI:
- modular reusable workflows
- standardized JSON artifacts
- lightweight static dashboard reporting
- Python-based data normalization for extensibility
Security Gate provides a productized starting point for security checks in CI:

- one default workflow users can call remotely
- audit and strict presets for non-blocking or blocking scans
- language-agnostic baseline controls
- optional low-level reusable workflows for advanced teams
- standardized JSON artifacts and lightweight dashboard reporting

## Architecture at a Glance
- Orchestrator workflow: `.github/workflows/security-baseline.yml`
- Product entry point: `.github/workflows/reusable-security-gate.yml`
- Local baseline workflow: `.github/workflows/security-baseline.yml`
- Independent reusable controls:
- `reusable-secrets.yml` (Gitleaks)
- `reusable-sast.yml` (Semgrep)
Expand All @@ -26,20 +29,52 @@ Detailed design is documented in `docs/architecture.md`.
- SCA: OSV-Scanner
- SBOM: Syft (CycloneDX JSON)

## Quick Start for Approved Repositories

Copy one of the templates from `examples/` into the target repository as `.github/workflows/security-gate.yml`.

Start in audit mode:

```yaml
jobs:
security-gate:
name: Security Gate
uses: hel-isa/security-gate/.github/workflows/reusable-security-gate.yml@v2.0.0
with:
mode: audit
semgrep_config: auto
repo_name: ${{ github.repository }}
gate_ref: v2.0.0
```

Switch to strict mode when the team is ready to block on findings:

```yaml
with:
mode: strict
semgrep_config: auto
```

See `docs/onboarding.md` for the full copy-paste workflow, `docs/presets.md` for preset guidance, `docs/release-management.md` for stable tag usage, and `docs/external-company-rollout.md` for repositories owned by another company.

## Repository Layout
- `.github/workflows/` - orchestrator and reusable workflow modules
- `examples/` - copy-paste workflows for consuming repositories
- `scripts/` - Python helpers for normalization/dashboard packaging
- `dashboard/` - static dashboard assets (HTML/CSS/JS)
- `docs/` - architecture and secure coding baseline docs
- `.gitleaks.toml` - local gitleaks config
- `SECURITY.md` - vulnerability reporting + scope
- `pull_request_template.md` - secure review checklist

## How to Enable Workflows
1. Push this repository to GitHub.
2. Ensure GitHub Actions are enabled for the repository.
3. Confirm default branch is `main` (or adjust trigger branch in `security-baseline.yml`).
4. Open a PR or push to `main` to trigger scans.
## Presets

| Preset | Mode | Behavior |
| --- | --- | --- |
| Audit | `audit` | Runs scans and reports findings without blocking merges. |
| Strict | `strict` | Runs scans and fails when blocking findings are detected. |

`non-strict` is accepted as an alias for `audit`.

## Artifacts and Dashboard
Each control uploads artifacts in JSON format:
Expand All @@ -56,6 +91,14 @@ The dashboard workflow downloads artifacts, normalizes results into `dashboard-d

Open `index.html` locally from the dashboard artifact folder to view the report.

## Advanced Usage

Advanced teams can call individual reusable workflows directly when they need custom composition. Most repositories should use `reusable-security-gate.yml`.

## Stable Releases

Approved consumers should pin to immutable release tags such as `v2.0.0`. Keep the workflow reference and `gate_ref` aligned so the reusable workflow and dashboard assets come from the same release.

## Local Usage (where applicable)
- Aggregation script:
```bash
Expand All @@ -72,3 +115,4 @@ Open `index.html` locally from the dashboard artifact folder to view the report.
- Multi-repo rollup dashboards
- SARIF export option
- Optional Slack/Teams notifications
- v3 bot to inspect repositories and generate tuned workflow/configuration
6 changes: 4 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,19 @@ Include:
- Potential impact
- Suggested remediation (if known)

## Supported Scope (v1)
This repository provides CI guardrails for:
## Supported Scope (v2)
This repository provides a reusable CI security gate for approved repositories:
- Secrets detection (Gitleaks)
- SAST (Semgrep)
- SCA (OSV-Scanner)
- SBOM generation (Syft)
- Static dashboard artifacts

## Out of Scope
- Runtime protection
- Cloud workload posture management
- Proprietary GHAS-only features
- Approval management for consuming repositories

## Disclosure Expectations
- Do not publicly disclose vulnerabilities before triage.
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.0.0
Loading
Loading