Observatory-style grades
Starts at 100, applies penalties then bonuses, and maps to A+ … F buckets with a LOW/MEDIUM likelihood indicator.
npm package · MIT · Node ≥ 18
Fail CI when deployed URLs ship weak HTTP security headers.
Scans live URLs for HSTS, CSP, COOP, frame protection, cookies and more, then gives you a specific fix for every problem, with Nginx, Express, Vercel and Netlify hints. Mozilla HTTP Observatory-style grades from A+ to F. Zero runtime dependencies.
npm i -D header-sentinel
$ npx header-sentinel https://github.com --no-http-upgrade --no-preload-check https://github.com/ (HTTP 200) Grade B+ score 80/100 · MEDIUM risk ⚠ warn CSP style-src allows 'unsafe-inline' [csp-unsafe-inline] ...
Security headers drift. A CDN change, a new reverse proxy or a framework upgrade quietly drops HSTS or loosens your CSP, and nobody notices until an audit.
header-sentinel checks the headers your deployed site actually sends, grades them the way Mozilla HTTP Observatory does, and fails the build with a concrete fix, so regressions get caught in CI rather than in a pentest report.
Starts at 100, applies penalties then bonuses, and maps to A+ … F buckets with a LOW/MEDIUM likelihood indicator.
Each problem comes with an example header plus Nginx, Express, Vercel and Netlify hints.
Checks max-age ≥ 1 year, includeSubDomains, preload eligibility, and HTTP→HTTPS redirect chains.
Flags missing CSP, unsafe-inline / unsafe-eval, overly broad wildcards and missing directives.
Record accepted findings once, then only fail on new issues in PRs and nightly runs.
Load every URL from sitemap.xml with --sitemap, repeatable.
--json exposes score, grade and observatory tests; --sarif feeds GitHub code scanning.
Node ≥ 18, ESM and CommonJS, with generated TypeScript types.
# Ad-hoc scan
npx header-sentinel https://example.com# Record a baseline on main
npx header-sentinel https://example.com --baseline .header-baseline.json --update-baseline# Fail only on new issues
npx header-sentinel https://example.com --baseline .header-baseline.json --fail-on error# Scan a whole sitemap
npx header-sentinel --sitemap https://example.com/sitemap.xml --baseline .header-baseline.jsonname: Security headers
on:
deployment_status:
schedule: [{ cron: '0 6 * * 1' }]
workflow_dispatch:
permissions: { contents: read, security-events: write }
jobs:
headers:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: MrLouisWright/header-sentinel@v1
with:
urls: https://example.com https://example.com/login
fail-on: error
sarif: header-sentinel.sarif
- uses: github/codeql-action/upload-sarif@v3
if: always()
with: { sarif_file: header-sentinel.sarif }
| Flag | Description |
|---|---|
-c, --config <file> | JSON config (default: .headerguardrc.json / .headersentinelrc.json if present) |
--fail-on <level> | error | warn | none (default: error) |
--json | Print JSON results (includes observatory score/tests) |
--sarif [file] | Print SARIF 2.1.0 (or write to file) |
--sitemap <url> | Load URLs from sitemap.xml (repeatable) |
--baseline <file> | Only fail on findings not in baseline |
--update-baseline | Write current fingerprints to --baseline |
--no-http-upgrade | Skip HTTP→HTTPS redirect analysis |
--no-preload-check | Skip HSTS preload list / eligibility lookups |
-t, --timeout <ms> | Request timeout (default: 10000) |
-H, --header "K: V" | Extra request header (repeatable) |
--no-follow-redirects | Check the first response instead of the final one |
Full reference, config file format and API in the README.
Support this project
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