Polyhydra Skills / Homelab Infra
Safely discover which Infisical project/env/path a secret key lives at, or list what keys exist somewhere -- without ever printing, logging, or writing a secret VALUE. Use before adding a sibling secret next to an existing one, or any time you need to know "where does key X live" without already knowing the value.
Drop this in — save the block below as ~/.claude/skills/infisical-lookup/SKILL.md, or run:
mkdir -p ~/.claude/skills/infisical-lookup cat > ~/.claude/skills/infisical-lookup/SKILL.md <<'EOF' # (paste the full source block below into this file) EOF
# Infisical Lookup ## Why this exists The `infisical` CLI has no "key names only" mode. `infisical secrets` (table output), `--plain`, and every `-o` format (`json`/`yaml`/`dotenv`) all include secret **values**, not just names. There was no existing tool for the very common case of "what's the key/env/path convention for secrets like this one" without already knowing (or wanting to see) the value. Built after a live incident (2026-08-09): while adding a new sibling secret (`GitHub__WebhookSecret`) next to an existing one (`Twitch__WebhookSecret`), an un-piped `infisical secrets --recursive` call was run to find where the existing key lived. Its output — a full table of real secret values — landed in a tool-results file on disk. It was caught and remediated, but the whole class of mistake is avoidable. ## The safe technique Never let `infisical secrets ... -o json` (or any variant) land anywhere as a standalone command — its output has values in it. Always pipe it directly into `jq` in the same command, so only the **projected key-name list** ever becomes visible output. The value-bearing JSON exists only transiently inside the pipe between two subprocesses: ```bash infisical secrets --projectId "$PROJECT" --env "$ENV" --path "$PATH" \ --domain https://secrets.polyhydragames.com/api -o json 2>/dev/null \ | jq -r '.[].secretKey' ``` This skill wraps that pattern so it's never re-derived (or gotten wrong) from scratch under time pressure. ## Commands ```bash scripts/infisical-list-folders.sh --project PROJECT_ID [--env ENV] [--path PATH] scripts/infisical-list-keys.sh --project PROJECT_ID [--env ENV] [--path PATH] [--recursive] [--find SUBSTRING] ``` - `infisical-list-folders.sh` — lists folder names under a path. Folder structure is metadata, not secret data, so this is safe without any special handling — use it first to discover the project's folder layout (most projects here are organized one-folder-per-external-provider, e.g. `/twitch`, `/kick`, `/spotify`, plus an app-named folder like `/channel-cheevos` for app-specific runtime keys). - `infisical-list-keys.sh` — lists secret KEY NAMES (never values) at a project/env/path. Use `--find SUBSTRING` to check "does a key like this already exist" or "where does key X live" across a known folder. Token resolution (both scripts, in order): `INFISICAL_TOKEN` env var if already set; else `INFISICAL_CLIENT_ID`/`INFISICAL_CLIENT_SECRET` (env or `~/.config/secrets/infisical.env`) exchanged via `infisical login --method universal-auth`. Same resolution order most repos' `scripts/lib/secrets.sh` already use, so it works out of the box on machines already set up for homelab work. ## Non-negotiables - Never run `infisical secrets` (any form) without piping its output straight into `jq` (or discarding it) in the same command. If you need to eyeball raw output to debug a jq filter, redirect to a file under `/dev/shm` (tmpfs, memory-backed) and `shred -u` it immediately after — never a regular disk path, never a path that could end up in a tool-results/transcript capture. - **Never run `infisical login ... --plain` (or `--token`, or any flag whose entire job is printing a raw credential) as a standalone command you then view.** These exist to hand a token to the *next* program in a pipeline, not to a human. A second live incident (2026-08-09) happened exactly this way: debugging why `infisical-list-keys.sh` returned nothing, someone ran `infisical login --method universal-auth ... --plain` directly and piped the output to `tail` "to see what happened" — the raw access token landed in a conversation transcript. If a login/token step needs debugging, check the *exit code* and a redacted marker (token non-empty? starts with the expected prefix?) — never the token content itself. If genuinely stuck, read this skill's scripts to reason about it statically rather than running the underlying command unfiltered. - This skill only ever prints key names, never values. If a task genuinely needs a value (e.g. to complete an external provider's webhook setup UI), that's a job for a human retrieving it themselves via their own Infisical access (web UI or `infisical secrets get KEY --plain` run directly in their own terminal) — not for an agent to fetch and relay. - If a value ever does leak into a file, log, or transcript despite this, treat it as a real exposure: flag it to the operator immediately, don't try to quietly clean it up without telling them, and let them decide on rotation. ## Companion `secret-apply` (same skills directory) is the write-side counterpart — once you know where a key needs to live (via this skill), `secret-apply.sh` is what actually applies a new/rotated value there without it touching an agent transcript.