Add scheduled security scan workflow

This commit is contained in:
MrSphay
2026-05-03 22:01:41 +02:00
parent a218e338bd
commit 6308417945
8 changed files with 241 additions and 1 deletions

View File

@@ -60,6 +60,7 @@ Use only the files that fit the project. For a tiny script repo, `AGENTS.md`, `R
| `files/AGENTS.md` | `AGENTS.md` |
| `files/project.md` | `.codex/project.md` |
| `files/build-gitea.yml` | `.gitea/workflows/build.yml` |
| `files/security-scan-gitea.yml` | `.gitea/workflows/security-scan.yml` |
| `files/release-checklist.md` | `docs/release-checklist.md` |
| `files/security-review.md` | `docs/security-review.md` |
| `files/blueprint.md` | `blueprint.md` |
@@ -123,6 +124,7 @@ When applying this kit, an agent should:
- keep `AGENTS.md` and `.codex/project.md` aligned,
- update `README.md` whenever README blueprint files change,
- update security and release docs when release behavior changes,
- add or preserve scheduled security automation for releasable projects,
- update `docs/agent-handoff.md` when work is interrupted, risky, or multi-session,
- run `git diff --check` before finishing,
- run the cheapest reliable verification command,
@@ -130,6 +132,21 @@ When applying this kit, an agent should:
<p align="center"><img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="-----------------------------------------------------" width="100%"></p>
## Scheduled Security Automation
`files/security-scan-gitea.yml` provides an optional weekly Gitea workflow for releasable projects.
It checks:
- stack-specific dependency vulnerabilities,
- suspicious code patterns,
- committed secrets or local config files,
- AI instruction-injection indicators.
The workflow is intentionally conservative. If it fails, an agent should inspect the matches and decide whether they are real risks, documentation examples, or test fixtures. Do not silence the workflow without documenting why.
<p align="center"><img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="-----------------------------------------------------" width="100%"></p>
## Gitea API Token
When working with private repositories on `git.wilkensxl.de`, Codex agents may find a local `GITEA_TOKEN` environment variable on the machine.

View File

@@ -9,6 +9,7 @@ Read manifest.json first.
Use its copyMap for file destinations.
Use new-repository.md or existing-project.md as the task workflow.
Use matching profiles/*.md guidance after detecting the stack.
For releasable projects, add or preserve scheduled security automation.
Check git status before editing.
Preserve unrelated user changes.
Replace all applicable placeholders and remove non-applicable placeholder sections.
@@ -74,6 +75,10 @@ Does the project have CI?
yes -> patch existing workflow
no -> add .gitea/workflows/build.yml only when commands are known
Is the project releasable or does it process user/secrets/config data?
yes -> add .gitea/workflows/security-scan.yml or preserve equivalent scheduled security automation
no -> document why scheduled security automation is not needed
Are commands unknown?
yes -> document PENDING in .codex/project.md
no -> wire commands into AGENTS.md and CI
@@ -123,6 +128,7 @@ docs/release-checklist.md
docs/security-review.md
docs/agent-handoff.md
.gitea/workflows/build.yml
.gitea/workflows/security-scan.yml
```
For README-generator projects:

View File

@@ -120,6 +120,8 @@ If CI does not exist:
- remove stack-specific steps that do not apply,
- keep publishing disabled until credentials and artifact names are known.
For releasable projects, add `.gitea/workflows/security-scan.yml` unless the repository already has equivalent scheduled security automation. If an existing scanner is present, document it in `.codex/project.md` instead of duplicating it.
### 6. Security Review
Fill `docs/security-review.md` with known facts.

View File

