GitHub Packages · MIT · Node ≥ 18

dsar-warden

Assemble Data Subject Access Request exports from many systems into one structured, checksummed bundle, and catch the mistakes before you send it.

  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/dsar-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 dsar-warden test/fixtures/bad/dsar.jsondsar-warden — test/fixtures/bad/dsar.json2 record(s) from 2/5 source(s), due 2026-02-05 HIGH     test/fixtures/bad/broken.json Source "logs": Unexpected end of JSON input [dsar-source-parse-error]HIGH     test/fixtures/bad/dsar.json Response was due 2026-02-05 (252 day(s) ago) [dsar-overdue]HIGH     test/fixtures/bad/dsar.json Duplicate source id "crm" [dsar-manifest-error]HIGH     test/fixtures/bad/missing.json Source "billing": test/fixtures/bad/missing.json not found [dsar-source-missing]MEDIUM   test/fixtures/bad/crm.csv Source "crm": no record has match field(s) email [dsar-match-field-missing]MEDIUM   test/fixtures/bad/dsar.json Requester identity is not marked verified [dsar-identity-unverified]
Sample output from the dsar-warden README.

Why it exists

Under GDPR Article 15 (and the UK GDPR) a person can ask for a copy of everything you hold about them, and you normally have one calendar month to answer. In practice that means exporting from the CRM, the order database, the support desk and the mailing tool, filtering each export down to one person, stripping password hashes and other people's details, and adding the purposes, recipients and retention for each. dsar-warden does that from a small dsar.json manifest: it reads CSV, TSV, JSON and JSONL exports, keeps only the subject's records, writes a machine-readable bundle with checksums, and reports anything that would make the response wrong or late.

CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies, runs offline. By Louis Wright.

Features

Sources

CSV/TSV (quotes, CRLF, BOM), JSON (array, or recordsPath into an object) and JSONL/NDJSON exports, paths relative to the manifest.

Matching

one or more identifiers (email, customer_id, phone, ...) mapped to fields per source, including nested paths (customer.id) and several fields (["to", "cc"]); case-insensitive, phone numbers normalised.

Cleaning

include to whitelist fields, exclude to drop them, redact to keep the key with [REDACTED]; password, token, hash, salt, OTP and session fields are always removed and reported.

Third-party data

emails and phone numbers in exported records that do not belong to the subject are flagged until redacted or marked thirdPartyReviewed.

Article 15 context

each source should state purpose, category, recipients and retention; these are carried into the bundle and SUMMARY.txt.

Deadline

due date is one calendar month from received (clamped at month end; extended: true adds two months, or set deadlineDays); overdue and due-soon requests are reported, plus unverified identity.

Bundle

--out dir writes bundle.json, sources/<id>.json, SUMMARY.txt and SHA256SUMS.

Usage

# Example

 npx dsar-warden requests/DSAR-2026-014 --out out/DSAR-2026-014

# Example

 npx dsar-warden dsar.json --subject email=jane@acme.io --subject customer_id=C123 -o bundle

# Example

 npx dsar-warden . --fail-on medium --format markdown

CI / GitHub Action

permissions:
  contents: read
  security-events: write   # only needed for the SARIF upload
jobs:
  dsar-warden:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with: { persist-credentials: false }
      - uses: MrLouisWright/dsar-warden@v1
        with:
          path: requests/DSAR-2026-014
          fail-on: high
          sarif: dsar-warden.sarif
      - uses: github/codeql-action/upload-sarif@v3
        if: always()
        with: { sarif_file: dsar-warden.sarif }

Options & flags

FlagDescription
Request
-s, --subject <k=v>Subject identifier, repeatable (e.g. email=jane@acme.io, customer_id=C123)
-o, --out <dir>Write the bundle: bundle.json, sources/*.json, SUMMARY.txt, SHA256SUMS
--warn-days <n>Warn when the response is due within n days (default 7)
Common
-c, --config <file>JSON config (default: .dsar-warden.json or "dsarWarden" 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