---
title: "QWED Security"
description: "A GitHub App that checks every pull request and release boundary with 20 deterministic engines, fails closed, and signs every verified verdict. Free for public repositories."
url: https://qwedai.com/platform/security
---

# 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.

[Install from Marketplace](https://github.com/marketplace/qwed-security) [Read the rule catalogue](https://docs.qwedai.com/advanced/qwed-security-rule-catalog)

Free for unlimited public repositories.

Every scan, in three stages

1.  **Evidence** 20 engines extract findings from code, configuration, lockfiles and release packages.
2.  **Context** Each finding is classified, so a test or a comment is not treated like running code.
3.  **Policy** A 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 credentials** An API key for OpenAI, GitHub, AWS or Stripe is committed along with the code.

-   **Unsafe commands** A script runs rm -rf / or pipes a download straight into a shell.

-   **Weak build settings** A 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

1.  **Leaked credentials** secret\_scan The pull request check fails.

    BLOCKED · DENY
2.  **Unsafe commands** shell\_safety The pull request check fails.

    BLOCKED · DENY
3.  **Weak build settings** docker\_scan, ci\_scan Reported 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.

.qwed.yml

```
ignore_patterns_in_tests: true
treat_unknown_as_block: true
diff_aware: true
allowed_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

1.  Open QWED Security on [GitHub Marketplace](https://github.com/marketplace/qwed-security) and choose the free Basic plan.
2.  Install it on your account or organisation, for all repositories or only some.
3.  Open a pull request. The check run, the comment and the code scanning results appear on their own.

[Install from Marketplace](https://github.com/marketplace/qwed-security) [Rule catalogue](https://docs.qwedai.com/advanced/qwed-security-rule-catalog)

### 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](https://qwedai.com/terms) and the [privacy policy](https://qwedai.com/privacy).
