Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ inputs:
default: '20'

claude-api-key:
description: 'Anthropic Claude API key for security analysis'
required: true
description: 'Anthropic Claude API key for security analysis. Optional: if omitted, the action uses keyless / environment-based auth resolved by the Anthropic SDK and Claude CLI (e.g. Workload Identity Federation via ANTHROPIC_FEDERATION_RULE_ID / ANTHROPIC_ORGANIZATION_ID / ANTHROPIC_SERVICE_ACCOUNT_ID plus an OIDC identity token, or ANTHROPIC_AUTH_TOKEN). Set those in the calling workflow env when using keyless auth.'
required: false
default: ''

claude-model:
Expand Down Expand Up @@ -203,14 +203,14 @@ runs:
exit 0
fi

# Validate API key is provided
# Auth: a static ANTHROPIC_API_KEY is optional. If no key was provided,
# unset the (empty) variable so the Claude CLI and Anthropic SDK can
# resolve keyless credentials from the environment (e.g. Workload
# Identity Federation). An empty-but-set ANTHROPIC_API_KEY would
# otherwise take precedence over keyless auth and break it. Truly
# missing credentials are surfaced by the scan's own validation.
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "::error::ANTHROPIC_API_KEY is not set. Please provide the claude-api-key input to the action."
echo "Example usage:"
echo " - uses: anthropics/claude-code-security-reviewer@main"
echo " with:"
echo " claude-api-key: \$\{{ secrets.ANTHROPIC_API_KEY }}"
exit 1
unset ANTHROPIC_API_KEY
fi

# Set timeout
Expand Down
23 changes: 14 additions & 9 deletions claudecode/claude_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,21 @@ def __init__(self,
self.timeout_seconds = timeout_seconds or DEFAULT_TIMEOUT_SECONDS
self.max_retries = max_retries or DEFAULT_MAX_RETRIES

# Get API key from environment or parameter
# Resolve auth. An explicit key (arg or ANTHROPIC_API_KEY) is used
# directly. Otherwise, fall through to the SDK's own credential
# resolution rather than failing hard -- this enables keyless auth such
# as Workload Identity Federation (ANTHROPIC_FEDERATION_RULE_ID /
# ANTHROPIC_ORGANIZATION_ID / ANTHROPIC_SERVICE_ACCOUNT_ID plus an OIDC
# identity token) and ANTHROPIC_AUTH_TOKEN, all of which the Anthropic
# SDK auto-detects from the environment.
self.api_key = api_key or os.environ.get("ANTHROPIC_API_KEY")
if not self.api_key:
raise ValueError(
"No Anthropic API key found. Please set ANTHROPIC_API_KEY environment variable "
"or provide api_key parameter."
)

# Initialize Anthropic client
self.client = Anthropic(api_key=self.api_key)
if self.api_key:
self.client = Anthropic(api_key=self.api_key)
else:
# No static key -- let the SDK auto-detect credentials from the
# environment. It raises a clear authentication error at call time
# if nothing is configured.
self.client = Anthropic()
logger.info("Claude API client initialized successfully")

def validate_api_access(self) -> Tuple[bool, str]:
Expand Down
27 changes: 23 additions & 4 deletions claudecode/github_action_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,29 @@ def validate_claude_available(self) -> Tuple[bool, str]:
)

if result.returncode == 0:
# Also check if API key is configured
api_key = os.environ.get('ANTHROPIC_API_KEY', '')
if not api_key:
return False, "ANTHROPIC_API_KEY environment variable is not set"
# Accept either a static credential or keyless / environment-based
# auth (e.g. Workload Identity Federation, ANTHROPIC_AUTH_TOKEN),
# which the Claude CLI and Anthropic SDK resolve from the
# environment.
has_static_credential = bool(
os.environ.get('ANTHROPIC_API_KEY')
or os.environ.get('ANTHROPIC_AUTH_TOKEN')
)
has_wif = all(
os.environ.get(var)
for var in (
'ANTHROPIC_FEDERATION_RULE_ID',
'ANTHROPIC_ORGANIZATION_ID',
'ANTHROPIC_SERVICE_ACCOUNT_ID',
)
)
if not (has_static_credential or has_wif):
return False, (
"No Anthropic credentials configured. Set ANTHROPIC_API_KEY, "
"or configure Workload Identity Federation "
"(ANTHROPIC_FEDERATION_RULE_ID / ANTHROPIC_ORGANIZATION_ID / "
"ANTHROPIC_SERVICE_ACCOUNT_ID)."
)
return True, ""
else:
error_msg = f"Claude Code returned exit code {result.returncode}"
Expand Down