@@ -20,6 +20,7 @@ PROJECT_NAME: PROJECT_DESCRIPTION
- After pushing commits that trigger a Gitea workflow, poll the workflow run until it succeeds. If it fails or is cancelled, inspect the failing job/logs, fix the issue when in scope, push again, and repeat the workflow check loop. Fixing and pushing a workflow failure is not a stopping point.
- When the project uses `blueprint.md` and `blueprint.json` for README generation, keep the rainbow `{{ template:section-line }}` divider between major README sections. Do not replace it with plain `---` unless the target renderer cannot display inline images.
- If README blueprint files are changed, regenerate or update `README.md` in the same change and verify the generated output renders reasonably.
- For releasable projects, add or preserve `.gitea/workflows/security-scan.yml` using `files/security-scan-gitea.yml` unless the repository already has equivalent scheduled security automation.
## Commands
@@ -54,6 +55,7 @@ ARTIFACT_NAME
- Review `docs/security-review.md` before release work.
- Fill `docs/security-review.md` with actual checked commands and results when performing release-readiness work.
- Review scheduled security workflow failures before changing code. Treat matches as leads: they may be true positives, documentation examples, or test fixtures.
- Treat generated credentials and config files as sensitive.
- Keep external network calls documented.
- Prefer local processing for user data.

View File

@@ -0,0 +1,174 @@
name: Scheduled Security Scan
on:
schedule:
- cron: "17 3 * * 1"
workflow_dispatch:
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Detect project stack
id: detect
shell: bash
run: |
stacks=""
[ -f package.json ] && stacks="${stacks} node"
{ [ -f pyproject.toml ] || [ -f requirements.txt ]; } && stacks="${stacks} python"
[ -f Cargo.toml ] && stacks="${stacks} rust"
[ -f go.mod ] && stacks="${stacks} go"
{ [ -f Dockerfile ] || [ -f compose.yml ] || [ -f docker-compose.yml ]; } && stacks="${stacks} docker"
echo "stacks=${stacks:-generic}" >> "$GITHUB_OUTPUT"
echo "Detected stacks:${stacks:- generic}"
- name: Node production dependency audit
if: contains(steps.detect.outputs.stacks, 'node')
run: npm audit --omit=dev --audit-level=high
- name: Python dependency audit
if: contains(steps.detect.outputs.stacks, 'python')
shell: bash
run: |
python -m pip install --upgrade pip pip-audit
if [ -f requirements.txt ]; then
pip-audit -r requirements.txt
else
pip-audit
fi
- name: Rust dependency audit
if: contains(steps.detect.outputs.stacks, 'rust')
shell: bash
run: |
cargo install cargo-audit --locked
cargo audit
- name: Go vulnerability scan
if: contains(steps.detect.outputs.stacks, 'go')
shell: bash
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
- name: Suspicious code pattern scan
shell: bash
run: |
grep_excludes=(
--exclude-dir=.git
--exclude-dir=node_modules
--exclude-dir=dist
--exclude-dir=build
--exclude-dir=release
--exclude=security-scan.yml
)
patterns=(
'eval\s*\('
'new Function\s*\('
'dangerouslySetInnerHTML'
'innerHTML\s*='
'child_process'
'exec\s*\('
'spawn\s*\('
'shell\.openExternal'
'nodeIntegration:\s*true'
'webSecurity:\s*false'
'allowRunningInsecureContent:\s*true'
'curl .*sh'
'wget .*sh'
)
found=0
for pattern in "${patterns[@]}"; do
if grep -RInE "${grep_excludes[@]}" "$pattern" .; then
found=1
fi
done
if [ "$found" -eq 1 ]; then
echo "Suspicious code patterns were found. Review the matches above."
exit 1
fi
- name: Secret and config leak scan
shell: bash
run: |
grep_excludes=(
--exclude-dir=.git
--exclude-dir=node_modules
--exclude-dir=dist
--exclude-dir=build
--exclude-dir=release
--exclude=security-scan.yml
)
patterns=(
'BEGIN (RSA |EC |OPENSSH |)PRIVATE KEY'
'AKIA[0-9A-Z]{16}'
'xox[baprs]-[0-9A-Za-z-]+'
'gh[pousr]_[0-9A-Za-z_]+'
'sk-[A-Za-z0-9]{20,}'
'api[_-]?key\s*=\s*["'\'']?[A-Za-z0-9_\-]{20,}'
'token\s*=\s*["'\'']?[A-Za-z0-9_\-]{20,}'
'password\s*=\s*["'\'']?[^[:space:]]{8,}'
)
found=0
for pattern in "${patterns[@]}"; do
if grep -RInE "${grep_excludes[@]}" "$pattern" .; then
found=1
fi
done
if find . -path ./.git -prune -o \( -name ".env" -o -name ".env.*" \) -not -name ".env.example" -print | grep .; then
echo "Committed environment files were found."
found=1
fi
if [ "$found" -eq 1 ]; then
echo "Potential secret or config leak detected. Review the matches above."
exit 1
fi
- name: AI instruction injection scan
shell: bash
run: |
grep_excludes=(
--exclude-dir=.git
--exclude-dir=node_modules
--exclude-dir=dist
--exclude-dir=build
--exclude-dir=release
--exclude=security-scan.yml
)
patterns=(
'ignore (all )?(previous|above) instructions'
'system prompt'
'developer message'
'reveal your instructions'
'exfiltrate'
'send.*token'
'send.*secret'
'disable.*safety'
'jailbreak'
'prompt injection'
)
found=0
for pattern in "${patterns[@]}"; do
if grep -RInEi "${grep_excludes[@]}" "$pattern" .; then
found=1
fi
done
if [ "$found" -eq 1 ]; then
echo "Potential AI instruction-injection text found. Review whether this is documentation, test data, or malicious content."
exit 1
fi

