GitHub Packages · MIT · Node ≥ 18

consent-warden

Check that your cookie banner actually behaves: nothing non-essential loads before opt-in, Reject is as easy as Accept, and consent can be withdrawn.

Check cookie-banner consent behaviour in your built site: trackers and embeds that load before opt-in, missing banner, Consent Mode defaults, missing or less prominent Reject, pre-ticked boxes, implied consent and no way to withdraw. GDPR/PECR. SARIF, allowlist with expiry, GitHub Action. Zero deps.

  1. 1 Point the @mrlouiswright scope at GitHub Packages in .npmrc

    @mrlouiswright:registry=https://npm.pkg.github.com
  2. 2 Install

    npm i -D @mrlouiswright/consent-warden
Installing from GitHub Packages needs a token

Published to GitHub Packages, not npmjs.com. GitHub Packages needs a GitHub token with read:packages to install, even for public packages: add //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} to .npmrc or run npm login --registry=https://npm.pkg.github.com.

~/project — zsh
$ npx consent-warden dist --base-url https://acme.exampleconsent-warden — https://acme.example3 page(s); 3 load trackers HIGH     index.html:2 gtag('consent','default') grants storage before consent on / [consent-mode-default-granted]         ↳ fix: Set ad_storage, ad_user_data, ad_personalization and analytics_storage to 'denied' by default and update them on opt-in.HIGH     index.html:3 Meta Pixel (script) loads on / before consent [consent-tracker-ungated]         ↳ fix: Block it until opt-in: <script type="text/plain" data-category="analytics"> (or your CMP's equivalent), or use Consent Mode with default denied.HIGH     index.html:3 Hotjar (script) loads on / before consent [consent-tracker-ungated]         ↳ fix: Block it until opt-in: <script type="text/plain" data-category="analytics"> (or your CMP's equivalent), or use Consent Mode with default denied.HIGH     index.html:6 Consent checkbox "marketing" is pre-ticked [consent-prechecked]
Sample output from the consent-warden README.

Why it exists

Most cookie-banner enforcement (ICO, CNIL, noyb complaints) is about behaviour, not cookie flags: the Meta pixel fires before anyone clicks, Consent Mode defaults to granted, Reject is a grey link hidden behind Settings, boxes are pre-ticked, and once dismissed there is no way back. consent-warden reads the built HTML and checks how trackers are loaded relative to the banner and how the banner itself is built, reporting each problem with the file, line, severity and a concrete fix.

CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies. Works on any static build output (Astro, Next.js “output: 'export'”, Eleventy, Hugo, Jekyll, Docusaurus, VitePress, plain HTML) and runs offline: point it at the folder your build writes. By Louis Wright.

Features

Loading before opt-in

tracking scripts, inline SDK snippets and pixels must be blocked until consent: type="text/plain" with a category (data-category, data-cookieconsent, data-cookiecategory, ...), a consent check in the snippet, or Google Consent Mode with defaults denied.

Consent Mode

gtag("consent","default",…) granting ad_storage/analytics_storage up front, or Google tags with no default at all.

Embeds

YouTube, Vimeo, Google Maps, Google Fonts and social/chat widgets that load before consent (use click-to-load or self-host).

Banner presence

pages that load trackers with no banner and no CMP (Cookiebot, OneTrust, Usercentrics, Klaro, CookieConsent, Complianz, iubenda, Osano, Termly, CookieYes are recognised).

Equal choice

Accept without Reject on the first layer, Reject as a link or with weaker styling than Accept, pre-ticked non-essential checkboxes, implied-consent wording ("by continuing to browse…").

Withdrawal

a persistent "Cookie settings" link or button outside the banner.

Usage

# Example

 npx consent-warden dist

# Example

 npx consent-warden dist --fail-on medium

# Example

 npx consent-warden public --essential plausible --allow-embeds

# Example

 npx consent-warden out --cmp-provides-withdraw --format sarif > consent.sarif

CI / GitHub Action

permissions:
  contents: read
  security-events: write   # only needed for the SARIF upload
jobs:
  consent-warden:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with: { persist-credentials: false }
      - run: npm ci && npm run build   # produce the static site first
      - uses: MrLouisWright/consent-warden@v1
        with:
          path: dist
          fail-on: high
          sarif: consent-warden.sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with: { sarif_file: consent-warden.sarif }

Options & flags

FlagDescription
Site
--base-url <url>Public URL of the site, e.g. https://example.com (default: inferred from canonical/og:url)
--include <globs>Only check these pages (file or URL path globs, comma-separated)
--exclude <globs>Skip these pages
--clean-urlsPages are served without .html (about.html -> /about)
Consent
--essential <vendors>Vendor ids treated as strictly necessary (payments, security and CMPs are by default)
--allow-embedsDo not report video/maps/fonts/social embeds that load before consent
--cmp-provides-withdrawYour CMP injects its own floating settings button
Common
-c, --config <file>JSON config (default: .consent-warden.json or "consentWarden" in package.json)
-f, --format <fmt>text (default) | json | sarif | markdown
--json <file>Also write a JSON report
--sarif <file>Also write SARIF 2.1.0
--markdown <file>Also write Markdown (e.g. for a job summary)
--fail-on <sev>critical | high | medium | low | info | none (default: high)
--list-rulesPrint rules and default severities
--no-fixesHide fix suggestions in text output
--no-colorDisable colours

Full reference, config file format and API in the README.

Support this project

Support open-source security tools

I build free, open-source tools that help developers ship safer websites. Every coffee helps keep them maintained, documented and free for everyone.

Buy me a coffee (opens Stripe in a new tab)

Secure checkout by Stripe

Portrait of Louis Wright

About the author

Louis Wright

Cyber security researcher and software engineer based in the UK.

More tools by Louis Wright

58 tools

Sentinels security scanners & CI gates · 20