-
Notifications
You must be signed in to change notification settings - Fork 0
297 lines (283 loc) · 11.5 KB
/
ci.yml
File metadata and controls
297 lines (283 loc) · 11.5 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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
security-events: write
jobs:
# ── Lint + static analysis ──────────────────────────────────────
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: ruff
- run: ruff check skills/ tests/ mcp-server/ scripts/ --config pyproject.toml
skill-contract:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
- run: python scripts/validate_skill_contract.py
- run: python scripts/validate_skill_integrity.py
- run: python scripts/validate_dependency_consistency.py
- run: python scripts/validate_framework_coverage.py
- run: python scripts/validate_ocsf_metadata.py
safe-skill-bar:
runs-on: ubuntu-latest
needs: [lint, skill-contract]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: bandit pip-audit
- run: python scripts/validate_safe_skill_bar.py
- name: Check for hardcoded secrets
run: |
! grep -rn "AKIA[A-Z0-9]\{16\}" skills/*/*/src/ mcp-server/src/ scripts/ --include="*.py" || exit 1
! grep -rn "sk-[a-zA-Z0-9]\{20,\}" skills/*/*/src/ mcp-server/src/ scripts/ --include="*.py" || exit 1
! grep -rn "ghp_[a-zA-Z0-9]\{36\}" skills/*/*/src/ mcp-server/src/ scripts/ --include="*.py" || exit 1
echo "No hardcoded secrets found in enforced executable paths"
- name: Dependency vulnerability audit
run: pip-audit "${{ github.workspace }}"
security-scan:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: bandit
- run: bandit -r skills/evaluation/cspm-aws-cis-benchmark skills/remediation/iam-departures-remediation mcp-server -c pyproject.toml --severity-level medium
# ── Unit tests, grouped into category lanes ───────────────────
test-compliance:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: >-
boto3 moto pytest pytest-cov
google-cloud-compute google-cloud-iam google-cloud-resource-manager google-cloud-storage
azure-identity azure-mgmt-network azure-mgmt-resource azure-mgmt-storage
- name: Run compliance skill suites
shell: bash
run: |
set -euo pipefail
for skill in \
cspm-aws-cis-benchmark \
cspm-gcp-cis-benchmark \
cspm-azure-cis-benchmark \
k8s-security-benchmark \
container-security
do
echo "==> skills/evaluation/${skill}"
pytest "skills/evaluation/${skill}/tests/" -v -o "testpaths=tests"
done
test-remediation:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: >-
boto3 moto pytest pytest-cov
google-cloud-iam google-cloud-resource-manager google-api-python-client
azure-identity
clickhouse-connect databricks-sql-connector httpx snowflake-connector-python
- run: pytest skills/remediation/iam-departures-remediation/tests/ -v -o "testpaths=tests"
test-detection-engineering:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: pytest pytest-cov
- name: Run ingestion, detection, and view suites
shell: bash
run: |
set -euo pipefail
for skill_dir in \
skills/ingestion/ingest-cloudtrail-ocsf \
skills/ingestion/ingest-vpc-flow-logs-ocsf \
skills/ingestion/ingest-vpc-flow-logs-gcp-ocsf \
skills/ingestion/ingest-nsg-flow-logs-azure-ocsf \
skills/ingestion/ingest-guardduty-ocsf \
skills/ingestion/ingest-security-hub-ocsf \
skills/ingestion/ingest-gcp-scc-ocsf \
skills/ingestion/ingest-azure-defender-for-cloud-ocsf \
skills/ingestion/ingest-gcp-audit-ocsf \
skills/ingestion/ingest-azure-activity-ocsf \
skills/ingestion/ingest-entra-directory-audit-ocsf \
skills/ingestion/ingest-okta-system-log-ocsf \
skills/ingestion/ingest-google-workspace-login-ocsf \
skills/ingestion/ingest-k8s-audit-ocsf \
skills/ingestion/ingest-mcp-proxy-ocsf \
skills/detection/detect-mcp-tool-drift \
skills/detection/detect-okta-mfa-fatigue \
skills/detection/detect-google-workspace-suspicious-login \
skills/detection/detect-privilege-escalation-k8s \
skills/detection/detect-sensitive-secret-read-k8s \
skills/detection/detect-lateral-movement \
skills/view/convert-ocsf-to-sarif \
skills/view/convert-ocsf-to-mermaid-attack-flow
do
echo "==> ${skill_dir}"
pytest "${skill_dir}/tests/" -v -o "testpaths=tests"
done
test-ai-infra-security:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
name: test-ai-infra
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: >-
boto3 pytest pytest-cov
google-cloud-compute google-cloud-iam google-cloud-resource-manager google-cloud-storage
azure-identity azure-mgmt-resource
- name: Run discovery and AI infra skill suites
shell: bash
run: |
set -euo pipefail
for skill_dir in \
skills/discovery/discover-environment \
skills/discovery/discover-ai-bom \
skills/discovery/discover-control-evidence \
skills/discovery/discover-cloud-control-evidence \
skills/evaluation/model-serving-security \
skills/evaluation/gpu-cluster-security
do
echo "==> ${skill_dir}"
pytest "${skill_dir}/tests/" -v -o "testpaths=tests"
done
test-integration:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: pytest pytest-cov
- run: pytest tests/integration/ mcp-server/tests/ -v -o "testpaths=tests"
# ── IaC validation (CloudFormation + Terraform in one job) ─────
validate-iac:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: cfn-lint
- uses: hashicorp/setup-terraform@v4
with:
terraform_version: "1.12.0"
- name: cfn-lint — CloudFormation
run: |
cfn-lint skills/remediation/iam-departures-remediation/infra/cloudformation.yaml
cfn-lint skills/remediation/iam-departures-remediation/infra/cross_account_stackset.yaml
- name: terraform validate
run: cd skills/remediation/iam-departures-remediation/infra/terraform && terraform init -backend=false && terraform validate
# ── agent-bom scans (code + skills + fs + IaC with SARIF upload) ─
agent-bom:
runs-on: ubuntu-latest
needs: [lint, skill-contract, safe-skill-bar]
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-python-deps
with:
python-version: "3.11"
packages: agent-bom
- name: Scan code for AI components
run: agent-bom code skills/ -f json -o code-scan.json || true
- name: Audit skill definitions
run: agent-bom skills scan skills/ -f json -o skills-audit.json --verbose || true
- name: Scan filesystem for packages and CVEs
run: agent-bom fs skills/ -f json -o fs-scan.json || true
- name: Scan IaC (CloudFormation + Terraform)
run: |
agent-bom iac \
skills/remediation/iam-departures-remediation/infra/cloudformation.yaml \
skills/remediation/iam-departures-remediation/infra/cross_account_stackset.yaml \
skills/remediation/iam-departures-remediation/infra/terraform/main.tf \
-f json -o iac-scan.json || true
- name: Scan IaC (SARIF for code scanning)
run: |
agent-bom iac \
skills/remediation/iam-departures-remediation/infra/cloudformation.yaml \
skills/remediation/iam-departures-remediation/infra/cross_account_stackset.yaml \
skills/remediation/iam-departures-remediation/infra/terraform/main.tf \
-f sarif -o iac-scan.sarif || true
- name: Normalise SARIF (handle agent-bom empty-result quirk)
if: always()
run: |
python3 - <<'PY'
import json, os
path = "iac-scan.sarif"
stub = {
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
"version": "2.1.0",
"runs": [{
"tool": {"driver": {"name": "agent-bom-iac", "version": "0.76.2", "informationUri": "https://github.com/msaad00/agent-bom"}},
"results": []
}]
}
if not os.path.exists(path):
json.dump(stub, open(path, "w"))
print("wrote stub SARIF (file missing)")
else:
try:
doc = json.load(open(path))
except Exception as e:
json.dump(stub, open(path, "w"))
print(f"wrote stub SARIF (json parse failed: {e})")
else:
if not (isinstance(doc, dict) and "runs" in doc):
json.dump(stub, open(path, "w"))
print("wrote stub SARIF (not SARIF-shaped)")
else:
print(f"SARIF ok: {len(doc.get('runs', []))} runs")
PY
- name: Upload IaC SARIF to GitHub code scanning
if: always()
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: iac-scan.sarif
category: agent-bom-iac
continue-on-error: true
- name: Upload scan artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: agent-bom-results
path: |
code-scan.json
skills-audit.json
fs-scan.json
iac-scan.json
iac-scan.sarif
if-no-files-found: ignore