v1.3.15 — Sanitize operator data from public sources¶
Note: this file is excluded from
scripts/check-no-personal-data.shby design — it documents the sanitization patch and must name the patterns it scrubbed. The exclusion is narrow (only this file + the script itself).
Security / hygiene patch. Scrubs operator-specific data that the v1.3.2-v1.3.14 dogfood pass leaked into committed release notes, CHANGELOG, ARCHITECTURE.md, a few code fixtures, and one frontend hint string. Adds a guardrail to keep it out going forward.
Why¶
argos-edge is a public repo (github.com/cmos486/argos-edge). Across roughly a dozen release-note files committed during the v1.3.2-v1.3.14 cycle, smoke-test sessions captured the maintainer's actual homelab deployment verbatim:
- per-service subdomains (
archive.cmos486.es,casa.cmos486.es,unifi.cmos486.es, ...) -- a fingerprint of what's running inside the maintainer's network - internal LAN IPs (
192.168.3.156,192.168.3.161, ...) -- topology hints - one Go comment + one frontend hint string referencing the apex domain as an example
None of this is critical attack-surface data on its own, but publishing the catalogue of services + addresses on a public repo is a courtesy lapse and a small attack-surface boost. The v1.3.15 patch removes it from the committed sources and wires in a CI check so the next dogfood pass can't regress it.
What was changed¶
Domain mappings (RFC 2606 placeholders)¶
| Original (private) | Replacement |
|---|---|
archive.cmos486.es | app.example.com |
bookmarks.cmos486.es | bookmarks.example.com |
casa.cmos486.es | home.example.com |
emby.cmos486.es | media.example.com |
fotos.cmos486.es | photos.example.com |
huntlo.cmos486.es | marketplace.example.com |
instaplanner.cmos486.es | planner.example.com |
iot.cmos486.es | iot.example.com |
koi.cmos486.es | fish-tracker.example.com |
links.cmos486.es | links.example.com |
m3u.cmos486.es | iptv.example.com |
pad.cmos486.es | notes.example.com |
photo-quiz.cmos486.es | quiz.example.com |
plex.cmos486.es | streaming.example.com |
smokeping.cmos486.es | ping-monitor.example.com |
storage.cmos486.es | storage.example.com |
sync.cmos486.es | sync.example.com |
unifi.cmos486.es | network-controller.example.com |
uptime.cmos486.es | uptime.example.com |
urbex.cmos486.es | mapping.example.com |
any other *.cmos486.es | app.example.com (catch-all) |
*.cmos486.es (wildcard cert) | *.example.com |
bare cmos486.es (apex; not cmos486.github.io) | example.com |
IP mappings (RFC 5737 documentation ranges)¶
| Original | Replacement |
|---|---|
192.168.3.X (services LAN) | 192.0.2.X (last octet preserved) |
192.168.5.X (client side) | 198.51.100.X (last octet preserved) |
Last octet is preserved so distinct hosts in worked examples stay visually distinct.
Files touched¶
| File | Why it was hit |
|---|---|
CHANGELOG.md | smoke output blocks |
docs/release-notes/v1.3.2.md | subdomain in repro |
docs/release-notes/v1.3.7.md | LAN IP in JSON example |
docs/release-notes/v1.3.8.md | RFC range string is fine; nothing actually changed here -- swept anyway |
docs/release-notes/v1.3.12.md | several smoke-test code blocks |
docs/release-notes/v1.3.14.md | WS smoke-test block |
docs/release-notes/v1.0.0.md v1.1.0.md v1.0.1.md v1.3.0.md v1.3.1.md v1.2.0.md prereleases/v1.3.0-alpha.md prereleases/v1.3.0-beta.md | repo-link footers (no operator data; not modified) |
docs/phase1-dns.md | testbed subdomain + IP |
ARCHITECTURE.md | foo.cmos486.es example |
frontend/src/components/SSOSection.tsx | UI hint string used the apex |
backend/internal/oidc/config.go | comment referenced apex as example |
backend/internal/notifications/events.go | sample event payload had operator IP |
backend/internal/api/oidc_test.go | test fixtures used the apex |
backend/internal/api/target_health_test.go | log-fixture lines used operator IPs |
What was NOT touched (intentional)¶
- Go module path
github.com/cmos486/argos-edge-- the actual public repo URL; required by every Go import and by the README shield badges. mkdocs.ymlsite_url: https://cmos486.github.io/argos-edge/,repo_url,repo_name,site_author: cmos486-- the literal published-docs-portal config.README.mdbadge URLs and the "edit this page" links -- intentional canonical references to the public repo.- All commit messages and authors. Rewriting history would break already-published GitHub release tags and any third-party bookmarks pointing at them.
The reasoning: cmos486 as a GitHub handle bound to this repo is the URL anyone reaches the project through. Scrubbing the handle would defeat its own purpose -- the next visitor would just look at the URL bar.
Operator action required¶
The committed release notes are now sanitized. The corresponding release bodies on GitHub are independent artifacts that the maintainer typed once when publishing each tag. They still contain the original operator data.
Re-edit each release body manually at:
- https://github.com/cmos486/argos-edge/releases/edit/v1.3.2
- https://github.com/cmos486/argos-edge/releases/edit/v1.3.7
- https://github.com/cmos486/argos-edge/releases/edit/v1.3.12
- https://github.com/cmos486/argos-edge/releases/edit/v1.3.14
(The other v1.3.X tags either contained no operator-specific data in their published body, or the body was already a copy-paste of the now-sanitized release-notes file. Spot-check each before saving.)
The simplest workflow: copy the body of the new docs/release-notes/v1.3.X.md (now sanitized) into the GitHub release-edit form and save.
Guardrail¶
scripts/check-no-personal-data.sh is a small grep-based check that fails non-zero on:
cmos486.essubdomains or apex (excluding thecmos486.github.iodocs URL).192.168.3.X/192.168.5.XLAN IPs.discodurovirtualkemail handle.
.github/workflows/personal-data-guardrail.yml runs it on every push to main and every PR. CI fails if a future change re-introduces any of the three patterns.
To run locally:
CONTRIBUTING.md¶
New file documenting the placeholder convention for future contributors / future-self:
- Domains:
example.com,*.example.com(RFC 2606) - LAN IPs:
192.0.2.X,198.51.100.X,203.0.113.X(RFC 5737) - Emails:
ops@example.com,admin@example.com,user@example.com - And the explicit list of public references (Go module path, docs portal URL, mkdocs config) that stay un-scrubbed by design.
The doc is excluded from the rendered mkdocs site (it's contributor-facing, not operator-facing) but lives in docs/ for GitHub-side discoverability.
Files (5 commits)¶
| Commit | Files |
|---|---|
security: sanitize operator hostnames and IPs from release notes (v1.3.2-v1.3.14) | docs/release-notes/*.md, ARCHITECTURE.md, docs/phase1-dns.md, frontend SSOSection, oidc/config.go, notifications/events.go, oidc_test.go, target_health_test.go |
security: sanitize CHANGELOG.md operator references | CHANGELOG.md only |
ci: add check-no-personal-data guardrail | scripts/check-no-personal-data.sh, .github/workflows/personal-data-guardrail.yml |
docs(contributing): operator data sanitization rules | docs/CONTRIBUTING.md, mkdocs.yml exclude_docs |
chore: bump version to 1.3.15 + CHANGELOG + release notes | backend/cmd/argos/main.go, frontend/package.json, CHANGELOG.md (this entry), docs/release-notes/v1.3.15.md, mkdocs.yml nav |
Verification¶
scripts/check-no-personal-data.sh -> [OK] no operator-specific data found in committed sources. go build ./..., go test ./..., go vet ./..., npm run build, npm run lint, mkdocs build --strict all pass post-sanitization.
Not changed¶
- All v1.3.14 functional fixes (WebSocket transport, expect status messaging, AppSec block-mode CRS, panel CLI) unchanged.
- No DB schema, no env vars, no compose surface modified.
- Public repo URLs and the docs portal stay where they are.