Skip to content

Commit 9b6619c

Browse files
Add static defensive validation workflow (#2)
1 parent 60cba34 commit 9b6619c

1 file changed

Lines changed: 134 additions & 0 deletions

File tree

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: Static Defensive Validation
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
push:
8+
branches:
9+
- main
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
static-validation:
17+
name: Static Defensive Validation
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: "22"
28+
29+
- name: Verify required repository files
30+
shell: bash
31+
run: |
32+
set -euo pipefail
33+
34+
required_files=(
35+
"index.html"
36+
"app.js"
37+
"styles.css"
38+
"AGENTS.md"
39+
"README.md"
40+
"SECURITY.md"
41+
"docs/evidence/01_repository_inventory.md"
42+
"docs/evidence/02_security_triage.md"
43+
"docs/remediation/human_approval_checklist.md"
44+
"docs/remediation/remediation_plan.md"
45+
"docs/threat-model/threat_model.md"
46+
"docs/validation/validation_report.md"
47+
"docs/daybreak-application/daybreak_candidate_summary.md"
48+
)
49+
50+
for file in "${required_files[@]}"; do
51+
if [[ ! -f "$file" ]]; then
52+
echo "::error::Required file missing: $file"
53+
exit 1
54+
fi
55+
done
56+
57+
echo "Required file inventory passed."
58+
59+
- name: Check JavaScript syntax
60+
shell: bash
61+
run: |
62+
set -euo pipefail
63+
node --check app.js
64+
echo "JavaScript syntax check passed."
65+
66+
- name: Block unsafe rendering and dynamic execution patterns
67+
shell: bash
68+
run: |
69+
set -euo pipefail
70+
71+
pattern='innerHTML|outerHTML|insertAdjacentHTML|eval\(|new Function'
72+
73+
if grep -RInE "$pattern" app.js index.html; then
74+
echo "::error::Unsafe rendering or dynamic execution pattern found in runtime files."
75+
exit 1
76+
fi
77+
78+
echo "Runtime unsafe-pattern scan passed."
79+
80+
- name: Scan runtime files for obvious secret patterns
81+
shell: bash
82+
run: |
83+
set -euo pipefail
84+
85+
pattern='SECRET|TOKEN|API[_-]?KEY|PASSWORD|PRIVATE KEY|OPENAI_API_KEY|client_secret|sk-[A-Za-z0-9]|ghp_|github_pat_'
86+
87+
if grep -RInE "$pattern" app.js index.html styles.css; then
88+
echo "::error::Potential secret pattern found in runtime files."
89+
exit 1
90+
fi
91+
92+
echo "Runtime secret-pattern scan passed."
93+
94+
- name: Block local state and generated archive artifacts
95+
shell: bash
96+
run: |
97+
set -euo pipefail
98+
99+
forbidden_matches="$({
100+
find . -path './.git' -prune -o -path '*/.netlify/*' -print
101+
find . -path './.git' -prune -o -name '*.zip' -print
102+
find . -path './.git' -prune -o -name '*.tar' -print
103+
find . -path './.git' -prune -o -name '*.tar.gz' -print
104+
find . -path './.git' -prune -o -name '*.7z' -print
105+
find . -path './.git' -prune -o -name '*.log' -print
106+
} | sort -u)"
107+
108+
if [[ -n "$forbidden_matches" ]]; then
109+
echo "::error::Forbidden local state, generated archive, or log artifact found."
110+
echo "$forbidden_matches"
111+
exit 1
112+
fi
113+
114+
echo "Repository hygiene scan passed."
115+
116+
- name: Confirm bounded public claims
117+
shell: bash
118+
run: |
119+
set -euo pipefail
120+
121+
required_claims=(
122+
"public sanitized lab"
123+
"No affiliation with OpenAI is claimed"
124+
"not a production vulnerability scan"
125+
)
126+
127+
for claim in "${required_claims[@]}"; do
128+
if ! grep -RInF "$claim" README.md docs SECURITY.md >/dev/null; then
129+
echo "::error::Required bounded-claim language missing: $claim"
130+
exit 1
131+
fi
132+
done
133+
134+
echo "Bounded public-claims check passed."

0 commit comments

Comments
 (0)