Open-source project
stephenlthorn/auto-identity-remove avatar
stephenlthorn/auto-identity-remove

auto-identity-remove: the README says 500 brokers, the manifest says 30

Automated data broker opt-out runner — removes your personal info from 30+ people-search sites on a monthly schedule

878 stars53 forksJavaScriptMIT

At a glance

What is it?
A Playwright runner that fills in data broker opt-out forms on a monthly schedule, pays CapSolver to clear CAPTCHAs, and tracks completed removals in state so they are not resubmitted. The headline count and the package description disagree by a factor of sixteen, and the Docker image tag has to match a pinned Playwright version that a test enforces.
Who is it for?
auto-identity-remove suits one person in one jurisdiction who has decided that broker listings are worth a monthly automated pass, who can supply a name plus state plus ZIP and a few aliases, and who is willing to either pay a small CAPTCHA-solving fee or handle those forms by hand each month. It does not suit anyone who wants a guaranteed result, since the tool's own design keeps a 90 day re-check window and hands stubborn sites back to a browser.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The headline says 500 sites and the package description says 30

The opening line claims removal of personal information from 500+ people-search sites and data broker databases. The package manifest says something else:

json
"description": "Automated data broker opt-out runner - removes your personal info from 30+ people-search and data broker sites on a monthly schedule",

The repository's own description field uses the same 30+ figure, so the README headline is the outlier rather than the typo. The gap matters operationally rather than cosmetically, because the first run visits every configured broker, fills a form and waits for a response, and a user who reads 500 and gets 30 will assume coverage they do not have, or the reverse. What the tool does per broker is a fixed seven-step pass: search the site for your name and state, find your specific listing where a profile URL is needed, fill and submit the opt-out form, solve CAPTCHAs through CapSolver, skip brokers already removed within 90 days, text you an iMessage summary, and open anything that still needs a human in your browser.

The image tag and the Playwright pin have to agree, and a test checks

The Dockerfile opens with a warning about its own first line. The image tag must match the `playwright` version pinned in package.json, because the image contains exactly one Chromium build, the one its own Playwright release expects, and a mismatched client fails at launch with the message `Executable doesn't exist at /ms-playwright/chromium-<rev>/chrome-linux/chrome`. The Dockerfile says not to bump one without the other, and that `test/docker-build-contract.test.js` enforces the match. The two values in question are:

code
FROM mcr.microsoft.com/playwright:v1.60.0-noble

and `"playwright": "1.60.0"` in the manifest. Note the pin style: Playwright is the only dependency with no caret, while axios is a caret range and nodemailer is optional. The reason for the exact pin is structural rather than cautious, since the base image and the client library are two halves of one Chromium download.

CAPTCHAs are cleared by a paid service or handed back to you

Some opt-out forms sit behind reCAPTCHA, and the tool's answer is to buy the solution rather than solve it. CapSolver is described as AI-powered at roughly $0.001 per solve, with $1 to $2 of credit described as enough for months of use, and setup asks for the key directly or takes it in `config.json` as a `capsolver.apiKey` value. The optional framing is repeated twice and is worth taking at face value: without a key, CAPTCHA-protected sites are flagged as manual and opened in your browser for completion, and a `--no-capsolver` flag skips them entirely rather than opening the browser at all. So the tool is fully functional without it, just less hands-off. This is also the one place where the automation depends on a paid third party whose relationship to the brokers being automated is not described anywhere in the documentation.

config.json is mounted read-write because the tool rewrites it

The compose file explains its own volume mode, which is the kind of comment that exists because someone got it wrong:

yaml
    volumes:
      # Not :ro - config.json is written back by --encrypt-config and by the
      # right-to-know pending-request bookkeeping.
      - ./config.json:/app/config.json
      - ./state.json:/app/state.json
      - ./logs:/app/logs

So the host file is not just read. Two features write to it: the encryption option, which protects the config at rest with AES-256-GCM and is opt-in through an `AIDR_PASSPHRASE` environment variable, and the bookkeeping for right-to-know requests still awaiting a reply. That makes the host copy of `config.json` the live state, not a snapshot, which matters because the file holds your name, city, state, ZIP, email, phone, past names and aliases, plus any one-time accounts created on sites that require a login. The documentation does say that personal information never leaves your machine and that both `config.json` and `state.json` are gitignored.

init: true is there because a leftover lock wedges the next run

