{"id":50769897,"url":"https://github.com/danieljustus/symaira-eraseme","last_synced_at":"2026-06-11T17:03:12.689Z","repository":{"id":359342677,"uuid":"1243498814","full_name":"danieljustus/symaira-eraseme","owner":"danieljustus","description":"Automated data broker removal tool ⌫ close your accounts, erase your data.","archived":false,"fork":false,"pushed_at":"2026-06-10T15:06:28.000Z","size":1073,"stargazers_count":2,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-10T15:24:38.296Z","etag":null,"topics":["ai","ccpa","claude-skills","cli","codex-skill","data-brokers","dsgvo","gdpr","hermes-skill","openclaw-skill","own-your-data","privacy","python"],"latest_commit_sha":null,"homepage":"https://symaira.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danieljustus.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-19T11:55:21.000Z","updated_at":"2026-06-10T14:05:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/danieljustus/symaira-eraseme","commit_stats":null,"previous_names":["danieljustus/openeraseme","danieljustus/symaira-eraseme"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/danieljustus/symaira-eraseme","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljustus%2Fsymaira-eraseme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljustus%2Fsymaira-eraseme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljustus%2Fsymaira-eraseme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljustus%2Fsymaira-eraseme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danieljustus","download_url":"https://codeload.github.com/danieljustus/symaira-eraseme/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danieljustus%2Fsymaira-eraseme/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34208761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ccpa","claude-skills","cli","codex-skill","data-brokers","dsgvo","gdpr","hermes-skill","openclaw-skill","own-your-data","privacy","python"],"created_at":"2026-06-11T17:03:11.831Z","updated_at":"2026-06-11T17:03:12.677Z","avatar_url":"https://github.com/danieljustus.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Symaira EraseMe\n\n**Automated data broker removal tool — close your accounts, erase your data.**\n\n\u003e **Beta** — Core features are stable and tested. Some advanced features (web-form CAPTCHA solving, DPA auto-filing) require manual setup or are event-flagged only.\n\n[![CI](https://img.shields.io/github/actions/workflow/status/danieljustus/Symaira-EraseMe/ci.yml?branch=main\u0026label=CI\u0026logo=github)](https://github.com/danieljustus/Symaira-EraseMe/actions/workflows/ci.yml)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://python.org)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/danieljustus/symaira-eraseme/main/assets/terminal-demo.svg\" alt=\"Symaira EraseMe terminal demo — init-profile, broker listing, plan creation, and campaign status\" width=\"760\"\u003e\n\u003c/p\u003e\n\nSymaira EraseMe helps you exercise your GDPR/CCPA right to erasure against\ndata brokers. It provides:\n\n- **A curated registry** of 1,200+ data brokers with opt-out processes documented\n- **CLI tools** to plan, send, track, and triage removal requests\n- **Skills** for LLM-powered agents (Claude Code, OpenClaw, etc.)\n- **Lifecycle management** with deadline tracking, reminders, escalation, and re-scans\n- **Automated registry maintenance** via weekly scans of public state broker registries\n\n## Features\n\n- **Curated broker registry** with YAML-based definitions for **1,277 data brokers** across the EU (121), UK (20), and US (1,138), including opt-out URLs, required account identifiers, contact methods (web forms, email), and verification keywords.\n- **Event-sourced architecture** with an append-only SQLite event store, state projections, and full audit trail for every removal request.\n- **CLI automation** with 30+ commands to plan removal campaigns, send opt-out requests in batches, track progress, monitor deadlines, and triage broker replies from the terminal.\n- **Web-form automation** via Playwright for brokers that only accept opt-outs through web forms, including form-filling, CAPTCHA detection, and screenshot capture.\n- **Inbox triage** via IMAP polling to fetch broker replies, classify them with an LLM (Claude), and generate jurisdiction-aware rebuttals for rejections.\n- **Deadline tracking** with automatic jurisdiction-aware deadline monitoring (GDPR: 30 days, CCPA: 45 days). The tick engine checks daily for overdue requests and triggers reminders with exponential backoff.\n- **Escalation workflows** that flag requests for DPA complaints after brokers miss the legal response window.\n- **LLM agent skills** as ready-made skill files for Claude Code, Cursor, Windsurf, Hermes, GitHub Copilot, Codex, and other LLM-powered coding agents. These skills let AI assistants work with the tool on your behalf. See [AGENTS.md](AGENTS.md) for setup instructions.\n- **Jurisdiction-aware workflows** with support for GDPR (Europe), CCPA (California), CPRA, LGPD, and PIPEDA erasure rights, including jurisdiction-specific templates, timelines, and legal references.\n- **Scheduler integration** that generates cron, launchd, or systemd configurations to run the tick engine, inbox polling, and quarterly re-scans automatically.\n- **Automated registry maintenance** with a weekly GitHub Action that pulls fresh entries from official US state broker registries and opens a PR with the diff, plus a Monday link-check workflow that flags dead broker websites.\n- **Dashboard and reports** for campaign analytics, jurisdiction breakdowns, and GDPR-compliant record-keeping exports.\n\n## Install\n\n**End users** (from PyPI):\n\n```bash\npip install symeraseme\n```\n\nOptional extras:\n\n```bash\npip install symeraseme[web]      # Playwright-based browser automation\npip install symeraseme[triage]   # LLM triage via Anthropic Claude\n```\n\n**macOS users** (via Homebrew):\n\n```bash\nbrew tap danieljustus/symaira\nbrew install symeraseme\n```\n\n**Developers** (from source):\n\n```bash\n# Clone the repository\ngit clone https://github.com/danieljustus/Symaira-EraseMe.git\ncd symaira-eraseme\n\n# Install dependencies with uv\nuv sync\nuv pip install -e \".[dev,web,triage]\"\n\n# Configure your environment\ncp .env.example .env\n# Edit .env and add your ANTHROPIC_API_KEY\n```\n\nSee `.env.example` for all supported environment variables.\n\n## Usage\n\n### Getting started\n\n```bash\n# Initialize your profile with personal details\nsymeraseme init-profile\n\n# List all registered brokers, optionally filtered by jurisdiction or law\nsymeraseme brokers list --law GDPR\n\n# Show details for a specific broker\nsymeraseme brokers show --name spokeo\n```\n\n### Demo\n\n```console\n$ symeraseme init-profile\n✓ Profile saved to ~/.config/symeraseme/profile.json\n\n$ symeraseme brokers list --law GDPR\n┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n┃ Name         ┃ Website                     ┃ Jurisdiction  ┃\n┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n│ Spokeo       │ https://www.spokeo.com      │ CCPA          │\n│ Intelius     │ https://www.intelius.com    │ CCPA          │\n│ Acxiom (EU)  │ https://www.acxiom.com      │ GDPR          │\n│ Schufa       │ https://www.schufa.de       │ GDPR          │\n└──────────────┴─────────────────────────────┴───────────────┘\n\n$ symeraseme plan create --campaign initial --law GDPR --max 5\n✓ Plan created: 5 brokers selected\n  Campaign: initial\n\n$ symeraseme plan status\nCampaign: initial\n┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓\n┃ Broker      ┃ Status      ┃ Deadline             ┃\n┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩\n│ Acxiom (EU) │ planned     │ —                    │\n│ Schufa      │ planned     │ —                    │\n│ Experian EU │ planned     │ —                    │\n│ Equifax EU  │ planned     │ —                    │\n│ Creditreform│ planned     │ —                    │\n└─────────────┴─────────────┴──────────────────────┘\n```\n\n### Planning and execution\n\n```bash\n# Create a removal plan for GDPR brokers (limit to 10)\nsymeraseme plan create --campaign initial --jurisdiction GDPR --max 10\n\n# Review the plan before sending\nsymeraseme plan show --campaign initial\n\n# Execute the plan in batches (respects rate limits, requires consent)\nsymeraseme plan execute --campaign initial --batch-size 5 --delay 30 --yes\n\n# Check overall campaign progress\nsymeraseme plan status\n\n# View deadline calendar and upcoming tick actions\nsymeraseme calendar --weeks 4\n```\n\n### Inbox triage (requires `[triage]` extra)\n\n```bash\n# Poll your IMAP inbox for broker replies\nsymeraseme poll-inbox --username your@email.com\n\n# Classify a broker reply via LLM\nsymeraseme classify-reply \u003crequest_id\u003e\n\n# Generate a jurisdiction-aware rebuttal for a rejection\nsymeraseme generate-rebuttal \u003crequest_id\u003e\n```\n\n### Web-form automation (requires `[web]` extra)\n\n```bash\n# Run a broker's web-form opt-out via Playwright\nsymeraseme run-web-form \u003cbroker_id\u003e\n\n# List manual fallback tasks for forms that couldn't be automated\nsymeraseme manual-tasks list\n\n# Mark a manual task as completed\nsymeraseme manual-tasks complete \u003ctask_id\u003e\n```\n\n### Lifecycle and maintenance\n\n```bash\n# Run the tick engine (checks deadlines, reminders, escalations)\nsymeraseme plan tick --dry-run\nsymeraseme plan tick\n\n# Generate scheduler configs (cron / launchd / systemd)\nsymeraseme generate-scheduler --output ./schedules\n\n# Install schedules\nsymeraseme schedule install ./schedules\n\n# Generate a dashboard report\nsymeraseme generate-dashboard\n\n# Export campaign data for GDPR record-keeping\nsymeraseme export --format json --output campaign.json\n```\n\n### Other commands\n\n```bash\n# Validate registry YAML files against the schema\nsymeraseme validate\n\n# Show event history for a request\nsymeraseme events show \u003crequest_id\u003e\n\n# List all removal requests\nsymeraseme requests list --status pending\n\n# Grant consent for destructive operations\nsymeraseme grant execute --ttl 3600\n```\n\nRun `symeraseme --help` for a full list of commands and options.\n\n## Architecture\n\nSymaira EraseMe uses an **event-sourced architecture** built on SQLite:\n\n```\n┌─────────────┐     ┌──────────────┐     ┌─────────────┐\n│   CLI /     │────▶│   Event      │────▶│  Request    │\n│   Skills    │     │   Store      │     │  State      │\n└─────────────┘     │  (SQLite)    │     │ (Projection)│\n                    └──────────────┘     └─────────────┘\n                           │\n                    ┌──────┴──────┐\n                    ▼             ▼\n            ┌──────────┐   ┌──────────┐\n            │  Tick    │   │  Reports │\n            │  Engine  │   │ / Export │\n            └──────────┘   └──────────┘\n```\n\n- **Event Store**: Append-only log of all actions (planned, sent, ack, reminder, deadline reached, etc.)\n- **State Projection**: Rebuilds the current state of every request from events\n- **Tick Engine**: Daily scan for deadlines, reminders, and escalations\n- **Triage**: LLM-based classification of broker replies with jurisdiction-aware rebuttal generation\n\n## Registry maintenance\n\nThe broker registry is kept fresh by two scheduled GitHub Actions:\n\n- **`registry-scanner`** (Sundays, 00:00 UTC) — fetches the latest data-broker\n  registries published by US states (e.g. California, Vermont, Oregon, Texas),\n  normalizes the records into YAML entries, and opens a pull request for any\n  additions or changes.\n- **`registry-link-check`** (Mondays, 06:00 UTC) — issues a `HEAD` request to\n  every broker's `website` field and reports unreachable URLs so dead entries\n  can be retired or corrected.\n\nYou can also run the sync manually:\n\n```bash\nuv run python scripts/registry_sync.py\n```\n\n## Development\n\n### Setup\n\n```bash\nuv sync --all-extras\nuv pip install -e \".[dev,web,triage]\"\npre-commit install\n```\n\nThe pre-commit hooks include:\n- **Detect private keys** — checks for hardcoded private keys\n\nCI additionally runs **TruffleHog** for comprehensive secrets scanning on every pull request.\n\n### Run tests\n\n```bash\nuv run pytest --verbose --tb=short\n```\n\n### Lint and type-check\n\n```bash\nuv run ruff check src/symeraseme/\nuv run ruff format --check src/symeraseme/\nuv run mypy src/symeraseme/\n```\n\nAll three checks run in CI on every push and pull request to the `main` branch.\n\n### Project structure\n\n```\nsrc/symeraseme/\n  cli/           — Typer CLI application\n  core/          — Event store, projections, tick engine, templating, scheduler\n  registry/      — Broker loader, schema validation\n  services/      — CLI command handlers\n  adapters/      — Web (Playwright), Triage (Claude), Email (SMTP/IMAP)\nregistry/\n  brokers/       — YAML broker definitions (eu/, uk/, us/)\n  laws/          — Jinja2 legal templates (GDPR, CCPA, rebuttals)\n  schemas/       — JSON Schema for broker validation\nskills/          — LLM agent skill files (Claude Code, Cursor, Windsurf, Hermes, Copilot, Codex)\nexamples/        — Integration examples for all supported AI agents\nAGENTS.md        — Setup guide for all AI agent integrations\n```\n\n## Security\n\n- **Identity profile encryption**: Profiles are encrypted with AES-256-GCM and authenticated with the header as AAD. Files written since v0.1.2 use header `version: 2`; earlier files used `version: 1`. A legacy no-AAD fallback exists for `version: 0` files only — any tampered ciphertext on version 1+ fails closed with `InvalidTag`.\n- **Database encryption**: When `SYMERASEME_ENCRYPT_DB=1` is set, the SQLite database is encrypted at rest using AES-256-GCM with a key derived from your identity master key. Databases created before v0.2.0 used a fixed PBKDF2 salt (V1 format); newer databases use a per-file random salt (V2 format). On open, any V1 database is automatically re-encrypted to V2 transparently — no manual migration is required. On open, the database is decrypted to a temporary file with restrictive permissions (`0o600`). The temp file is placed in a secure temporary directory. On Linux `/dev/shm` (tmpfs, memory-backed) is used when available. On macOS and Windows the OS temp directory is used, which may be disk-backed. On normal exit, SIGTERM, or context close, the temp file is re-encrypted and removed. A startup scavenger removes any stale temp files older than 5 minutes from previous aborted runs. A `SIGKILL` (e.g., `kill -9`, OOM killer, or system crash) may leave the decrypted temp file behind temporarily; the 5-minute scavenger window limits exposure. If this is a concern for your threat model, consider running Symaira EraseMe on a single-user system, using full-disk encryption, or setting `TMPDIR` to a RAM disk (e.g., `/dev/shm` on Linux).\n- **Consent tokens**: Consent tokens passed via `--consent` or the `SYMERASEME_CONSENT` environment variable are visible in process listings (`ps aux`), shell history, and crash dumps. On shared systems or CI runners, prefer `--consent-file` or `SYMERASEME_CONSENT_FILE` to read the token from a file with `0o600` permissions. The file is read once and the token is consumed (`consume_token`) after verification. Pipe-based input is supported: `echo $TOKEN | symeraseme plan execute --consent-file /dev/stdin`.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieljustus%2Fsymaira-eraseme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanieljustus%2Fsymaira-eraseme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanieljustus%2Fsymaira-eraseme/lists"}