ADMIT. Set it as a required check and merges gate on it.
How it works
- A developer opens or updates a pull request
- GitHub delivers a webhook event; the signature is verified (HMAC-SHA256)
- The app creates a Check Run (“QWED Security”) on the PR
- The pipeline runs: evidence extraction → context classification → policy
- A Verification Context v1.0 is emitted: verdict (
VERIFIED/UNVERIFIABLE/BLOCKED), admission (ADMIT/DENY), and a SHA-256proof_refbinding the decision to the exact scan evidence and rule-set version - The check run concludes and the full Verification Context is published as a collapsible PR comment for audit
The admission contract — what a green check proves
When the QWED Security check passes and you have it configured as a required check, a mergeable PR proves:- Full scan — every file in the PR was scanned by the complete engine set. If the PR exceeds the 300-file cap, the scan is demoted to
UNVERIFIABLE (DENY)— a capped scan can never be ADMIT (fail-closed) - Zero new blocking findings — admission is computed from new findings only; a PR that introduces no new
BLOCK/WARNINGfindings getsVERIFIED (ADMIT) - Pre-existing debt never blocks — findings that already exist on the base branch are reported (and listed in the PR comment) but do not affect admission. QWED blocks only what the PR introduces
- Rule-set bound in proof — the rule-set version is part of the SHA-256
proof_ref, so the bound under which the verdict was computed is part of the proof - Fail-closed — unknown context, unparseable manifests, missing evidence, or infrastructure failure never produce a pass.
UNVERIFIABLEandBLOCKEDboth deny admission
What QWED Security catches
Math and logic verification (SymPy / Z3) is available through the QWED engine suite and the QWED GitHub Action; the GitHub App focuses on the security surface above.
Check run output
Every scan also posts the full Verification Context as a collapsible PR comment:
Cryptographic attestation
VERIFIED verdicts are signed (RS256) — attestation is the trust gate, not a cosmetic badge:
- The signed JWT is delivered inside the Verification Context at
context.proof.configuration.attestation_token - Third parties verify it against the app’s JWKS at
/.well-known/jwks.json(or the operator-configuredQWED_ATTESTATION_JWKS_URL): fetch the JWKS, select the key bykid, verify the RS256 signature, then check the proof binding in the VC - Rotated signing keys stay published for the token lifetime plus skew, so unexpired tokens remain verifiable across key rotation
- Operators can set
QWED_REQUIRE_ATTESTATION=trueto fail closed whenever no signing key is configured — an unsignedVERIFIEDis never admitted
The SDK-level ES256 attestation flow for the verification API is documented separately under Cryptographic attestations. The GitHub App uses the RS256 flow described here.
Configuration (.qwed.yml)
QWED Security works out of the box with zero configuration. Repositories can tune policy with a .qwed.yml, loaded from the base branch — never the PR head, so a PR cannot weaken its own scan:
diff_aware(defaulttrue) — admission gating considers new findings only; release-boundary findings always applytreat_unknown_as_block— unknown context resolves toBLOCK(fail-closed)- Suppressions — maintainer-controlled, with separator-aware
path=globs:*and?never cross/(path=tests/*stays one level deep),**spans directories (path=tests/**covers everything undertests/, and**/foo.pyalso matches a root-levelfoo.py), and the pattern must match the whole path. Malformed globs are rejected when the config loads - Inline suppression —
# qwed-ignoreor scoped# qwed-ignore: rule-idon the offending line
Operational limits
Privacy and security
- No code storage — files are analyzed in memory and discarded
- Webhook verification — HMAC-SHA256 signature validation on every event
- JWT authentication — short-lived installation tokens (10-minute expiry)
- Base-branch policy —
.qwed.ymlis read from the base branch, never the PR head - Fail-closed everywhere — unknown states deny admission; infrastructure failures never pass silently
- Suspended installations — token minting stops the moment a suspension webhook is processed, across all workers (and across instances when the shared backend is enabled)
Permissions
The app never writes to your code, branches, or settings.
Plans
Install from the GitHub Marketplace listing.
Self-hosting and multi-instance deployments
The hosted app runs the default configuration. Self-hosters should note:- Coordination state (dedup, in-flight claims, rate windows, revocations) is file-locked and shared by all workers of one instance by default
- For Cloud Run scale-out across instances, an optional Firestore backend shares that state across every worker and every instance; scan claims fail closed on any backend error
- See the self-hosting guide for deployment details
QWED Security app vs GitHub Action
The GitHub App provides automatic, zero-config PR security gating. The GitHub Action provides configurable verification within your CI/CD pipeline. They complement each other.
Support
- Contact Form: qwedai.com/contact
- Email: support@qwedai.com
- Issues: GitHub Issues