Bot-Free Authentication in scan-plugins: How the Claude Plugins Community Action Handles Credentials

The scan-plugins composite action implements bot-free authentication by running a credential-free static analysis phase unconditionally while gating the AI-powered policy scan behind either ephemeral Workload Identity Federation (WIF) tokens or static API keys, skipping the policy scan entirely when no credentials are provided.

The scan-plugins GitHub Action in the anthropics/claude-plugins-community repository validates external plugin submissions through a carefully architected two-phase process. This design ensures bot-free authentication is maintained by strictly separating deterministic static checks—which require no credentials—from optional AI-driven scans that demand proper Anthropic authentication.

The Two-Phase Validation Architecture

The action is built to run two distinct phases with different security requirements:

  • Static "pin-check" (auth-free) – Runs unconditionally and only requires jq. It clones each changed external entry at its pinned SHA and inspects any .mcp.json launcher specifications. Because it never contacts Anthropic's API, it never requires credentials.

  • Claude policy scan (requires auth) – Only executed when the runner has either a static API key or a Workload Identity Federation (WIF) token.

The Auth-Free Static Pin Check

The static pin check operates completely without authentication. In .github/actions/scan-plugins/action.yml, the Static pin check step (lines 54-64) invokes scripts/static-pin-check.sh to perform deterministic validation.

This script clones each changed external entry at its pinned SHA and inspects any .mcp.json launcher specifications. Because this phase never contacts Anthropic's API, it produces JSON output without exposing any secrets to the runner.

Bot-Free Authentication Methods for Policy Scanning

When aiming to run the AI-powered policy scan, the action accepts two mutually exclusive authentication methods that determine how the Claude CLI authenticates with Anthropic's services.

Static API Key Authentication

The action accepts an anthropic-api-key input parameter that passes a classic secret API key directly to the Claude CLI. While functional, this method exposes a long-lived secret to the workflow runner.

Workload Identity Federation (WIF)

The preferred bot-free approach uses the anthropic-federation-rule-id input (a WIF rule ID formatted as fdrl_…). When this is set, the action mints a short-lived OIDC token and exchanges it for an Anthropic token, avoiding any static secret exposure.

According to the source code in action.yml (lines 66-78), the WIF flow creates a temporary file storing the OIDC JWT, continuously refreshes it, and injects the necessary environment variables for the Claude CLI:

  • ANTHROPIC_FEDERATION_RULE_ID
  • ANTHROPIC_ORGANIZATION_ID
  • ANTHROPIC_SERVICE_ACCOUNT_ID
  • ANTHROPIC_IDENTITY_TOKEN_FILE

Skip Logic and Conditional Execution

If neither anthropic-api-key nor anthropic-federation-rule-id is supplied, the policy scan is deliberately skipped. The "Skip if no Anthropic auth configured" step (lines 35-40 in action.yml) checks for the presence of credentials and aborts the policy scan if absent.

When authentication is present, the workflow proceeds to install the Claude CLI (lines 26-63) and then run the main scan (lines 65-81), passing the appropriate auth variables to the underlying scan.sh script.

In cases where the scan is skipped, the overall result is reported as skipped, but the auth-free pin check still produces its JSON output. This ensures that validation pipelines remain functional even without expensive AI credentials.

Key Implementation Files

The bot-free authentication model is implemented across three core files:

Complete Workflow Examples

Using Workload Identity Federation (Bot-Free)

This configuration uses ephemeral tokens rather than static secrets:

jobs:
  validate:
    runs-on: ubuntu-latest
    permissions:
      id-token: write   # required for WIF

    steps:
      - uses: actions/checkout@v4
      - name: Scan plugins
        uses: ./.github/actions/scan-plugins
        with:
          anthropic-federation-rule-id: ${{ secrets.ANTHROPIC_FEDERATION_RULE_ID }}
          anthropic-organization-id: ${{ secrets.ANTHROPIC_ORG_ID }}
          anthropic-service-account-id: ${{ secrets.ANTHROPIC_SVAC_ID }}
          fail-on-findings: true

Using Static API Key Authentication

For scenarios requiring classic authentication:

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Scan plugins
        uses: ./.github/actions/scan-plugins
        with:
          anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          fail-on-findings: true

Both configurations rely on the same underlying action; the decision to run the policy scan is made automatically based on which auth input is non-empty.

Summary

  • The static pin check runs unconditionally without any Anthropic credentials, providing deterministic validation of plugin manifests and pinned commits.
  • The Claude policy scan is strictly optional and requires either anthropic-api-key or anthropic-federation-rule-id.
  • Workload Identity Federation enables true bot-free authentication by minting short-lived OIDC tokens on-demand rather than exposing long-lived secrets.
  • Skip logic ensures graceful degradation when credentials are absent, reporting result=skipped while preserving the static check output.

Frequently Asked Questions

What happens if I don't provide any authentication to scan-plugins?

If neither anthropic-api-key nor anthropic-federation-rule-id is provided, the action skips the AI-powered policy scan entirely (as implemented in lines 35-40 of action.yml). The workflow reports result=skipped for the scan phase but continues to execute the auth-free static pin check, ensuring baseline validation still occurs.

How does Workload Identity Federation improve security over API keys?

Workload Identity Federation (WIF) eliminates long-lived secrets by minting short-lived OIDC tokens on-the-fly. According to the implementation in action.yml (lines 66-78), the action creates a temporary JWT file that continuously refreshes, injecting ephemeral credentials via environment variables rather than static API keys. This approach follows zero-trust principles and prevents credential leakage in CI logs.

Which validation steps run without any Anthropic credentials?

Only the static pin check operates without credentials. Located at lines 54-64 in action.yml and implemented in static-pin-check.sh, this phase clones repositories at their pinned SHA and validates .mcp.json launcher specifications using only jq. It requires no network access to Anthropic's API and serves as the auth-free safety net.

What files are inspected during the auth-free static pin check?

The static-pin-check.sh script inspects external plugin entries that have changed in the current commit, specifically examining the pinned SHA references and any .mcp.json launcher configuration files. This deterministic analysis validates the plugin structure without executing remote code or accessing Anthropic services.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →