← ClaudeAtlas

tailscale-wiflisted

Set up and troubleshoot SECRETLESS GitHub Actions -> Tailscale authentication using Workload Identity Federation (WIF): each run mints a GitHub OIDC token that a Tailscale "Trust Credential" exchanges for a short-lived API token or ephemeral auth key, so no Tailscale API key or OAuth client secret is ever stored. Use this WHENEVER a GitHub Actions workflow needs to talk to Tailscale — pushing an ACL/policy file with tailscale/gitops-acl-action, or joining a CI runner to the tailnet with tailscale/github-action — and you want to drop the stored credential, OR when such a workflow is failing with "token exchange failed with status 403: Unauthorized", "requested tags are invalid or not permitted", or "only one of API Key, OAuth secret, or OAuth client ID and audience". Reach for it on phrases like "Tailscale OIDC", "Tailscale WIF", "federated identity Tailscale", "secretless Tailscale in CI", "remove the Tailscale API key / OAuth secret from Actions", or "Tailscale Trust Credential".
JRichlen/claude-plugins · ★ 1 · AI & Automation · score 68
Install: claude install-skill JRichlen/claude-plugins
# Tailscale Workload Identity Federation (WIF) for GitHub Actions ## Invariant WIF auth is **secretless**. Only the **public** `oauth-client-id` and `audience` are stored — and they belong in repo **variables**, never secrets. The job that authenticates to Tailscale always carries `permissions: id-token: write`, and it passes **exactly one** auth mode. No long-lived Tailscale credential (a REST API key, an OAuth client secret) is ever stored to enable a run: each run mints a fresh GitHub OIDC token, and a Tailscale Trust Credential exchanges it for a short-lived (~1h) API token or an ephemeral auth key that expires on its own. If a change would put a Tailscale secret back into the workflow, drop `id-token: write`, or pass two auth modes at once, it breaks this plugin's whole reason to exist. The cheap eval (`evals/cheap/checks.sh`) defends the marker facts below. ## Why WIF Stored Tailscale credentials are the thing you are removing: - **REST API keys** expire in **90 days or less** — someone has to rotate them, and a leaked key is valid until it expires. - **OAuth client secrets** are long-lived bearer secrets — a leak is worse. WIF (a GA Tailscale feature) replaces both. Trust flows the other way: instead of handing Tailscale a stored secret, each workflow run proves its identity with a GitHub-signed **OIDC token**, and Tailscale's **Trust Credential** (configured in the admin console) decides whether to trust that identity and, if so, mints a short-lived token. Be