Files
temporal/test-authorization.sh
Christian Galo 02b4ec9ee3 Add JWT-based authorization support for Temporal server with Keycloak integration
- Create QUICK_REFERENCE.md for a concise guide on setting up temporal authorization.
- Add README_AUTHORIZATION.md detailing the implementation steps and common issues.
- Introduce REVERSE_PROXY_APPROACH.md as an alternative method for authorization using a reverse proxy.
- Implement Dockerfile for building a custom Temporal server with authorization features.
- Add main.go to initialize the custom Temporal server with JWT authorization.
- Create example-keycloak-mapper.json for mapping Keycloak groups to Temporal permissions.
- Add development.yaml for configuring the Temporal server with JWT settings.
- Implement test-authorization.sh script to verify JWT token claims and Temporal server access.
- Include go.mod for managing Go dependencies in the custom server.
- Document troubleshooting steps and customization options in README.md.
2025-10-24 02:10:54 +00:00

245 lines
7.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Test script to verify Temporal authorization setup
set -e
echo "=================================="
echo "Temporal Authorization Test Script"
echo "=================================="
echo ""
# Colors for output
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}$1${NC}"
}
print_info() {
echo " $1"
}
# Check if required tools are installed
echo "Checking prerequisites..."
command -v jq >/dev/null 2>&1 || { print_error "jq is not installed. Install with: apt-get install jq"; exit 1; }
command -v curl >/dev/null 2>&1 || { print_error "curl is not installed."; exit 1; }
print_success "Prerequisites OK"
echo ""
# Configuration
read -p "Enter Keycloak URL (e.g., https://keycloak.example.com): " KEYCLOAK_URL
read -p "Enter Realm name: " REALM
read -p "Enter Client ID (e.g., temporal-ui): " CLIENT_ID
read -sp "Enter Client Secret: " CLIENT_SECRET
echo ""
read -p "Enter test username: " USERNAME
read -sp "Enter test password: " PASSWORD
echo ""
echo ""
# Get token from Keycloak
print_info "Requesting token from Keycloak..."
TOKEN_ENDPOINT="${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/token"
RESPONSE=$(curl -s -X POST "$TOKEN_ENDPOINT" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}" \
-d "grant_type=password" \
-d "username=${USERNAME}" \
-d "password=${PASSWORD}")
if [ $? -ne 0 ]; then
print_error "Failed to connect to Keycloak"
exit 1
fi
# Check for errors
if echo "$RESPONSE" | jq -e '.error' >/dev/null 2>&1; then
print_error "Authentication failed:"
echo "$RESPONSE" | jq '.error_description'
exit 1
fi
# Extract access token
ACCESS_TOKEN=$(echo "$RESPONSE" | jq -r '.access_token')
if [ "$ACCESS_TOKEN" == "null" ] || [ -z "$ACCESS_TOKEN" ]; then
print_error "Failed to get access token"
echo "$RESPONSE"
exit 1
fi
print_success "Successfully obtained access token"
echo ""
# Decode and display JWT
print_info "Decoding JWT token..."
echo ""
# Split token into header, payload, signature
IFS='.' read -ra TOKEN_PARTS <<< "$ACCESS_TOKEN"
# Decode header
HEADER=$(echo "${TOKEN_PARTS[0]}" | base64 -d 2>/dev/null || echo "${TOKEN_PARTS[0]}" | base64 -d -i 2>/dev/null)
echo "JWT Header:"
echo "$HEADER" | jq '.' 2>/dev/null || echo "$HEADER"
echo ""
# Decode payload
PAYLOAD=$(echo "${TOKEN_PARTS[1]}" | base64 -d 2>/dev/null || echo "${TOKEN_PARTS[1]}" | base64 -d -i 2>/dev/null)
echo "JWT Payload:"
echo "$PAYLOAD" | jq '.' 2>/dev/null || echo "$PAYLOAD"
echo ""
# Extract relevant claims
print_info "Checking for Temporal authorization claims..."
echo ""
# Check for permissions claim
PERMISSIONS=$(echo "$PAYLOAD" | jq -r '.permissions // empty' 2>/dev/null)
if [ ! -z "$PERMISSIONS" ] && [ "$PERMISSIONS" != "null" ]; then
print_success "Found 'permissions' claim"
echo "Permissions:"
echo "$PAYLOAD" | jq '.permissions'
echo ""
else
print_warning "No 'permissions' claim found in JWT"
echo "Temporal requires a 'permissions' array in the JWT token."
echo "Each permission should be in the format: 'namespace:role'"
echo ""
fi
# Check for groups claim
GROUPS=$(echo "$PAYLOAD" | jq -r '.groups // empty' 2>/dev/null)
if [ ! -z "$GROUPS" ] && [ "$GROUPS" != "null" ]; then
print_info "Found 'groups' claim:"
echo "$PAYLOAD" | jq '.groups'
echo ""
else
print_warning "No 'groups' claim found"
echo ""
fi
# Check for roles claim
ROLES=$(echo "$PAYLOAD" | jq -r '.roles // empty' 2>/dev/null)
if [ ! -z "$ROLES" ] && [ "$ROLES" != "null" ]; then
print_info "Found 'roles' claim:"
echo "$PAYLOAD" | jq '.roles'
echo ""
else
print_warning "No 'roles' claim found"
echo ""
fi
# Check token expiration
EXP=$(echo "$PAYLOAD" | jq -r '.exp // empty' 2>/dev/null)
if [ ! -z "$EXP" ]; then
CURRENT_TIME=$(date +%s)
TIME_LEFT=$((EXP - CURRENT_TIME))
if [ $TIME_LEFT -gt 0 ]; then
print_success "Token is valid (expires in $((TIME_LEFT / 60)) minutes)"
else
print_error "Token has expired!"
fi
echo ""
fi
# Check issuer
ISSUER=$(echo "$PAYLOAD" | jq -r '.iss // empty' 2>/dev/null)
if [ ! -z "$ISSUER" ]; then
print_info "Token issuer: $ISSUER"
echo ""
fi
# Verify JWKS endpoint is accessible
print_info "Verifying JWKS endpoint..."
JWKS_URL="${ISSUER}/protocol/openid-connect/certs"
JWKS_RESPONSE=$(curl -s "$JWKS_URL")
if echo "$JWKS_RESPONSE" | jq -e '.keys' >/dev/null 2>&1; then
KEY_COUNT=$(echo "$JWKS_RESPONSE" | jq '.keys | length')
print_success "JWKS endpoint accessible ($KEY_COUNT keys available)"
echo "JWKS URL: $JWKS_URL"
else
print_error "JWKS endpoint not accessible or invalid response"
echo "URL: $JWKS_URL"
echo "Response: $JWKS_RESPONSE"
fi
echo ""
# Test Temporal Server connection (optional)
read -p "Do you want to test connection to Temporal Server? (y/n): " TEST_TEMPORAL
if [ "$TEST_TEMPORAL" == "y" ]; then
read -p "Enter Temporal Server address (e.g., localhost:7233): " TEMPORAL_ADDR
print_info "Testing Temporal Server connection..."
# Try to list namespaces with the token
# Note: This requires grpcurl to be installed
if command -v grpcurl >/dev/null 2>&1; then
RESULT=$(grpcurl -plaintext \
-H "authorization: Bearer $ACCESS_TOKEN" \
-d '{"pageSize": 10}' \
"$TEMPORAL_ADDR" \
temporal.api.workflowservice.v1.WorkflowService/ListNamespaces 2>&1)
if echo "$RESULT" | grep -q "PermissionDenied"; then
print_warning "Server rejected request (PermissionDenied)"
echo "This likely means authorization is working but the user lacks permissions."
echo "Check that the 'permissions' claim in the JWT matches your Temporal namespaces."
elif echo "$RESULT" | grep -q "namespaces"; then
print_success "Successfully connected to Temporal Server!"
echo "User has access to namespaces."
else
print_error "Unexpected response from Temporal Server:"
echo "$RESULT"
fi
else
print_warning "grpcurl not installed, skipping Temporal Server test"
echo "Install grpcurl to test server connection: https://github.com/fullstorydev/grpcurl"
fi
fi
echo ""
# Summary
echo "=================================="
echo "Summary"
echo "=================================="
echo ""
if [ ! -z "$PERMISSIONS" ] && [ "$PERMISSIONS" != "null" ]; then
print_success "JWT token contains 'permissions' claim - ready for Temporal authorization!"
echo ""
echo "Next steps:"
echo "1. Verify the permissions match your Temporal namespace names"
echo "2. Deploy the custom Temporal server with authorization enabled"
echo "3. Test access with different user groups"
else
print_warning "JWT token does NOT contain 'permissions' claim"
echo ""
echo "Next steps:"
echo "1. Configure Keycloak protocol mapper to add 'permissions' claim"
echo "2. Map user groups/roles to permissions in format: 'namespace:role'"
echo "3. Re-run this test script to verify"
echo ""
echo "See: custom-server/example-keycloak-mapper.json for an example"
fi
echo ""
echo "=================================="
echo "Full JWT Token (for debugging):"
echo "=================================="
echo "$ACCESS_TOKEN"
echo ""