From 98087cfb84caa24b83a8e58988497faec58c5864 Mon Sep 17 00:00:00 2001
From: XB382376
Date: Mon, 9 Mar 2026 23:25:26 +0800
Subject: [PATCH 1/2] test(protocol): add comprehensive protocol conformance
test
---
open-agent-auth-integration-tests/pom.xml | 20 +-
.../scripts/diagnose-conformance-env.sh | 271 ++++++
.../scripts/run-conformance-tests.sh | 302 +++++++
.../JwksEndpointConformanceTest.java | 453 ++++++++++
.../conformance/OAuth2DcrConformanceTest.java | 620 +++++++++++++
.../conformance/OAuth2ParConformanceTest.java | 499 ++++++++++
.../OAuth2TokenEndpointConformanceTest.java | 437 +++++++++
.../OAuth2TokenExchangeConformanceTest.java | 756 ++++++++++++++++
.../OidcDiscoveryConformanceTest.java | 458 ++++++++++
.../OidcIdTokenConformanceTest.java | 534 +++++++++++
.../conformance/ProtocolConformanceTest.java | 92 ++
.../ProtocolConformanceTestCondition.java | 119 +++
...otocolInteroperabilityConformanceTest.java | 831 +++++++++++++++++
.../WimseWorkloadCredsConformanceTest.java | 852 ++++++++++++++++++
14 files changed, 6243 insertions(+), 1 deletion(-)
create mode 100755 open-agent-auth-integration-tests/scripts/diagnose-conformance-env.sh
create mode 100755 open-agent-auth-integration-tests/scripts/run-conformance-tests.sh
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/JwksEndpointConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/OAuth2DcrConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/OAuth2ParConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/OAuth2TokenEndpointConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/OAuth2TokenExchangeConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/OidcDiscoveryConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/OidcIdTokenConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/ProtocolConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/ProtocolConformanceTestCondition.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/ProtocolInteroperabilityConformanceTest.java
create mode 100644 open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/WimseWorkloadCredsConformanceTest.java
diff --git a/open-agent-auth-integration-tests/pom.xml b/open-agent-auth-integration-tests/pom.xml
index 2a53662..efaacd5 100644
--- a/open-agent-auth-integration-tests/pom.xml
+++ b/open-agent-auth-integration-tests/pom.xml
@@ -141,10 +141,11 @@
org.apache.maven.plugins
maven-surefire-plugin
-
+
**/*E2ETest.java
**/*IntegrationTest.java
+ **/*ConformanceTest.java
@@ -171,5 +172,22 @@
+
+
+ protocol-conformance
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ **/*ConformanceTest.java
+
+
+
+
+
+
\ No newline at end of file
diff --git a/open-agent-auth-integration-tests/scripts/diagnose-conformance-env.sh b/open-agent-auth-integration-tests/scripts/diagnose-conformance-env.sh
new file mode 100755
index 0000000..fd0a357
--- /dev/null
+++ b/open-agent-auth-integration-tests/scripts/diagnose-conformance-env.sh
@@ -0,0 +1,271 @@
+#!/bin/bash
+
+###############################################################################
+# Open Agent Auth - Protocol Conformance Environment Diagnostic Script
+#
+# This script checks if the environment is ready for protocol conformance testing.
+# It validates all required services and protocol endpoints are accessible.
+#
+# Usage: ./scripts/diagnose-conformance-env.sh
+#
+# Author: Open Agent Auth Team
+###############################################################################
+
+# Script directory
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+MAGENTA='\033[0;35m'
+CYAN='\033[0;36m'
+NC='\033[0m' # No Color
+
+echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}"
+echo -e "${CYAN}║ ║${NC}"
+echo -e "${CYAN}║ Protocol Conformance Environment Diagnostic Tool ║${NC}"
+echo -e "${CYAN}║ ║${NC}"
+echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}"
+echo ""
+
+TOTAL_CHECKS=7
+ALL_PASSED=true
+
+# Check 1: Java version
+echo -e "${BLUE}[Check 1/${TOTAL_CHECKS}] Java Version${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+
+JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2)
+echo -e " Java version: ${JAVA_VERSION}"
+
+if [[ "$JAVA_VERSION" == "17"* ]] || [[ "$JAVA_VERSION" == "21"* ]]; then
+ echo -e " ${GREEN}✓ Java version is compatible${NC}"
+else
+ echo -e " ${YELLOW}⚠ Java version may not be compatible (recommended: 17 or 21)${NC}"
+fi
+echo ""
+
+# Check 2: Maven
+echo -e "${BLUE}[Check 2/${TOTAL_CHECKS}] Maven Installation${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+
+if command -v mvn &> /dev/null; then
+ MVN_VERSION=$(mvn -version 2>&1 | head -n 1)
+ echo -e " ${GREEN}✓ Maven is installed${NC}"
+ echo -e " $MVN_VERSION"
+else
+ echo -e " ${RED}✗ Maven is not installed${NC}"
+ ALL_PASSED=false
+fi
+echo ""
+
+# Check 3: Required services (port listening)
+echo -e "${BLUE}[Check 3/${TOTAL_CHECKS}] Required Services (Port Listening)${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+
+REQUIRED_SERVICES=(
+ "8082:Agent IDP"
+ "8083:Agent User IDP"
+ "8084:AS User IDP"
+ "8085:Authorization Server"
+ "8086:Resource Server"
+)
+
+ALL_SERVICES_RUNNING=true
+for service_info in "${REQUIRED_SERVICES[@]}"; do
+ port=$(echo "$service_info" | cut -d: -f1)
+ name=$(echo "$service_info" | cut -d: -f2)
+
+ if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
+ echo -e " ${GREEN}✓ $name (port $port) - Running${NC}"
+ else
+ echo -e " ${RED}✗ $name (port $port) - Not running${NC}"
+ ALL_SERVICES_RUNNING=false
+ ALL_PASSED=false
+ fi
+done
+
+if [ "$ALL_SERVICES_RUNNING" = true ]; then
+ echo -e " ${GREEN}✓ All services are running${NC}"
+else
+ echo -e " ${RED}✗ Some services are not running${NC}"
+fi
+echo ""
+
+# Check 4: JWKS endpoints (health check)
+echo -e "${BLUE}[Check 4/${TOTAL_CHECKS}] JWKS Endpoints (Health Check)${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+
+JWKS_SERVICES=(
+ "8082:Agent IDP"
+ "8083:Agent User IDP"
+ "8084:AS User IDP"
+ "8085:Authorization Server"
+)
+
+ALL_JWKS_HEALTHY=true
+for service_info in "${JWKS_SERVICES[@]}"; do
+ port=$(echo "$service_info" | cut -d: -f1)
+ name=$(echo "$service_info" | cut -d: -f2)
+
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:$port/.well-known/jwks.json" 2>/dev/null || echo "000")
+
+ if [ "$HTTP_CODE" = "200" ]; then
+ echo -e " ${GREEN}✓ $name JWKS endpoint (HTTP $HTTP_CODE)${NC}"
+ else
+ echo -e " ${RED}✗ $name JWKS endpoint (HTTP $HTTP_CODE)${NC}"
+ ALL_JWKS_HEALTHY=false
+ ALL_PASSED=false
+ fi
+done
+
+if [ "$ALL_JWKS_HEALTHY" = true ]; then
+ echo -e " ${GREEN}✓ All JWKS endpoints are accessible${NC}"
+fi
+echo ""
+
+# Check 5: OAuth 2.0 protocol endpoints
+echo -e "${BLUE}[Check 5/${TOTAL_CHECKS}] OAuth 2.0 Protocol Endpoints${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+
+OAUTH_ENDPOINTS=(
+ "http://localhost:8085/.well-known/openid-configuration:OIDC Discovery"
+ "http://localhost:8085/.well-known/jwks.json:JWKS"
+)
+
+ALL_OAUTH_HEALTHY=true
+for endpoint_info in "${OAUTH_ENDPOINTS[@]}"; do
+ url=$(echo "$endpoint_info" | cut -d: -f1-3)
+ name=$(echo "$endpoint_info" | cut -d: -f4)
+
+ HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$url" 2>/dev/null || echo "000")
+
+ if [ "$HTTP_CODE" = "200" ]; then
+ echo -e " ${GREEN}✓ $name ($url) - HTTP $HTTP_CODE${NC}"
+ else
+ echo -e " ${RED}✗ $name ($url) - HTTP $HTTP_CODE${NC}"
+ ALL_OAUTH_HEALTHY=false
+ ALL_PASSED=false
+ fi
+done
+
+# Token endpoint requires POST, so we check with a simple POST
+TOKEN_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "http://localhost:8085/oauth2/token" 2>/dev/null || echo "000")
+if [ "$TOKEN_CODE" = "400" ] || [ "$TOKEN_CODE" = "401" ]; then
+ echo -e " ${GREEN}✓ Token Endpoint (http://localhost:8085/oauth2/token) - HTTP $TOKEN_CODE (expected error for empty request)${NC}"
+elif [ "$TOKEN_CODE" = "000" ]; then
+ echo -e " ${RED}✗ Token Endpoint (http://localhost:8085/oauth2/token) - Not reachable${NC}"
+ ALL_OAUTH_HEALTHY=false
+ ALL_PASSED=false
+else
+ echo -e " ${YELLOW}⚠ Token Endpoint (http://localhost:8085/oauth2/token) - HTTP $TOKEN_CODE${NC}"
+fi
+
+# PAR endpoint requires POST
+PAR_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST "http://localhost:8085/par" 2>/dev/null || echo "000")
+if [ "$PAR_CODE" = "400" ] || [ "$PAR_CODE" = "401" ]; then
+ echo -e " ${GREEN}✓ PAR Endpoint (http://localhost:8085/par) - HTTP $PAR_CODE (expected error for empty request)${NC}"
+elif [ "$PAR_CODE" = "000" ]; then
+ echo -e " ${RED}✗ PAR Endpoint (http://localhost:8085/par) - Not reachable${NC}"
+ ALL_OAUTH_HEALTHY=false
+ ALL_PASSED=false
+else
+ echo -e " ${YELLOW}⚠ PAR Endpoint (http://localhost:8085/par) - HTTP $PAR_CODE${NC}"
+fi
+
+if [ "$ALL_OAUTH_HEALTHY" = true ]; then
+ echo -e " ${GREEN}✓ All OAuth 2.0 protocol endpoints are accessible${NC}"
+fi
+echo ""
+
+# Check 6: Conformance test files
+echo -e "${BLUE}[Check 6/${TOTAL_CHECKS}] Conformance Test Files${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+
+CONFORMANCE_DIR="$PROJECT_ROOT/src/test/java/com/alibaba/openagentauth/integration/conformance"
+
+EXPECTED_FILES=(
+ "ProtocolConformanceTest.java"
+ "ProtocolConformanceTestCondition.java"
+ "OidcDiscoveryConformanceTest.java"
+ "OAuth2TokenEndpointConformanceTest.java"
+ "OAuth2ParConformanceTest.java"
+ "OAuth2DcrConformanceTest.java"
+ "JwksEndpointConformanceTest.java"
+ "OidcIdTokenConformanceTest.java"
+ "WimseWorkloadCredsConformanceTest.java"
+)
+
+ALL_FILES_EXIST=true
+for file in "${EXPECTED_FILES[@]}"; do
+ if [ -f "$CONFORMANCE_DIR/$file" ]; then
+ echo -e " ${GREEN}✓ $file${NC}"
+ else
+ echo -e " ${RED}✗ $file - Missing${NC}"
+ ALL_FILES_EXIST=false
+ ALL_PASSED=false
+ fi
+done
+
+if [ "$ALL_FILES_EXIST" = true ]; then
+ echo -e " ${GREEN}✓ All conformance test files exist${NC}"
+fi
+echo ""
+
+# Check 7: Maven profile
+echo -e "${BLUE}[Check 7/${TOTAL_CHECKS}] Maven Profile Configuration${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+
+POM_FILE="$PROJECT_ROOT/pom.xml"
+if grep -q "protocol-conformance" "$POM_FILE" 2>/dev/null; then
+ echo -e " ${GREEN}✓ protocol-conformance profile is configured in pom.xml${NC}"
+else
+ echo -e " ${RED}✗ protocol-conformance profile is missing from pom.xml${NC}"
+ ALL_PASSED=false
+fi
+
+if grep -q "ConformanceTest" "$POM_FILE" 2>/dev/null; then
+ echo -e " ${GREEN}✓ ConformanceTest pattern is included in surefire configuration${NC}"
+else
+ echo -e " ${RED}✗ ConformanceTest pattern is missing from surefire configuration${NC}"
+ ALL_PASSED=false
+fi
+echo ""
+
+# Summary
+echo -e "${BLUE}═════════════════════════════════════════════════════════════════${NC}"
+echo -e "${BLUE}Diagnostic Summary${NC}"
+echo -e "${BLUE}═════════════════════════════════════════════════════════════════${NC}"
+echo ""
+
+if [ "$ALL_PASSED" = true ]; then
+ echo -e "${GREEN}✓ Environment is ready for protocol conformance testing${NC}"
+ echo ""
+ echo -e "${CYAN}Next Steps:${NC}"
+ echo -e " Run conformance tests: ./scripts/run-conformance-tests.sh"
+ echo -e " Run with skip-services: ./scripts/run-conformance-tests.sh --skip-services --skip-build"
+else
+ echo -e "${RED}✗ Environment is not ready for protocol conformance testing${NC}"
+ echo ""
+ echo -e "${CYAN}Recommended Actions:${NC}"
+
+ if [ "$ALL_SERVICES_RUNNING" = false ]; then
+ echo -e " 1. Start all services: ../open-agent-auth-samples/scripts/sample-start.sh"
+ fi
+
+ if [ "$ALL_JWKS_HEALTHY" = false ] || [ "$ALL_OAUTH_HEALTHY" = false ]; then
+ echo -e " 2. Check service logs: ../open-agent-auth-samples/scripts/sample-logs.sh "
+ echo -e " 3. Restart services: ../open-agent-auth-samples/scripts/sample-restart.sh"
+ fi
+
+ if [ "$ALL_FILES_EXIST" = false ]; then
+ echo -e " 4. Ensure all conformance test files are present"
+ fi
+
+ echo -e " 5. Run diagnostics again: ./scripts/diagnose-conformance-env.sh"
+fi
+
+echo ""
diff --git a/open-agent-auth-integration-tests/scripts/run-conformance-tests.sh b/open-agent-auth-integration-tests/scripts/run-conformance-tests.sh
new file mode 100755
index 0000000..b3ad939
--- /dev/null
+++ b/open-agent-auth-integration-tests/scripts/run-conformance-tests.sh
@@ -0,0 +1,302 @@
+#!/bin/bash
+
+###############################################################################
+# Open Agent Auth - Protocol Conformance Test Runner Script
+#
+# This script orchestrates the protocol conformance testing flow:
+# 1. Build the project (optional)
+# 2. Restart all sample services
+# 3. Wait for services to be ready
+# 4. Run protocol conformance tests
+# 5. Display test results
+#
+# Usage: ./scripts/run-conformance-tests.sh [--debug] [--skip-build] [--skip-services] [--test-class ]
+# --debug: Start services in debug mode
+# --skip-build: Skip Maven build step
+# --skip-services: Skip service restart (use when services are already running)
+# --test-class: Run specific conformance test class
+#
+# Author: Open Agent Auth Team
+###############################################################################
+
+set -e # Exit on error
+set -o pipefail # Exit on pipe failure
+
+# Script directory
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+PROJECT_ROOT_DIR="$(cd "$PROJECT_ROOT/.." && pwd)"
+SAMPLES_SCRIPTS_DIR="$PROJECT_ROOT_DIR/open-agent-auth-samples/scripts"
+
+# Colors for output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+MAGENTA='\033[0;35m'
+CYAN='\033[0;36m'
+NC='\033[0m' # No Color
+
+# Default conformance test classes
+DEFAULT_TEST_CLASSES="OidcDiscoveryConformanceTest,OAuth2TokenEndpointConformanceTest,OAuth2ParConformanceTest,OAuth2DcrConformanceTest,JwksEndpointConformanceTest,OidcIdTokenConformanceTest,WimseWorkloadCredsConformanceTest,OAuth2TokenExchangeConformanceTest,ProtocolInteroperabilityConformanceTest"
+
+# Parse arguments
+DEBUG_MODE=false
+SKIP_BUILD=false
+SKIP_SERVICES=false
+TEST_CLASS="$DEFAULT_TEST_CLASSES"
+while [[ $# -gt 0 ]]; do
+ case $1 in
+ --debug)
+ DEBUG_MODE=true
+ shift
+ ;;
+ --skip-build)
+ SKIP_BUILD=true
+ shift
+ ;;
+ --skip-services)
+ SKIP_SERVICES=true
+ shift
+ ;;
+ --test-class)
+ TEST_CLASS="$2"
+ shift 2
+ ;;
+ *)
+ echo -e "${RED}Unknown option: $1${NC}"
+ echo ""
+ echo "Usage: $0 [--debug] [--skip-build] [--skip-services] [--test-class ]"
+ exit 1
+ ;;
+ esac
+done
+
+echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}"
+echo -e "${CYAN}║ ║${NC}"
+echo -e "${CYAN}║ Open Agent Auth - Protocol Conformance Test Runner ║${NC}"
+echo -e "${CYAN}║ ║${NC}"
+echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}"
+echo ""
+echo -e "${MAGENTA}Protocols under test:${NC}"
+echo -e " • OAuth 2.0 Token Endpoint (RFC 6749 §5)"
+echo -e " • OAuth 2.0 Token Exchange (RFC 8693)"
+echo -e " • OAuth 2.0 DCR (RFC 7591)"
+echo -e " • OAuth 2.0 PAR (RFC 9126)"
+echo -e " • OIDC Discovery (OpenID Connect Discovery 1.0)"
+echo -e " • OIDC ID Token (OpenID Connect Core 1.0 §2)"
+echo -e " • JWKS Endpoint (RFC 7517)"
+echo -e " • WIMSE WIT/WPT (draft-ietf-wimse-workload-creds)"
+echo -e " • Cross-Protocol Interoperability (DCR→PAR→Token, OIDC→JWKS, WIT→TokenExchange)"
+echo ""
+
+# Build arguments for restart script
+RESTART_ARGS=()
+if [ "$DEBUG_MODE" = true ]; then
+ RESTART_ARGS+=("--debug")
+fi
+if [ "$SKIP_BUILD" = true ]; then
+ RESTART_ARGS+=("--skip-build")
+fi
+RESTART_ARGS+=("--profile")
+RESTART_ARGS+=("mock-llm")
+
+# Determine total steps based on whether services are skipped
+if [ "$SKIP_SERVICES" = true ]; then
+ TOTAL_STEPS=3
+ STEP_OFFSET=0
+else
+ TOTAL_STEPS=5
+ STEP_OFFSET=0
+fi
+
+CURRENT_STEP=0
+
+next_step() {
+ CURRENT_STEP=$((CURRENT_STEP + 1))
+}
+
+# Step 1: Build the entire project
+next_step
+echo -e "${BLUE}[Step ${CURRENT_STEP}/${TOTAL_STEPS}] Building the entire project...${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+echo ""
+
+cd "$PROJECT_ROOT_DIR"
+
+if [ "$SKIP_BUILD" = false ]; then
+ if ! mvn clean install -DskipTests; then
+ echo -e "${RED}[ERROR] Failed to build project${NC}"
+ exit 1
+ fi
+else
+ echo -e "${YELLOW}[SKIP] Build step skipped${NC}"
+fi
+
+echo ""
+echo -e "${GREEN}✓ Project built successfully${NC}"
+echo ""
+
+if [ "$SKIP_SERVICES" = false ]; then
+ # Step 2: Restart all services
+ next_step
+ echo -e "${BLUE}[Step ${CURRENT_STEP}/${TOTAL_STEPS}] Restarting all sample services...${NC}"
+ echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+ echo ""
+
+ if ! "$SAMPLES_SCRIPTS_DIR/sample-restart.sh" "${RESTART_ARGS[@]}"; then
+ echo -e "${RED}[ERROR] Failed to restart services${NC}"
+ echo -e "${YELLOW}Check logs above for detailed error information${NC}"
+ exit 1
+ fi
+
+ echo ""
+ echo -e "${GREEN}✓ All services restarted successfully${NC}"
+ echo ""
+
+ # Step 3: Verify all services are healthy
+ next_step
+ echo -e "${BLUE}[Step ${CURRENT_STEP}/${TOTAL_STEPS}] Verifying service health...${NC}"
+ echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+ echo ""
+
+ REQUIRED_SERVICES=(
+ "8082:Agent IDP"
+ "8083:Agent User IDP"
+ "8084:AS User IDP"
+ "8085:Authorization Server"
+ "8086:Resource Server"
+ )
+
+ ALL_HEALTHY=true
+ for service_info in "${REQUIRED_SERVICES[@]}"; do
+ port=$(echo "$service_info" | cut -d: -f1)
+ name=$(echo "$service_info" | cut -d: -f2)
+
+ echo -ne "${YELLOW} Checking $name (port $port)...${NC} "
+
+ if curl -s -o /dev/null -w "%{http_code}" "http://localhost:$port/.well-known/jwks.json" 2>/dev/null | grep -q "200"; then
+ echo -e "${GREEN}✓ Healthy${NC}"
+ else
+ echo -e "${RED}✗ Unhealthy${NC}"
+ ALL_HEALTHY=false
+ fi
+ done
+
+ echo ""
+
+ if [ "$ALL_HEALTHY" = false ]; then
+ echo -e "${RED}[ERROR] Not all services are healthy${NC}"
+ echo -e "${YELLOW}Run diagnostic: $SCRIPT_DIR/diagnose-conformance-env.sh${NC}"
+ exit 1
+ fi
+
+ echo -e "${GREEN}✓ All services are healthy${NC}"
+ echo ""
+fi
+
+# Step: Display protocol endpoints
+next_step
+echo -e "${BLUE}[Step ${CURRENT_STEP}/${TOTAL_STEPS}] Protocol endpoints under test...${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+echo ""
+echo -e " ${CYAN}Authorization Server (8085):${NC}"
+echo -e " • Discovery: http://localhost:8085/.well-known/openid-configuration"
+echo -e " • JWKS: http://localhost:8085/.well-known/jwks.json"
+echo -e " • Token: http://localhost:8085/oauth2/token"
+echo -e " • PAR: http://localhost:8085/par"
+echo -e " • DCR: http://localhost:8085/oauth2/register"
+echo ""
+echo -e " ${CYAN}Identity Providers:${NC}"
+echo -e " • Agent IDP (8082): http://localhost:8082/.well-known/jwks.json"
+echo -e " • Agent User IDP (8083): http://localhost:8083/.well-known/jwks.json"
+echo -e " • AS User IDP (8084): http://localhost:8084/.well-known/jwks.json"
+echo ""
+
+# Step: Run conformance tests
+next_step
+echo -e "${BLUE}[Step ${CURRENT_STEP}/${TOTAL_STEPS}] Running protocol conformance tests...${NC}"
+echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}"
+echo ""
+
+cd "$PROJECT_ROOT"
+
+TEST_START_TIME=$(date +%s)
+
+echo -e "${YELLOW}Running: mvn test -P protocol-conformance -Dtest=\"$TEST_CLASS\" -DENABLE_INTEGRATION_TESTS=true${NC}"
+echo ""
+
+TEST_RESULTS=$(mvn test -P protocol-conformance -Dtest="$TEST_CLASS" -DENABLE_INTEGRATION_TESTS=true -Djacoco.skip=true 2>&1 | tee /dev/stderr)
+TEST_EXIT_CODE=$?
+
+TEST_END_TIME=$(date +%s)
+TEST_DURATION=$((TEST_END_TIME - TEST_START_TIME))
+
+echo ""
+echo ""
+
+# Display test results
+echo -e "${BLUE}═════════════════════════════════════════════════════════════════${NC}"
+echo -e "${BLUE}Protocol Conformance Test Results${NC}"
+echo -e "${BLUE}═════════════════════════════════════════════════════════════════${NC}"
+echo ""
+
+if [ $TEST_EXIT_CODE -eq 0 ]; then
+ echo -e "${GREEN}✓ All protocol conformance tests PASSED${NC}"
+else
+ echo -e "${RED}✗ Protocol conformance tests FAILED${NC}"
+fi
+
+echo ""
+echo -e "${CYAN}Test Duration: ${TEST_DURATION}s${NC}"
+echo ""
+
+# Parse and display test statistics
+echo -e "${CYAN}Test Statistics:${NC}"
+echo "$TEST_RESULTS" | grep -E "(Tests run:|Failures:|Errors:|Skipped:)" | sed 's/^/ /' || echo " Test statistics not available"
+
+echo ""
+echo -e "${CYAN}Protocols Validated:${NC}"
+echo -e " • OAuth 2.0 Token Endpoint (RFC 6749 §5)"
+echo -e " • OAuth 2.0 Token Exchange (RFC 8693)"
+echo -e " • OAuth 2.0 DCR (RFC 7591)"
+echo -e " • OAuth 2.0 PAR (RFC 9126)"
+echo -e " • OIDC Discovery (OpenID Connect Discovery 1.0)"
+echo -e " • OIDC ID Token (OpenID Connect Core 1.0 §2)"
+echo -e " • JWKS Endpoint (RFC 7517)"
+echo -e " • WIMSE WIT/WPT (draft-ietf-wimse-workload-creds)"
+echo -e " • Cross-Protocol Interop (DCR→PAR→Token, OIDC→JWKS, WIT→TokenExchange)"
+echo ""
+
+echo -e "${BLUE}═════════════════════════════════════════════════════════════════${NC}"
+echo ""
+
+# Final status
+if [ $TEST_EXIT_CODE -eq 0 ]; then
+ echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
+ echo -e "${GREEN}║ ║${NC}"
+ echo -e "${GREEN}║ Protocol Conformance Tests Completed Successfully! ✓ ║${NC}"
+ echo -e "${GREEN}║ ║${NC}"
+ echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
+ echo ""
+ echo -e "${CYAN}Next Steps:${NC}"
+ echo -e " - Review test output above for protocol compliance details"
+ echo -e " - Run E2E tests: $SCRIPT_DIR/run-e2e-tests.sh"
+ echo -e " - Stop services when done: $SAMPLES_SCRIPTS_DIR/sample-stop.sh"
+ echo ""
+else
+ echo -e "${RED}╔════════════════════════════════════════════════════════════════╗${NC}"
+ echo -e "${RED}║ ║${NC}"
+ echo -e "${RED}║ Protocol Conformance Tests Failed! ✗ ║${NC}"
+ echo -e "${RED}║ ║${NC}"
+ echo -e "${RED}╚════════════════════════════════════════════════════════════════╝${NC}"
+ echo ""
+ echo -e "${CYAN}Troubleshooting:${NC}"
+ echo -e " - Review test output above for specific protocol violations"
+ echo -e " - Run diagnostics: $SCRIPT_DIR/diagnose-conformance-env.sh"
+ echo -e " - Check service logs: $SAMPLES_SCRIPTS_DIR/sample-logs.sh "
+ echo -e " - Restart services: $SAMPLES_SCRIPTS_DIR/sample-restart.sh"
+ echo ""
+fi
+
+exit $TEST_EXIT_CODE
diff --git a/open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/JwksEndpointConformanceTest.java b/open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/JwksEndpointConformanceTest.java
new file mode 100644
index 0000000..7b04141
--- /dev/null
+++ b/open-agent-auth-integration-tests/src/test/java/com/alibaba/openagentauth/integration/conformance/JwksEndpointConformanceTest.java
@@ -0,0 +1,453 @@
+/*
+ * Copyright 2026 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.alibaba.openagentauth.integration.conformance;
+
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+import io.restassured.response.Response;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static io.restassured.RestAssured.given;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+/**
+ * Protocol conformance tests for JWKS (JSON Web Key Set) endpoint.
+ *
+ * This test class validates that the JWKS endpoints of various services conform to
+ * RFC 7517 (JSON Web Key (JWK)) specification, particularly Section 5 which defines
+ * the JWK Set (JWKS) JSON representation.
+ *
+ *
+ * Tests verify:
+ *
+ *
+ * - JWK Set format compliance per RFC 7517 §5
+ * - Required JWK fields (kty, kid) per RFC 7517 §4.1
+ * - RSA key parameter requirements (n, e)
+ * - Key algorithm and usage validation
+ * - Multi-service JWKS endpoint accessibility
+ * - Caching behavior for JWKS responses
+ * - Security: no private key material exposure
+ *
+ *
+ * Note: These tests require the following services to be running:
+ *
+ *
+ * - Authorization Server (localhost:8085)
+ * - Agent User IDP (localhost:8083)
+ * - AS User IDP (localhost:8084)
+ * - Agent IDP (localhost:8082)
+ *
+ *
+ * Use the provided scripts to start the services before running tests:
+ *
+ * cd open-agent-auth-samples
+ * ./scripts/sample-start.sh
+ *
+ *
+ *
+ * @see RFC 7517 - JSON Web Key (JWK)
+ * @see RFC 7517 §5 - JWK Set Format
+ * @see RFC 7517 §4 - JWK Parameters
+ * @since 1.0
+ */
+@ProtocolConformanceTest(
+ value = "JWKS Endpoint Conformance Tests",
+ protocol = "JWKS (RFC 7517)",
+ reference = "RFC 7517 §5, §4.1",
+ requiredServices = {"localhost:8082", "localhost:8083", "localhost:8084", "localhost:8085"}
+)
+@DisplayName("JWKS Endpoint Conformance Tests")
+class JwksEndpointConformanceTest {
+
+ private static final String AS_BASE_URI = "http://localhost:8085";
+ private static final String AGENT_USER_IDP_BASE_URI = "http://localhost:8083";
+ private static final String AS_USER_IDP_BASE_URI = "http://localhost:8084";
+ private static final String AGENT_IDP_BASE_URI = "http://localhost:8082";
+ private static final String JWKS_PATH = "/.well-known/jwks.json";
+
+ private static final Set PRIVATE_KEY_FIELDS = Set.of("d", "p", "q", "dp", "dq", "qi");
+ private static final Set VALID_KEY_TYPES = Set.of("RSA", "EC");
+ private static final Set VALID_KEY_USE = Set.of("sig", "enc");
+ private static final Set VALID_JWS_ALGORITHMS = Set.of(
+ "HS256", "HS384", "HS512",
+ "RS256", "RS384", "RS512",
+ "ES256", "ES384", "ES512",
+ "PS256", "PS384", "PS512",
+ "ES256K", "EdDSA"
+ );
+
+ @BeforeEach
+ void setUp() {
+ RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
+ }
+
+ @Nested
+ @DisplayName("JWK Set Format Tests - RFC 7517 §5")
+ class JwkSetFormatTests {
+
+ @Test
+ @DisplayName("AS JWKS endpoint should return JSON content type")
+ void asJwksEndpointShouldReturnJsonContentType() {
+ given()
+ .baseUri(AS_BASE_URI)
+ .when()
+ .get(JWKS_PATH)
+ .then()
+ .statusCode(200)
+ .contentType(ContentType.JSON);
+ }
+
+ @Test
+ @DisplayName("JWKS response must contain keys array field")
+ void jwksResponseMustContainKeysArrayField() {
+ given()
+ .baseUri(AS_BASE_URI)
+ .when()
+ .get(JWKS_PATH)
+ .then()
+ .statusCode(200)
+ .body("$", hasKey("keys"))
+ .body("keys", instanceOf(List.class));
+ }
+
+ @Test
+ @DisplayName("keys array must not be empty")
+ void keysArrayMustNotBeEmpty() {
+ Response response = given()
+ .baseUri(AS_BASE_URI)
+ .when()
+ .get(JWKS_PATH);
+
+ List