View File

@@ -16,6 +16,17 @@
"Run the cheapest reliable verification command or document why it could not run.",
"After pushing workflow-triggering commits, poll Gitea workflow runs until success or a concrete blocker."
],
"securityAutomation": {
"workflow": "files/security-scan-gitea.yml",
"target": ".gitea/workflows/security-scan.yml",
"schedule": "weekly",
"checks": [
"stack-specific dependency audit",
"suspicious code pattern scan",
"secret and config leak scan",
"AI instruction injection scan"
]
},
"readmeDivider": {
"templateName": "section-line",
"source": "https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png",
@@ -92,6 +103,11 @@
"source": "files/build-gitea.yml",
"target": ".gitea/workflows/build.yml",
"required": false
},
{
"source": "files/security-scan-gitea.yml",
"target": ".gitea/workflows/security-scan.yml",
"required": false
}
],
"placeholders": [

View File

@@ -34,6 +34,27 @@
}
}
},
"securityAutomation": {
"type": "object",
"required": ["workflow", "target", "schedule", "checks"],
"properties": {
"workflow": {
"type": "string"
},
"target": {
"type": "string"
},
"schedule": {
"type": "string"
},
"checks": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"workflows": {
"type": "object",
"required": ["newRepository", "existingProject", "quickstart"],
@@ -90,4 +111,3 @@
}
}
}

View File

@@ -50,6 +50,7 @@ files/release-notes.md -> docs/release-notes.md
files/blueprint.md -> blueprint.md
files/blueprint.json -> blueprint.json
files/build-gitea.yml -> .gitea/workflows/build.yml
files/security-scan-gitea.yml -> .gitea/workflows/security-scan.yml
```
Skip `build-gitea.yml` when the project has no CI target yet. Skip README blueprint files when the project should keep a very small manual README.
@@ -156,6 +157,8 @@ upload artifacts
Only publish artifacts to a package registry when the artifact names and credentials are known.
For releasable projects, config tools, apps, or repositories that process user data, secrets, or deployment files, also add `.gitea/workflows/security-scan.yml`. Keep the scheduled workflow conservative and review false positives before silencing checks.
### 7. Finish
Before final response: