mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
## What changed? - Added `development-jwt.yaml` config that runs Temporal with JWT authorization enabled using a JWKS file loaded from local disk. Loading from local disk is added in https://github.com/temporalio/temporal/pull/9590. - Added `config/jwt/setup-keys.sh` to generate an RSA key pair and JWKS file in `/tmp/temporal-jwt-test/`. - Added `config/jwt/generate-token.sh` to create signed JWTs for testing. - Added `make start-jwt` target. ## Why? Testing JWT authentication currently requires an external identity provider or manual key/token setup. This provides a self-contained local workflow: `make start-jwt` generates keys automatically and starts the server with auth enforced, and `generate-token.sh` produces tokens on demand. ## How did you test it? - [X] built - [X] run locally and tested manually - [ ] covered by existing tests - [ ] added new unit test(s) - [ ] added new functional test(s) Tested this in conjunction with https://github.com/temporalio/temporal/pull/9582. Was able to list the workflows by passing the token and dumping their history. When the token is not used, the auth fails with "Request denied". ## Potential risks Keys are stored in /tmp/temporal-jwt-test/ which is world-readable. This is acceptable for local development but the scripts should not be used in shared or production environments.
59 lines
1.9 KiB
Bash
Executable File
59 lines
1.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# Generate a test JWT signed with the local private key
|
|
# Usage: ./generate-token.sh [subject] [permissions...]
|
|
#
|
|
# Examples:
|
|
# ./generate-token.sh # Default: [email protected] with system:admin
|
|
# ./generate-token.sh [email protected] # Custom subject with system:admin
|
|
# ./generate-token.sh [email protected] default:admin # Custom subject with namespace permission
|
|
# ./generate-token.sh [email protected] system:admin default:writer # Multiple permissions
|
|
#
|
|
# The generated JWT has the following structure:
|
|
# Header: {"alg": "RS256", "typ": "JWT", "kid": "test-key-1"}
|
|
# Payload: {"sub": "<subject>", "permissions": ["<perm1>", ...], "iat": <now>, "exp": <now+1h>}
|
|
|
|
set -euo pipefail
|
|
|
|
base64url() { base64 | tr -d '\n' | tr '+/' '-_' | tr -d '='; }
|
|
|
|
KEY_DIR="/tmp/temporal-jwt-test"
|
|
PRIVATE_KEY="$KEY_DIR/private-key.pem"
|
|
|
|
if [ ! -f "$PRIVATE_KEY" ]; then
|
|
echo "Private key not found at $PRIVATE_KEY, running setup-keys.sh..." >&2
|
|
"$(dirname "$0")/setup-keys.sh"
|
|
fi
|
|
|
|
if [ ! -f "$PRIVATE_KEY" ]; then
|
|
echo "Error: Private key still not found at $PRIVATE_KEY" >&2
|
|
exit 1
|
|
fi
|
|
|
|
SUBJECT="${1:-test[email protected]}"
|
|
shift 2>/dev/null || true
|
|
|
|
# Collect permissions (default to system:admin if none specified)
|
|
if [ $# -eq 0 ]; then
|
|
PERMISSIONS='["system:admin"]'
|
|
else
|
|
PERMISSIONS=$(printf '%s\n' "$@" | jq -R . | jq -s .)
|
|
fi
|
|
|
|
NOW=$(date +%s)
|
|
EXP=$((NOW + 3600))
|
|
|
|
HEADER='{"alg":"RS256","typ":"JWT","kid":"test-key-1"}'
|
|
HEADER_B64=$(echo -n "$HEADER" | base64url)
|
|
|
|
PAYLOAD=$(jq -n -c --arg sub "$SUBJECT" --argjson perms "$PERMISSIONS" \
|
|
--argjson iat "$NOW" --argjson exp "$EXP" \
|
|
'{sub: $sub, permissions: $perms, iat: $iat, exp: $exp}')
|
|
PAYLOAD_B64=$(echo -n "$PAYLOAD" | base64url)
|
|
|
|
SIGNATURE=$(echo -n "${HEADER_B64}.${PAYLOAD_B64}" | \
|
|
openssl dgst -sha256 -sign "$PRIVATE_KEY" | \
|
|
base64url)
|
|
|
|
# Output the complete JWT
|
|
echo "${HEADER_B64}.${PAYLOAD_B64}.${SIGNATURE}"
|