A GitHub Actions supply-chain analyser. Deterministic rules find the problems; an optional AI layer explains them and provably cannot invent them.
Built with .NET 10, React and TypeScript, a read-only GitHub App, and the OpenAI API.
Most security tools that use a language model let the model decide what is vulnerable. This one does the opposite, and enforces it:
- Deterministic rules identify findings and severity. They are the only source of truth.
- The model's response is schema-constrained, and the rule identifiers it returns must match the deterministic set exactly. A reply that invents a finding, drops one, or renames a rule is rejected and replaced with a deterministic fallback.
- Proposed fixes are re-analysed before being shown as valid. A patch that introduces a finding is refused.
- GitHub access is read-only, restricted by the App's own permissions and again by an allowlist the application checks independently.
The interesting part is not the prose the model returns — the rules already carry a description and a recommendation, and the fallback produces comparable text with no model call. It is the enforcement around it. That constraint is what makes live AI defensible in a security tool at all.
Eleven rules covering pinning, permissions, timeouts, privileged triggers, script injection, credential persistence, untrusted checkout, secret forwarding, self-hosted runners and artifact poisoning.
| GHA001 unpinned action | GHA005 script injection | GHA009 undeclared permissions |
| GHA002 excessive permissions | GHA006 persisted credentials | GHA010 self-hosted runner |
| GHA003 missing timeout | GHA007 untrusted checkout | GHA011 artifact poisoning |
GHA004 pull_request_target |
GHA008 inherited secrets |
Full descriptions in docs/architecture/rules.md.
git clone https://github.com/bgard68/DevSecOpsSentinel.git
cd DevSecOpsSentinel
.\scripts\setup-local.ps1
.\scripts\start-local.ps1Open http://localhost:5173, pick a scenario, analyse it. No credentials required — GitHub is off by default and OpenAI defaults to Mock.
Full setup, including the optional integrations, in docs/getting-started.md.
Select Script injection, tick Include AI explanation, analyse.
One Critical finding. The model explains it and supplies the env: binding that
fixes it — a remediation the deterministic engine deliberately will not apply
itself.
Then select the safe workflow.
Zero findings, and the model declines to invent any. That is the claim the whole design exists to support.
| Getting started | Prerequisites, running it, secrets |
| Architecture | Layers and trust boundaries |
| Program flow | What happens on a request |
| Detection rules | All eleven, and how to add one |
| Engineering log | Defects found after "complete", and what prevents them now |
| CI/CD | Four workflows, path-selective builds |
| Scripts | Every script and why it exists |
| Full index | Everything else |
- .NET 10 minimal APIs, layered so dependencies point inward
- React 19 + TypeScript 5.9, Vite
- YamlDotNet for document structure, with a line model retained for content inside block scalars and for line-indexed patching
- 117 .NET tests, 4 frontend tests, and a 25-check smoke suite that drives a real server over HTTP
- CodeQL, Gitleaks, dependency review, Dependabot, secret scanning with push protection, and SHA-pinned actions enforced by policy
- Path-selective CI: a frontend change does not build the .NET solution, and a change spanning both still builds both, in one pipeline
The project passes its own analyser. Its workflows are SHA-pinned, least-privilege, timeout-bounded, and free of the injection pattern GHA005 reports.
It creates no branches, commits, pull requests or merges. It does not scan on a schedule. It stores no history. Each would need a separate threat model, stronger authentication, and new GitHub permissions — so each is absent rather than half-built.
docs/engineering-log.md records eleven defects found
after this project was first considered finished — including findings that
never rendered in the interface, an exported patch git apply refused, a SARIF
document no consumer would accept, and a protection gate that passed because it
had nothing to check.
Each entry covers how it surfaced and what now prevents it. The defects are more instructive than the features.
MIT. See LICENSE.


