#!/usr/bin/env bash # Rotate the dedicated Coder token used by the omp MCP integration. # # Coder caps token lifetime at 168h (7d) on this deployment, so this must be run # weekly or the agent's Coder tools start returning 401. # # Mints a fresh `omp-mcp` token, writes it to .mcp-token (mode 600), then # revokes every older token of the same name. The value is never printed. set -euo pipefail ROOT="/home/loca/dev/coder" CRED="$ROOT/.admin-credentials" TOKEN_FILE="$ROOT/.mcp-token" CONTAINER="coder" NAME="omp-mcp" LIFETIME="168h" [[ -r "$CRED" ]] || { echo "missing credentials file: $CRED" >&2; exit 1; } url="$(sed -n 's/^url=//p' "$CRED")" session="$(sed -n 's/^session_token=//p' "$CRED")" [[ -n "$url" && -n "$session" ]] || { echo "url= or session_token= missing in $CRED" >&2; exit 1; } ENVF="$(mktemp)" chmod 600 "$ENVF" trap 'rm -f "$ENVF"' EXIT printf 'CODER_URL=%s\nCODER_SESSION_TOKEN=%s\n' "$url" "$session" >"$ENVF" coder() { sudo -n docker exec -i --env-file "$ENVF" "$CONTAINER" /opt/coder "$@"; } # Existing token ids for this name, captured before minting the replacement. old_ids="$(coder tokens list | awk -v n="$NAME" 'NR>1 && $2==n {print $1}')" new="$(coder tokens create --name "$NAME" --lifetime "$LIFETIME" | tail -n1 | tr -d '[:space:]')" [[ -n "$new" ]] || { echo "token creation produced no value" >&2; exit 1; } umask 077 printf '%s\n' "$new" >"$TOKEN_FILE" chmod 600 "$TOKEN_FILE" # Verify before revoking the old ones, so a bad mint cannot lock us out. code="$(curl -s -o /dev/null -w '%{http_code}' -H "Coder-Session-Token: $new" "$url/api/v2/users/me")" [[ "$code" == "200" ]] || { echo "new token failed verification (http $code); old tokens left intact" >&2; exit 1; } for id in $old_ids; do coder tokens remove "$id" >/dev/null && echo "revoked old token $id" done echo "rotated $NAME; expires in $LIFETIME" coder tokens list