-
Notifications
You must be signed in to change notification settings - Fork 1
150 lines (141 loc) · 5.71 KB
/
devsecops.yml
File metadata and controls
150 lines (141 loc) · 5.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
name: Security
# ── Trigger strategy ─────────────────────────────────────────────────────────
# • push to main → full security suite on every merged commit
# • pull_request → lightweight gate (secret scan + license check only)
# Heavy jobs (cargo compile, trivy) run post-merge.
# • schedule weekly → full audit even without code changes (CVE freshness)
# • workflow_dispatch → manual on-demand run
#
# Rationale: running cargo-audit + cargo-deny + trivy on every PR compiles the
# workspace twice and costs ~15 min of Linux time per PR. The risk window is
# acceptable because: (1) secret scanning still runs on PRs, (2) deps cannot
# reach production until merged to main.
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Weekly Monday 6 AM UTC
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# ── Secret scanning (runs on PRs + push — fast, no compilation) ──────────
secrets:
name: Secret Scanning (gitleaks)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install gitleaks
run: |
GITLEAKS_VERSION="8.21.2"
curl -sSfL "https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" \
| tar xz -C /usr/local/bin gitleaks
- name: Gitleaks scan
run: gitleaks detect --source . --verbose --redact --config .gitleaks.toml
# ── License + ban check (runs on PRs + push, fast) ───────────────────────
deny:
name: License & Ban Check (cargo-deny)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-private-deps
with:
token: ${{ secrets.PALOMA_HTTPS_TOKEN }}
- uses: dtolnay/rust-toolchain@stable
- name: Install cargo-deny
run: cargo install --locked cargo-deny@0.18.2
- name: Run cargo-deny
run: cargo deny check licenses bans sources --config deny.toml
# ── Dependency vulnerability audit (post-merge + schedule only) ──────────
# Skipped on PRs: cargo-audit requires a full workspace resolve and is
# better run on known-good (merged) code to reduce noise.
audit:
name: Dependency Audit (cargo-audit)
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
# Advisory only — upstream CVEs should not block the pipeline.
# Review findings in GitHub Security tab.
continue-on-error: true
permissions:
contents: read
checks: write
steps:
- uses: actions/checkout@v4
- uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
# ── Clippy security lints (post-merge + schedule only) ───────────────────
# CI already runs clippy on every PR. This job adds security-focused lints
# (unsafe, integer arithmetic, etc.) only when merging.
clippy-security:
name: Clippy Security Lints
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-private-deps
with:
token: ${{ secrets.PALOMA_HTTPS_TOKEN }}
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- name: Security-focused clippy
run: cargo clippy --workspace --no-default-features --exclude momoto-core --exclude momoto-metrics --exclude momoto-intelligence -- -D warnings
# ── Container/filesystem scan (post-merge + schedule only) ───────────────
trivy:
name: Trivy Vulnerability Scan
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- name: Run Trivy (filesystem scan)
uses: aquasecurity/trivy-action@0.35.0
with:
scan-type: fs
scan-ref: .
format: sarif
output: trivy-results.sarif
severity: HIGH,CRITICAL
exit-code: 0 # Report only — don't fail build
- name: Upload Trivy SARIF
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
category: trivy-filesystem
# ── Weekly SBOM snapshot (schedule only, no code changes required) ────────
sbom-weekly:
name: Weekly SBOM
runs-on: ubuntu-latest
# Guard against forks accidentally consuming minutes via inherited schedules.
# Repository was renamed `halcon-cli` → `halcon`; the previous condition
# silently never matched.
if: github.event_name == 'schedule' && github.repository == 'cuervo-ai/halcon'
steps:
- uses: actions/checkout@v4
- name: Install syft
run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
- name: Generate SBOM
run: |
syft dir:. \
--output spdx-json=sbom-weekly.spdx.json \
--output cyclonedx-json=sbom-weekly.cyclonedx.json
- name: Upload SBOM artifacts
uses: actions/upload-artifact@v4
with:
name: weekly-sbom-${{ github.run_id }}
path: |
sbom-weekly.spdx.json
sbom-weekly.cyclonedx.json
retention-days: 90