Check every pull request before it merges.
A GitHub App built on QWED. It runs 20 deterministic engines on every pull request and release boundary, fails closed on anything it cannot decide, and keeps models out of the verdict.
Free for unlimited public repositories.
Every scan, in three stages
- Evidence20 engines extract findings from code, configuration, lockfiles and release packages.
- ContextEach finding is classified, so a test or a comment is not treated like running code.
- PolicyA deterministic policy decides BLOCK, WARN or INFO, and fails closed when context is unclear.
Mistakes it is built to catch
Nobody checked any of it
Without QWED Security
-
Leaked credentialsAn API key for OpenAI, GitHub, AWS or Stripe is committed along with the code.
-
Unsafe commandsA script runs rm -rf / or pipes a download straight into a shell.
-
Weak build settingsA Docker image runs as root or uses :latest, or a CI workflow allows script injection.
Each pull request checked before it merges
With QWED Security
- Leaked credentialssecret_scanThe pull request check fails.BLOCKED · DENY
- Unsafe commandsshell_safetyThe pull request check fails.BLOCKED · DENY
- Weak build settingsdocker_scan, ci_scanReported as findings on the pull request.
A verified verdict is signed, with a record of why.
QWED Security returns the check; your branch protection decides whether a failing check blocks the merge.
20 engines, one rule set
The engines run against a versioned rule set, and the version is bound into each result. A clean scan means verified against the QWED rule set, never “proven secure”.
- pattern_scan
Dangerous execution primitives and security patterns
- python_ast
eval, exec, subprocess and unsafe deserialisation in Python
- python_deep_ast
Deeper Python patterns the basic scan misses
- taint_analysis
Untrusted input flowing to a dangerous sink within a file
- cross_file_taint
A source in one file reaching a sink in another
- js_patterns
eval, XSS, prototype pollution and new Function in JavaScript and TypeScript
- go_patterns
os/exec, unsafe, SQL building, skipped TLS checks and weak crypto in Go
- rust_patterns
unsafe, Command, transmute, SQL building and weak crypto in Rust
- secret_scan
Provider-shaped credentials for OpenAI, GitHub, AWS, Stripe and more
- entropy_scan
High-entropy credentials that keyword rules miss
- codeguard
Obfuscation such as base64 payloads and tampered builtins
- shell_safety
rm -rf /, pipe-to-shell, setuid and raw disk writes
- docker_scan
Root user, :latest tags, remote ADD and multi-stage COPY
- ci_scan
Script injection, pull_request_target and permission escalation in workflows
- lockfile_scan
Missing hashes, http:// sources and unknown registries in lockfiles
- dependency_scan
Unpinned dependencies, non-registry sources and rogue index URLs
- release_boundary
What actually ships in npm, PyPI and Docker artifacts
- verification_integrity
Trust-boundary anti-patterns such as token leaks and disabled guards
- policy_config
Validation of the repository’s .qwed.yml policy
- consensus
Cross-engine corroboration with reliability tiers
Context before policy
A hard-coded key in a test fixture is not the same risk as one in production code. Every finding is placed in one of eight contexts before any rule decides, and anything that cannot be placed fails closed.
- Runtime code
- Test code
- Demo code
- Config
- CI config
- Documentation
- Comment
- String literal
- BLOCK
Must fix. A security boundary is violated.
- WARN
Review recommended. An advisory risk.
- INFO
Informational, or suppressed by policy.
- UNVERIFIABLE
Could not be proven. Fails closed and is never treated as a pass.
Gate on what the pull request introduces
The whole codebase is scanned, but a pull request is held to the lines it changes. Pre-existing findings stay visible without blocking unrelated work.
Policy lives in an optional .qwed.yml, always read from the base branch, so a pull request cannot weaken its own scan. Suppressions carry a reason and can be scoped to paths.
ignore_patterns_in_tests: truetreat_unknown_as_block: truediff_aware: trueallowed_test_patterns: []suppressions: - pattern=some-rule-id reason=false-positive path=src/legacy/*A verdict anyone can check
Results use the same three-layer DiagnosticResult as the rest of QWED. A verified verdict is signed, so a third party can check it from the pull request comment alone.
-
Three layers
A safe summary for agents, structured evidence for developers, and a proof_ref that binds the verdict to the exact scan evidence.
-
Signed when verified
Verified verdicts carry an RS256-signed attestation inside the Verification Context, with a dedicated key that is never the app’s own.
-
Checkable by anyone
Fetch the public JWKS, verify the signature, issuer, audience and expiry, and compare the proof hash with the evidence.
Results where your team already works
-
GitHub Checks
A check run with line annotations. It passes only when admission is granted.
-
Pull request comment
One sticky comment with the verdict and the Verification Context.
-
Code scanning
Findings uploaded as SARIF to GitHub code scanning.
Install in a minute
- Open QWED Security on GitHub Marketplace and choose the free Basic plan.
- Install it on your account or organisation, for all repositories or only some.
- Open a pull request. The check run, the comment and the code scanning results appear on their own.
Questions
How is this different from other code scanners?
Before any rule decides, every finding is classified by where it lives: runtime code, tests, documentation, configuration or a string literal. Inert code is not treated as executable risk, release artifacts are checked for what actually ships, and every verdict is bound to its evidence by a proof_ref.
Will it block pull requests over old code?
No. It scans the whole codebase but gates only on findings the pull request introduces. Findings on untouched lines are marked pre-existing and stay visible as advisory. Release-boundary findings always apply.
Does it use an LLM?
No model is in the verdict path. Findings come from AST parsing, taint tracking, pattern and entropy rules, and a deterministic policy engine.
Which languages and files are covered?
Python, JavaScript and TypeScript, Go and Rust source; Dockerfiles; GitHub Actions workflows; npm and PyPI lockfiles and dependencies; and npm, PyPI and Docker release artifacts.
What does it cost?
The Basic plan on GitHub Marketplace is free and covers unlimited public repositories.
Using the app is covered by the terms and the privacy policy.