Skip to content

Commit f09eff2

Browse files
rajsinghtechclaude
andcommitted
Fix OIDC token exchange for API-only tailnet workflow
- Add exchange-oidc-token.sh script for proper OIDC JWT token exchange - Update workflow to use OIDC token exchange instead of OAuth client credentials - This matches the authentication pattern used in the working token.yml workflow 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent cd90534 commit f09eff2

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

.github/workflows/api-tailnet-k8s-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
id: get_access_token
4444
run: |
4545
echo "Exchanging OIDC token with Tailscale..."
46-
ACCESS_TOKEN=$(./tailscale/scripts/get-access-token.sh "${{ inputs.client_id }}" "${{ steps.get_oidc_token.outputs.jwt }}")
46+
ACCESS_TOKEN=$(./tailscale/scripts/exchange-oidc-token.sh "${{ inputs.client_id }}" "${{ steps.get_oidc_token.outputs.jwt }}")
4747
echo "::add-mask::$ACCESS_TOKEN"
4848
echo "access_token=$ACCESS_TOKEN" >> $GITHUB_OUTPUT
4949
echo "Successfully obtained access token"
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
CLIENT_ID="$1"
6+
JWT="$2"
7+
8+
if [ -z "$CLIENT_ID" ]; then
9+
echo "Error: OAuth client ID is required as first argument" >&2
10+
exit 1
11+
fi
12+
13+
if [ -z "$JWT" ]; then
14+
echo "Error: JWT token is required as second argument" >&2
15+
exit 1
16+
fi
17+
18+
RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST https://api.tailscale.com/api/v2/oauth/token-exchange \
19+
-H "Content-Type: application/x-www-form-urlencoded" \
20+
-d "client_id=$CLIENT_ID" \
21+
-d "jwt=$JWT")
22+
23+
HTTP_STATUS=$(echo "$RESPONSE" | tail -n 1 | cut -d: -f2)
24+
RESPONSE_BODY=$(echo "$RESPONSE" | sed '$d')
25+
26+
if [ "$HTTP_STATUS" != "200" ]; then
27+
echo "Error: Token exchange failed with status $HTTP_STATUS" >&2
28+
echo "Response: $RESPONSE_BODY" >&2
29+
exit 1
30+
fi
31+
32+
ACCESS_TOKEN=$(echo "$RESPONSE_BODY" | jq -r '.access_token')
33+
34+
if [ "$ACCESS_TOKEN" == "null" ] || [ -z "$ACCESS_TOKEN" ]; then
35+
echo "Error: No access token in response" >&2
36+
echo "Response: $RESPONSE_BODY" >&2
37+
exit 1
38+
fi
39+
40+
echo "$ACCESS_TOKEN"

0 commit comments

Comments
 (0)