Add .github/workflows/gatekeep-pr.yml with uses: ./ and OPENROUTER_API_KEY from secrets. Forge-agnostic API helper for Gitea.
This commit is contained in:
commit
05f8fad38a
48 files changed
+2844
No files matched your search
@@ -0,0 +1,12 @@
|
||||
# Deploy slots (stub — later)
|
||||
|
||||
Gatekeep’s PR Action does **not** perform production rollback. Ops keeps two slots:
|
||||
|
||||
| Slot | Role |
|
||||
| --- | --- |
|
||||
| `current` / `active` | What players/users hit now |
|
||||
| `previous` | Last known-good artifact for one-command swap |
|
||||
|
||||
**v1 note only:** wire symlink or compose services outside this Action; record `previous_good_sha` on every deploy; PR template “How to revert” points operators here. Auto-rollback stays human-confirm by default except crash-loop burn-in (see Project rollback design).
|
||||
|
||||
Artifact retention for review/verify jobs uses `actions/upload-artifact` (`gatekeep-last-good-<run_id>`, 14 days) — that is **CI evidence**, not the production slot.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Dogfood — Gatekeep reviews Gatekeep
|
||||
|
||||
The Action repo itself runs Gatekeep on its own pull requests.
|
||||
|
||||
| Piece | Path / value |
|
||||
| --- | --- |
|
||||
| Live workflow | `.github/workflows/gatekeep-pr.yml` |
|
||||
| Action | `uses: ./` (repo-root `action.yml`) |
|
||||
| Secret | `OPENROUTER_API_KEY` → step `env` |
|
||||
| Trigger | `pull_request` (non-draft) + `workflow_dispatch` |
|
||||
|
||||
## How to see a review
|
||||
|
||||
1. Branch off `main`, make a tiny change, open a PR on https://git.potatolab.uk/layue13/gatekeep
|
||||
2. Wait for the **Gatekeep** workflow (same Actions runner pool as other `layue13` repos)
|
||||
3. Look for the summary comment `<!-- gatekeep-review -->` on the PR
|
||||
|
||||
Consumer sample workflows remain under top-level `workflows/` for copy-paste into *other* repos’ `.github/workflows/`.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Remote `uses:` — limitations & workarounds
|
||||
|
||||
Gatekeep is a **self-contained composite Action** (`action.yml` at repo root + `scripts/` + `defaults/`). Consumers should prefer:
|
||||
|
||||
```yaml
|
||||
uses: https://git.example.com/OWNER/gatekeep@v1
|
||||
# Project example:
|
||||
uses: https://git.potatolab.uk/layue13/gatekeep@main
|
||||
```
|
||||
|
||||
No copy of Action sources into the consumer repo is required. Optional `.github/gatekeep/` overrides still work via `config-dir`.
|
||||
|
||||
## What must be true
|
||||
|
||||
| Requirement | Notes |
|
||||
| --- | --- |
|
||||
| Runner can fetch the Action git repo | Network + credentials if the Action repo is private |
|
||||
| Runner can reach OpenRouter | `OPENROUTER_API_KEY` secret |
|
||||
| `GITHUB_TOKEN` permissions | `pull-requests: write`, `checks: write` (see sample workflow) |
|
||||
| Org / repo Actions policy | External Actions allowed |
|
||||
|
||||
## GitHub.com-hosted consumers + Gitea-hosted Action
|
||||
|
||||
**Honest status:** GitHub Actions’ first-class `uses: owner/repo@ref` syntax is for **github.com**. Full URL `uses: https://…@ref` is documented for public Actions, but **enterprise / org allowlists** often restrict non-`github.com` Action sources. Behavior can also differ by plan and policy version.
|
||||
|
||||
If `uses: https://git.potatolab.uk/layue13/gatekeep@main` fails on github.com runners with an allowlist / “not permitted” / fetch error:
|
||||
|
||||
### Workaround A — GitHub mirror (recommended)
|
||||
|
||||
1. Mirror `layue13/gatekeep` to a github.com repo you control (e.g. `your-org/gatekeep`).
|
||||
2. Point consumers at:
|
||||
```yaml
|
||||
uses: your-org/gatekeep@main
|
||||
# or: uses: your-org/gatekeep@v1
|
||||
```
|
||||
3. Keep the Gitea repo as source of truth; sync tags on release.
|
||||
|
||||
### Workaround B — Vendor checkout (still no Marketplace)
|
||||
|
||||
If remotes are fully blocked, checkout Gatekeep into the job and run the composite via local path:
|
||||
|
||||
```yaml
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: layue13/gatekeep # or mirror
|
||||
# For Gitea, use a custom remote + token:
|
||||
# (or actions/checkout with sparse / git mirror step)
|
||||
path: .gatekeep-action
|
||||
ref: main
|
||||
- uses: ./.gatekeep-action
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
openrouter-api-key: ${{ secrets.OPENROUTER_API_KEY }}
|
||||
```
|
||||
|
||||
For a pure Gitea URL when `actions/checkout` only speaks github.com, use an explicit `git clone` step with a deploy token, then `uses: ./.gatekeep-action`.
|
||||
|
||||
### Workaround C — Copy-in (appendix)
|
||||
|
||||
Copy Action files into `.github/actions/gatekeep` (see README appendix). Same runtime; more drift risk.
|
||||
|
||||
## Gitea / Forgejo Actions runners
|
||||
|
||||
If the **consumer** also runs on Gitea Actions (not GitHub-hosted), use that forge’s documented `uses:` / local action syntax. Paths remain `github.action_path`-relative so the same Action tree works once the runner can resolve it.
|
||||
|
||||
## Secrets never travel with the Action
|
||||
|
||||
Remote fetch does **not** include consumer secrets. Always set `OPENROUTER_API_KEY` (and any forge token for private Action clones) on the **consumer** repo/org.
|
||||
@@ -0,0 +1,23 @@
|
||||
# Gatekeep security seed checklist
|
||||
|
||||
Used in model prompts **and** the deterministic scanner (`action/scripts/security-scan.sh`).
|
||||
|
||||
| Item | Deterministic scan | Model review |
|
||||
| --- | --- | --- |
|
||||
| Hardcoded secrets/tokens | Added-line regex | Yes |
|
||||
| Prompt injection via repo files | Instruction-override phrases in diff | Yes |
|
||||
| Auth bypass | Path globs (`**/auth/**`) floor high | Yes |
|
||||
| Unauthorized API access | — | Yes |
|
||||
| Billing logic bypass | Path globs (`**/billing/**`, `**/payment/**`) | Yes |
|
||||
| CI workflow tampering | `.github/workflows/**` → high + scan hit | Yes |
|
||||
| Unsafe deserialization | pickle/yaml.load/unserialize patterns | Yes |
|
||||
| SQL/command injection | Concat / `shell=True` patterns | Yes |
|
||||
|
||||
## Blocking policy (default)
|
||||
|
||||
`policy.json` → `security_agreement`: **`require_agreement_unless_scan_hard_fail`**
|
||||
|
||||
- **Inline + block:** security / **Critical** findings where **≥2 models agree**, or any **deterministic scan hard-fail**.
|
||||
- **Summary only:** lone-model security flags (disputed) — do not inline; humans can still escalate.
|
||||
- Scan hard-fail always floors PR tier to **high** and fails check `gatekeep / security`.
|
||||
- Every finding (including security) still shows **severity + where + why it matters**.
|
||||
Reference in new issue
Block a user