diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 9555f71..d32d03c 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -32,6 +32,7 @@ jobs: run: nix develop --command python3 scripts/validate.py env: TAILSCALE_API_KEY: ${{ secrets.TAILSCALE_API_KEY }} + TS_OAUTH_CLIENT_ID: ${{ vars.TS_OAUTH_CLIENT_ID }} XDG_CACHE_HOME: ${{ runner.temp }}/.cache - name: Show diff @@ -39,10 +40,12 @@ jobs: nix develop --command python3 scripts/push.py --dry-run || true env: TAILSCALE_API_KEY: ${{ secrets.TAILSCALE_API_KEY }} + TS_OAUTH_CLIENT_ID: ${{ vars.TS_OAUTH_CLIENT_ID }} XDG_CACHE_HOME: ${{ runner.temp }}/.cache - name: Push ACL to Tailscale run: nix develop --command python3 scripts/push.py --confirm env: TAILSCALE_API_KEY: ${{ secrets.TAILSCALE_API_KEY }} + TS_OAUTH_CLIENT_ID: ${{ vars.TS_OAUTH_CLIENT_ID }} XDG_CACHE_HOME: ${{ runner.temp }}/.cache diff --git a/scripts/ts_auth.py b/scripts/ts_auth.py index 0652620..c703933 100644 --- a/scripts/ts_auth.py +++ b/scripts/ts_auth.py @@ -14,6 +14,7 @@ """ import json +import os import urllib.parse import urllib.request @@ -24,14 +25,24 @@ def resolve_bearer(secret: str) -> str: """Return a usable bearer token for the Tailscale API. Direct API keys are returned unchanged; OAuth client secrets are exchanged - for an access token. + for an access token. The exchange requires the (non-secret) client id in + TS_OAUTH_CLIENT_ID — Tailscale's token endpoint rejects requests without it. """ if not secret or not secret.startswith("tskey-client-"): return secret + client_id = os.environ.get("TS_OAUTH_CLIENT_ID", "") + if not client_id: + raise RuntimeError( + "TAILSCALE_API_KEY holds an OAuth client secret (tskey-client-...) " + "but TS_OAUTH_CLIENT_ID is unset; the token exchange requires the " + "client id. Set the TS_OAUTH_CLIENT_ID Actions variable (it is not " + "a secret) alongside the client-secret swap." + ) + data = urllib.parse.urlencode( { - "client_id": "", + "client_id": client_id, "client_secret": secret, "grant_type": "client_credentials", }