{
  "schema_version": 1,
  "type": "skill",
  "slug": "adom-security",
  "title": "adom-security — what Claude MUST NOT leak outward",
  "brief": "Hard rules for every Claude Code on Adom: never post container slug, hostname, internal URL, or token. Use user name + repo name instead.",
  "version": "1.0.0",
  "tags": [],
  "license": "MIT",
  "discovery_triggers": [
    "post message to chat",
    "send to slack",
    "send to gchat",
    "send to kel",
    "send email",
    "post to webhook",
    "publish to wiki",
    "create github issue",
    "comment on pr",
    "tweet",
    "announce",
    "notify team",
    "alert",
    "share log output",
    "paste error",
    "attribution",
    "identity",
    "security",
    "safe to share",
    "redact",
    "leak",
    "expose",
    "container url",
    "can I include this slug",
    "is this sensitive",
    "hostname in message",
    "container hostname",
    "docker hostname",
    "which user is this"
  ],
  "discovery_pitch": "Hard security rules for every Claude Code running on Adom. Read proactively before any outward post (chat / webhook / wiki / GitHub / email). Covers what NEVER to leak (slug, hostname, internal URL, token) and the canonical safe attribution format (user + repo name).",
  "source_path": "SKILL.md",
  "readme": "---\nname: adom-security\ndescription: Critical security rules for every Claude Code running on an Adom container. Read proactively before posting anything to an external destination (Google Chat, Slack, email, public wiki, GitHub issue/PR/comment, any URL outside the container). Covers secret-shaped identifiers that must NEVER leak — container slugs, Docker hostnames, internal service URLs, tokens, webhook URLs — and the safe alternatives (user name + repo name). Trigger words: post, message, notify, alert, chat, gchat, email, webhook, announce, share, publish, comment, tweet, send to, attribution, security, identity, leak, redact, safe to share.\n---\n\n# adom-security — what Claude MUST NOT reveal outside the container\n\nEvery Adom container has identifiers that behave like passwords. Leaking them into a chat message, GitHub comment, wiki page, log file that might be shared, or any other outward-facing surface lets anyone construct internal URLs and reach services that were supposed to be private.\n\nBefore any outbound post, **run the checklist below.** This is a HARD rule — not a stylistic preference.\n\n## 🚫 NEVER include in outbound messages\n\n| Value | Example | Why it's sensitive |\n|---|---|---|\n| **Container slug** | `8v0y8o3547h2`, `rk6euj7525tq` | Part of `adom-cli carbon containers current | jq .slug` or the `ssh <user>-<name>-<slug>@adom.cloud` form. Slugs are effectively passwords for the SSH hostname — **if someone has the slug they can often reach services directly**. |\n| **Docker short hostname** | `27bd9735b059`, `c1c0a59c279a` | The value of `$(hostname)` inside a container. Sometimes exposes the slug (or a sibling ID that works the same way) via the `/proxy/PORT/` URL pattern. Treat identically to slug. |\n| **Coder / container internal URL** | `https://coder.john-service-jlcpcb-9a8b6c0328533a9b.containers.adom.inc/...` | Contains the slug fragment. Anyone with the URL can attempt auth against the internal service. Especially sensitive for `service-*` containers that may not require auth on every endpoint. |\n| **Auth tokens / bearer strings** | `WIKI_AUTH_TOKEN`, `ADOM_WIKI_TOKEN`, any `gh` PAT, any API key, `chat.googleapis.com/.../?key=...&token=...` webhook URL | Obvious. But webhooks are easy to accidentally paste; they carry their own token in the query string. |\n| **OAuth refresh tokens / client secrets** | Values from `~/.config/gchat-oauth.json`, `.env` files | Full account takeover potential. |\n| **Absolute paths that reveal usernames of other people** | `/home/noah/...` when posting from an automated script | Minor but preferred. |\n\n## ✅ SAFE to include\n\n| Value | Source | Example |\n|---|---|---|\n| **Adom user name** | `adom-cli carbon user get \\| jq -r .name` | `john` |\n| **Display name** | `adom-cli carbon user get \\| jq -r .display_name` | `John Lauer` |\n| **Repo name** | `adom-cli carbon containers current \\| jq -r .repository.name` | `galliaApril` |\n| **Repo owner name** | `adom-cli carbon containers current \\| jq -r .repository.owner.name` | `john` |\n| **Public domain URLs** | (these don't embed slugs) | `wiki-ufypy5dpx93o.adom.cloud`, `adom.inc` |\n\nThese are not secrets — they're the equivalent of \"name and team\" and are already visible to anyone on the platform.\n\n## Canonical attribution format\n\nWhen posting automated messages to any channel (Google Chat via `kel`, Slack, email, a GitHub comment, wiki page, etc.), attribute to the **user** and (if useful) the **repo**, never the slug or hostname:\n\n- Short form: `on behalf of john`\n- With repo: `on behalf of john via galliaApril`\n- Kel-specific: `*Kel (on behalf of john)*` or `*Kel (on behalf of john via galliaApril)*`\n\nThe `kel` CLI does this automatically. If you're writing a script that posts to any other outward channel, follow the same pattern — don't roll your own `$(hostname)` tag.\n\n## Where to get safe identifiers\n\nPreferred — read the cached identity file populated by `gallia/install.mjs`:\n\n```bash\npython3 -c \"import json; d=json.load(open('/home/adom/.config/adom-identity.json')); print(d['user'], d['repo'])\"\n```\n\nFallback (slower, makes a network call):\n\n```bash\nadom-cli carbon user get | jq -r .name\nadom-cli carbon containers current | jq -r .repository.name\n```\n\nIf neither works, **do not post** — omit the message or fail loudly. Don't substitute in `$(hostname)`.\n\n## Common mistakes Claude Code makes (and must avoid)\n\n1. **Reflexively using `$(hostname)` as \"the container name\".** Docker's short hostname is derived from the container ID, which is slug-equivalent. Use the identity file instead.\n2. **Pasting the current terminal path/context into a bug report.** `~/project/gallia/...` is fine; `/proxy/8785/...` URLs with slug fragments are not.\n3. **Including a coder container URL in a public wiki page or GitHub issue.** The URL is clickable-proof-of-access to your internal services. Always rewrite to the public domain (e.g., the wiki's `wiki-ufypy5dpx93o.adom.cloud`) or drop the URL entirely.\n4. **Echoing a webhook URL back to the user in an outward channel.** The URL itself is the auth token. Keep it in private config files only.\n5. **Writing logs/alerts that include the slug, then sending the log to chat.** Tail-and-post workflows need to redact first: `sed -E 's/[a-z0-9]{16}\\.containers\\.adom\\.inc/REDACTED.containers.adom.inc/g; s/[a-f0-9]{12}/REDACTED/g'`.\n\n## Redaction helper (use before posting raw log contents)\n\n```bash\n# Redact likely slugs + coder URLs from piped input before posting.\nredact() {\n  sed -E \\\n    -e 's#coder\\.[a-z0-9-]+\\.containers\\.adom\\.inc#REDACTED-container-url#g' \\\n    -e 's#\\b[a-f0-9]{12}\\b#REDACTED-hostname#g' \\\n    -e 's#\\b[a-z0-9]{12,16}\\.adom\\.cloud#REDACTED-container.adom.cloud#g' \\\n    -e 's#key=[A-Za-z0-9_-]+#key=REDACTED#g' \\\n    -e 's#token=[A-Za-z0-9_.-]+#token=REDACTED#g' \\\n    -e 's#Bearer [A-Za-z0-9_.-]+#Bearer REDACTED#g'\n}\n\ntail -20 /var/log/build.log | redact | kel --stdin\n```\n\n## When in doubt\n\nIf you're about to post something outward and you're uncertain whether a string might be a slug, token, or internal-only URL — **redact it**. A message with one REDACTED blob that reaches the reader is strictly better than the one where a slug leaked and later had to be rotated.\n\nThis rule is non-negotiable across every channel, every user, every container. If you see a prior message in the current conversation where Claude leaked an identifier, flag it to the user immediately so they can rotate (the webhook URL, the token, or if necessary the container itself).\n",
  "author": {
    "name": "Kyle Bergstedt",
    "email": "kyle@adom.inc"
  },
  "visibility": {
    "public": true
  },
  "hero": null,
  "sample_prompts": [],
  "metadata": {},
  "created_at": "2026-05-28T05:29:48.637Z",
  "updated_at": "2026-05-28T05:29:48.637Z",
  "sub_skills": [],
  "parent_app": null,
  "org": "adom"
}