Skip to content

Commit 783424b

Browse files
committed
Finished P1
1 parent 6cfe8be commit 783424b

3 files changed

Lines changed: 61 additions & 7 deletions

File tree

.github/workflows/security-pipeline.yml

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
- main
99

1010
jobs:
11-
security-gates:
11+
security-core-gates:
1212
runs-on: ubuntu-latest
1313

1414
steps:
@@ -21,14 +21,14 @@ jobs:
2121
- name: Install dependencies
2222
run: docker exec core-php-1 composer install --no-interaction --prefer-dist
2323

24-
- name: Run security contract tests
24+
- name: Run must-pass security tests
2525
run: |
2626
docker exec -e XDEBUG_MODE=coverage core-php-1 php vendor/bin/phpunit --colors=never --do-not-fail-on-risky --filter '/^.*AuthApiTest::testResolveApiTokenPrecedenceHeaderCookieAndQuery$/'
2727
docker exec -e XDEBUG_MODE=coverage core-php-1 php vendor/bin/phpunit --colors=never --do-not-fail-on-risky --filter '/^.*AuthApiTest::testResolveApiTokenRejectsMalformedHeaderTokenAndFallsBackToCookie$/'
2828
docker exec -e XDEBUG_MODE=coverage core-php-1 php vendor/bin/phpunit --colors=never --do-not-fail-on-risky --filter '/^.*RequestResponseSecurityContractTest::testCookiePayloadMatrixAndSecurityInterplay$/'
2929
docker exec -e XDEBUG_MODE=coverage core-php-1 php vendor/bin/phpunit --colors=never --do-not-fail-on-risky --filter '/^.*RequestResponseSecurityContractTest::testCheckCorsSetsHeadersForAllowedOriginOnGet$/'
3030
31-
- name: Run composer audit
31+
- name: Run dependency audit (SCA)
3232
run: docker exec core-php-1 composer audit --no-interaction
3333

3434
- name: Enforce quality gate
@@ -39,4 +39,51 @@ jobs:
3939
uses: actions/upload-artifact@v4
4040
with:
4141
name: security-quality-gate
42-
path: doc/security/quality-gate.json
42+
path: security/reports/quality-gate.json
43+
44+
security-static-analysis:
45+
runs-on: ubuntu-latest
46+
47+
steps:
48+
- name: Checkout
49+
uses: actions/checkout@v4
50+
51+
- name: Run Semgrep (SAST)
52+
uses: returntocorp/semgrep-action@v1
53+
with:
54+
config: p/owasp-top-ten
55+
generateSarif: "1"
56+
57+
- name: Upload Semgrep SARIF
58+
if: always()
59+
uses: github/codeql-action/upload-sarif@v3
60+
with:
61+
sarif_file: semgrep.sarif
62+
63+
- name: Run Gitleaks (secret scanning)
64+
uses: gitleaks/gitleaks-action@v2
65+
env:
66+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67+
GITLEAKS_CONFIG: .gitleaks.toml
68+
69+
- name: Upload Gitleaks report
70+
if: always()
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: security-gitleaks
74+
path: results.sarif
75+
if-no-files-found: ignore
76+
77+
- name: Generate SBOM (CycloneDX)
78+
uses: anchore/sbom-action@v0
79+
with:
80+
path: .
81+
format: cyclonedx-json
82+
output-file: security/reports/sbom.cyclonedx.json
83+
84+
- name: Upload SBOM
85+
if: always()
86+
uses: actions/upload-artifact@v4
87+
with:
88+
name: security-sbom
89+
path: security/reports/sbom.cyclonedx.json

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,7 @@ doc/security/**/quality-gate.json
4444
doc/security/**/*-report.json
4545
doc/security/**/security-testing-*.xml
4646
doc/security/**/security-testing-*.sarif
47+
48+
# CI runtime security artifacts
49+
security/reports/*
50+
!security/reports/.gitkeep

scripts/security/quality_gate.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ function runTests(array $tests): array
104104
return $results;
105105
}
106106

107-
$controlMatrixPath = 'doc/security/contracts/control-matrix.yaml';
108-
$findingsPath = 'doc/security/contracts/findings.json';
109-
$outputPath = 'doc/security/quality-gate.json';
107+
$controlMatrixPath = getenv('PSFS_SECURITY_CONTROL_MATRIX') ?: 'security/contracts/control-matrix.yaml';
108+
$findingsPath = getenv('PSFS_SECURITY_FINDINGS') ?: 'security/contracts/findings.json';
109+
$outputPath = getenv('PSFS_SECURITY_QUALITY_GATE_REPORT') ?: 'security/reports/quality-gate.json';
110110

111111
$mustPassTests = parseMustPassTests($controlMatrixPath);
112112
$findings = loadFindings($findingsPath);
@@ -129,6 +129,9 @@ function runTests(array $tests): array
129129
'tests' => $testResults,
130130
];
131131

132+
if (!is_dir(dirname($outputPath))) {
133+
mkdir(dirname($outputPath), 0775, true);
134+
}
132135
file_put_contents($outputPath, json_encode($report, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
133136
out("[QUALITY_GATE] status={$status} report={$outputPath}");
134137

0 commit comments

Comments
 (0)