{"id":49670660,"url":"https://github.com/mrworf/dmarc4you","last_synced_at":"2026-05-06T22:37:34.150Z","repository":{"id":346703033,"uuid":"1191194749","full_name":"mrworf/dmarc4you","owner":"mrworf","description":"Selfhosted DMARC analysis platform, complete with RBAC and audit logging","archived":false,"fork":false,"pushed_at":"2026-04-10T23:16:36.000Z","size":942,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-11T01:13:13.567Z","etag":null,"topics":["dkim","dmarc","email","spf"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrworf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY_AND_AUDIT.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-03-25T02:20:52.000Z","updated_at":"2026-04-10T23:16:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mrworf/dmarc4you","commit_stats":null,"previous_names":["mrworf/dmarc4you"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mrworf/dmarc4you","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrworf%2Fdmarc4you","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrworf%2Fdmarc4you/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrworf%2Fdmarc4you/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrworf%2Fdmarc4you/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrworf","download_url":"https://codeload.github.com/mrworf/dmarc4you/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrworf%2Fdmarc4you/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32715426,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T19:35:05.142Z","status":"ssl_error","status_checked_at":"2026-05-06T19:35:03.996Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["dkim","dmarc","email","spf"],"created_at":"2026-05-06T22:37:33.364Z","updated_at":"2026-05-06T22:37:34.144Z","avatar_url":"https://github.com/mrworf.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DMARCWatch\n\n[![dependency-audit](https://github.com/mrworf/dmarc4you/actions/workflows/dependency-audit.yml/badge.svg)](https://github.com/mrworf/dmarc4you/actions/workflows/dependency-audit.yml)\n[![frontend-seeded-e2e](https://github.com/mrworf/dmarc4you/actions/workflows/frontend-seeded-e2e.yml/badge.svg)](https://github.com/mrworf/dmarc4you/actions/workflows/frontend-seeded-e2e.yml)\n[![docker-publish](https://github.com/mrworf/dmarc4you/actions/workflows/docker-publish.yml/badge.svg)](https://github.com/mrworf/dmarc4you/actions/workflows/docker-publish.yml)\n[![ghcr-backend](https://img.shields.io/badge/GHCR-backend%20image-2ea44f?logo=docker\u0026logoColor=white)](https://github.com/mrworf/dmarc4you/pkgs/container/dmarc4you-backend)\n[![ghcr-frontend](https://img.shields.io/badge/GHCR-frontend%20image-2ea44f?logo=docker\u0026logoColor=white)](https://github.com/mrworf/dmarc4you/pkgs/container/dmarc4you-frontend)\n\nDMARCWatch is a self-hosted DMARC analysis platform with a FastAPI backend, a Next.js frontend, SQLite storage in v1, asynchronous ingest jobs, domain-scoped RBAC, and audit logging.\n\n\u003e ℹ️ **NOTE** \n\u003e\n\u003e This project is entirely created using AI as an experiement. Take it for what you want, as usual, no disclaimers or warranty provided. But seems to work pretty good.\n\n## Core capabilities\n\n- Ingest DMARC aggregate and forensic reports from API, CLI, browser upload, XML files, ZIP/GZIP payloads, and MIME email messages.\n- Normalize report data for dashboard views, aggregate exploration, and forensic search.\n- Enforce strict domain scoping for users, dashboards, and API keys.\n- Support optional reverse DNS and offline GeoIP enrichment during ingest.\n- Manage domain archive, restore, retention, and purge workflows.\n\n## Quick start\n\n```bash\ngit clone \u003crepository-url\u003e\ncd dmarc4you\n\npython -m venv .venv\nsource .venv/bin/activate\npip install -r requirements.txt\n\ncp config.example.yaml config.yaml\ncd frontend\nnpm install\ncd ..\n```\n\nEdit `config.yaml` and set a real `auth.session_secret` before using the service outside local development.\n\nStart the backend:\n\n```bash\npython -m backend.main\n```\n\nStart the frontend in another terminal:\n\n```bash\ncd frontend\nnpm run dev\n```\n\nThe backend listens on `http://127.0.0.1:8000` by default and the frontend on `http://127.0.0.1:3000`. On first startup, the bootstrap `admin` password is printed once to the backend console and must be changed after the first sign-in.\n\nFor contributor and test tooling, also install:\n\n```bash\npip install -r requirements-dev.txt\n```\n\n## Docker quick start\n\nPrebuilt images are published to GitHub Container Registry:\n\n- `ghcr.io/mrworf/dmarc4you-backend`\n- `ghcr.io/mrworf/dmarc4you-frontend`\n- `ghcr.io/mrworf/dmarc4you-imap`\n\nTo run the stack with Docker Compose:\n\n```bash\ncp compose.env.example compose.env\ndocker compose --env-file compose.env up -d\n```\n\nThe base stack publishes:\n\n- frontend on `http://127.0.0.1:3000`\n- backend API on `http://127.0.0.1:8000`\n\nImportant notes:\n\n- Set a real `DMARC_SESSION_SECRET` in `compose.env` before exposing the stack outside local development.\n- The frontend image reads `NEXT_PUBLIC_API_BASE_URL` at runtime so the same GHCR image can be reused across environments.\n- Split-subdomain deployments such as `app.example.com` plus `api.example.com` should set `DMARC_COOKIE_DOMAIN=example.com` so browser CSRF protection works across the frontend/API origins.\n- Keep `DMARC_SESSION_COOKIE_SECURE=false` when serving plain `http://` URLs; switch it to `true` only when browsers reach the app over HTTPS.\n- SQLite data persists in the `dmarc_data` volume. Optional raw artifact archival persists in the `dmarc_archive` volume.\n- If you prefer bind mounts, `compose.yaml` includes commented examples for `./data:/app/data` and `./archive:/app/archive`.\n- Optional offline GeoIP databases can be mounted from `./data/geoip` into `/app/geoip`.\n- The optional IMAP collector joins the stack with `docker compose --env-file compose.env --profile imap up -d`; it uploads unread RFC822 messages from a mailbox through the existing ingest API.\n- To run the collector on a different host from DMARCWatch, use `docker compose --env-file compose.env -f compose.imap.yaml up -d` and point `DMARC_IMAP_API_URL` at the remote API.\n- For HTTPS or a friendlier public entrypoint, start the optional Caddy layer with `docker compose --env-file compose.env -f compose.yaml -f compose.override.proxy.yaml up -d` and set `DMARC_FRONTEND_HOST` / `DMARC_API_HOST` in `compose.env`.\n\n## Verification\n\nBefore opening a PR, run the dependency audit gate locally:\n\n```bash\nbash scripts/check_dependency_audits.sh\n```\n\nThis checks frontend production dependencies with `npm audit` and backend Python dependencies with `pip-audit`, matching the CI security workflow.\nThe Python audit targets runtime dependencies from `requirements.txt`; test-only packages live in `requirements-dev.txt`.\n\n## Configuration highlights\n\n```yaml\ndatabase:\n  path: data/dmarc.db\n\nauth:\n  session_secret: change-me-in-production\n\narchive:\n  storage_path: null\n\ndns:\n  nameservers: []\n  timeout_seconds: 5.0\n\ngeoip:\n  provider: none\n  database_path: null\n```\n\nNotes:\n\n- `DMARC_*` environment variables can override YAML config values.\n- Container deployments can use `compose.env` without a `config.yaml` file.\n- Store local GeoIP MMDB files under `data/`, for example `data/dbip-country-lite.mmdb`.\n- `archive.storage_path` is optional. Leave it unset to disable raw artifact archival.\n\n## CLI\n\n```bash\npython -m cli ingest --api-key YOUR_KEY report.xml report.xml.gz report.zip report.eml\npython -m cli imap-watch --api-key YOUR_KEY --api-url http://localhost:8000 --host imap.example.com --username reports@example.com --password secret\npython -m cli reset-admin-password [config.yaml]\npython -m cli seed-e2e [config.e2e.yaml] [--cleanup]\n```\n\n## Documentation\n\n- [Getting Started](docs/GETTING_STARTED.md)\n- [Submitting Reports](docs/SUBMITTING_REPORTS.md)\n- [API v1](docs/API_V1.md)\n- [GeoIP Setup](docs/GEOIP_SETUP.md)\n- [Domain Lifecycle](docs/DOMAIN_LIFECYCLE.md)\n- [Security and Audit](docs/SECURITY_AND_AUDIT.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrworf%2Fdmarc4you","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrworf%2Fdmarc4you","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrworf%2Fdmarc4you/lists"}