Add workload identity federation support to base-action (#1378)

* Add workload identity federation support to base-action

Move the workload identity module into base-action so the standalone
action can fetch and refresh the GitHub OIDC identity token itself, and
expose the same federation inputs as the outer action. Switch the
base-action test workflows from the anthropic_api_key secret to the
federation repo variables and grant them id-token: write.

* Verify MCP test tool invocation instead of init connection status

MCP servers can connect asynchronously, so the init event may report a
server as pending. Check that the server is registered at init, then
assert the test tool was actually called and returned its response.
Also pass the MCP config through claude_args --mcp-config, replacing the
removed mcp_config input.
This commit is contained in:
Ashwin Bhat
2026-06-02 11:52:23 -07:00
committed by GitHub
parent 7f37f2e373
commit 420335da51
15 changed files with 250 additions and 126 deletions
+55 -25
View File
@@ -5,6 +5,13 @@ on:
workflow_dispatch:
workflow_call:
# The Claude API is authenticated via workload identity federation: id-token
# lets the action mint the GitHub OIDC token it exchanges for a short-lived
# access token. See docs/setup.md.
permissions:
contents: read
id-token: write
jobs:
test-mcp-integration:
runs-on: ubuntu-latest
@@ -25,8 +32,11 @@ jobs:
uses: ./base-action
id: claude-test
with:
prompt: "List all available tools"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "Call the test_tool tool and report its response."
anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }}
claude_args: --allowedTools mcp__test-server__test_tool
env:
# Change to test directory so it finds .mcp.json
CLAUDE_WORKING_DIR: ${{ github.workspace }}/base-action/test/mcp-test
@@ -50,21 +60,29 @@ jobs:
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers' "$OUTPUT_FILE" > /dev/null; then
echo "✓ Found mcp_servers in output"
# Check if test-server is connected
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers[] | select(.name == "test-server" and .status == "connected")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ test-server is connected"
# MCP servers can connect asynchronously, so the init event may
# report the server as pending — check registration there, then
# verify the tool actually ran.
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers[] | select(.name == "test-server")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ test-server is registered"
else
echo "✗ test-server not found or not connected"
echo "✗ test-server not found"
jq '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers' "$OUTPUT_FILE"
exit 1
fi
# Check if mcp tools are available
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .tools[] | select(. == "mcp__test-server__test_tool")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ MCP test tool found"
if jq -e '.[] | select(.type == "assistant") | .message.content[]? | select(.type == "tool_use" and .name == "mcp__test-server__test_tool")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ MCP test tool was called"
else
echo "✗ MCP test tool not found"
jq '.[] | select(.type == "system" and .subtype == "init") | .tools' "$OUTPUT_FILE"
echo "✗ MCP test tool was not called"
jq '[.[] | select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name]' "$OUTPUT_FILE"
exit 1
fi
if jq -e '.[] | select(.type == "user") | .message.content[]? | select(.type == "tool_result") | select(.content | tostring | contains("Test tool response"))' "$OUTPUT_FILE" > /dev/null; then
echo "✓ MCP test tool returned its response"
else
echo "✗ MCP test tool response not found"
exit 1
fi
else
@@ -106,9 +124,13 @@ jobs:
uses: ./base-action
id: claude-config-test
with:
prompt: "List all available tools"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
mcp_config: '{"mcpServers":{"test-server":{"type":"stdio","command":"bun","args":["simple-mcp-server.ts"],"env":{}}}}'
prompt: "Call the test_tool tool and report its response."
anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }}
claude_args: |
--allowedTools mcp__test-server__test_tool
--mcp-config '{"mcpServers":{"test-server":{"type":"stdio","command":"bun","args":["simple-mcp-server.ts"],"env":{}}}}'
env:
# Change to test directory so bun can find the MCP server script
CLAUDE_WORKING_DIR: ${{ github.workspace }}/base-action/test/mcp-test
@@ -132,21 +154,29 @@ jobs:
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers' "$OUTPUT_FILE" > /dev/null; then
echo "✓ Found mcp_servers in output"
# Check if test-server is connected
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers[] | select(.name == "test-server" and .status == "connected")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ test-server is connected"
# MCP servers can connect asynchronously, so the init event may
# report the server as pending — check registration there, then
# verify the tool actually ran.
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers[] | select(.name == "test-server")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ test-server is registered"
else
echo "✗ test-server not found or not connected"
echo "✗ test-server not found"
jq '.[] | select(.type == "system" and .subtype == "init") | .mcp_servers' "$OUTPUT_FILE"
exit 1
fi
# Check if mcp tools are available
if jq -e '.[] | select(.type == "system" and .subtype == "init") | .tools[] | select(. == "mcp__test-server__test_tool")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ MCP test tool found"
if jq -e '.[] | select(.type == "assistant") | .message.content[]? | select(.type == "tool_use" and .name == "mcp__test-server__test_tool")' "$OUTPUT_FILE" > /dev/null; then
echo "✓ MCP test tool was called"
else
echo "✗ MCP test tool not found"
jq '.[] | select(.type == "system" and .subtype == "init") | .tools' "$OUTPUT_FILE"
echo "✗ MCP test tool was not called"
jq '[.[] | select(.type == "assistant") | .message.content[]? | select(.type == "tool_use") | .name]' "$OUTPUT_FILE"
exit 1
fi
if jq -e '.[] | select(.type == "user") | .message.content[]? | select(.type == "tool_result") | select(.content | tostring | contains("Test tool response"))' "$OUTPUT_FILE" > /dev/null; then
echo "✓ MCP test tool returned its response"
else
echo "✗ MCP test tool response not found"
exit 1
fi
else