The compose service sets `init: true` with a two-line justification: without it node runs as PID 1, so `docker stop` cannot reap the Chromium children and the state lock is left behind, wedging the next run. That single line documents a whole failure mode. The tool holds a lock across a run that drives a browser, and if the container is stopped uncleanly the lock survives, the next run refuses to start, and the remedy is not in the documentation but in the deletion of a file inside a bind mount. Two related tuning knobs sit next to it. `shm_size: 512mb` exists because Docker's default of 64MB is exhausted by Chromium renderers, with the note that the code also passes `--disable-dev-shm-usage` so a plain `docker run` still works, only slower. And `AIDR_LOW_MEMORY` exists for hosts with around 2GB of RAM, pointed at a Synology NAS and Raspberry Pi walkthrough.

The schedule is 9am local and the container clock is UTC

Setup registers a monthly job to run on the 1st at 9am, with the scheduler detected automatically across launchd, systemd, crontab and schtasks. Inside a container that local time is not local, and the compose file says so:

yaml
      # Container clocks are UTC. The scheduler and the report timestamps use
      # local time, so set this to your zone or a "1st of the month, 9am" run
      # lands at the wrong hour.
      - TZ=${TZ:-UTC}

The default is UTC, so an unset variable produces a job that fires at nine in the morning UTC rather than nine in the morning where you live. The documented `docker run` invocation handles this by passing `-e TZ="$(date +%Z)"` from the host, and the compose file passes it through with a default. The same local-time assumption reaches into reporting, since `aidr report` generates a monthly PDF and emails the summary and the timestamps in it are local as well. Two notification paths exist for the results: an iMessage to a phone number collected at setup, and email, which is why `nodemailer` sits in optionalDependencies rather than dependencies.

aidr is a wrapper and all seventeen subcommands reach watcher.js

The CLI table lists seventeen subcommands, from `setup` and `preview` through `serp-watch`, `breach`, `freeze`, `complaints`, `know`, `update-brokers` and `doctor`. The documentation is candid about what they are: `aidr` is a friendly wrapper around the underlying scripts, and every subcommand maps to the equivalent `node watcher.js --<flag>` invocation, with extra flags passed straight through, as in `aidr run --only Spokeo` or `aidr preview --skip BeenVerified`. The manifest confirms the shape, with `"main": "watcher.js"` and a single binary mapping `aidr` to `./bin/aidr.js`. Getting the command onto your PATH needs one extra step, and the reason is spelled out: run `npm link` or `npm i -g .`, because there is no `./node_modules/.bin/aidr`, since npm only creates `.bin` shims for dependencies and never for the package's own `bin`.

Editorial conclusion

auto-identity-remove suits one person in one jurisdiction who has decided that broker listings are worth a monthly automated pass, who can supply a name plus state plus ZIP and a few aliases, and who is willing to either pay a small CAPTCHA-solving fee or handle those forms by hand each month. It does not suit anyone who wants a guaranteed result, since the tool's own design keeps a 90 day re-check window and hands stubborn sites back to a browser. Check four things first. Check the broker count you believe, because the README says 500+ and the package description says 30+, and the difference decides how long a first run takes. Check your CAPTCHA route, since CapSolver is optional, costs roughly a tenth of a cent per solve, and its absence moves protected forms into a manual list you have to work through yourself. Check that your container has timezone set, because the scheduler registers for the 1st at 9am local while the container clock is UTC. And check that config.json is backed up before the first run, because it is mounted read-write and the encryption option rewrites it in place. The licence is MIT, there are no GitHub releases, and the default branch was pushed on 2026-09-18.

Frequently asked questions

How do I make myself unsearchable online?

This tool removes listings from data brokers rather than from search engines. It runs a monthly pass over the configured broker list, tracks what it has already removed with a 90 day re-check window, and adds a search-engine watch that alerts only when your name appears on a new domain.

Is there a way to remove your identity online?

Two legal routes are built in alongside the automated opt-outs. One subcommand sends CCPA and GDPR right-to-know requests, and another generates regulator complaints for brokers that pass the legal deadline, with pending-request bookkeeping held in config.json.

How can I remove my name from all search engines?

That is not what this does. It targets broker listings, and the closest it comes to search engines is a command that scans them for where your name still ranks and a watching mode that alerts only when a new domain appears.

Which data broker removal service is the best?

This project does not make that comparison. What it states about itself is that it runs for macOS, Linux and Windows, needs Node 18 or newer plus Playwright browsers, tracks completed opt-outs so they are not resubmitted, and pulls its broker list from the official California SB 362 and Vermont registries.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. stephenlthorn/auto-identity-remove on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stephenlthorn-auto-identity-remove.svg)](https://hysenlabs.com/projects/stephenlthorn-auto-identity-remove)