Skip to content

[awf] Compiler lacks Anthropic WIF support — EngineAuthConfig and ClaudeEngine need extension #35937

Description

@lpcox

Summary

The gh-aw compiler does not support Anthropic Workload Identity Federation (WIF). Two code paths need updating so that Claude-engine workflows can authenticate via GitHub OIDC token exchange instead of requiring ANTHROPIC_API_KEY.

The firewall side is complete — PRs gh-aw-firewall#3979 and gh-aw-firewall#4012 added full Anthropic WIF support to the api-proxy sidecar. But the compiler never emits the env vars that the firewall consumes.

Gaps

1. EngineAuthConfig is Azure-only (pkg/workflow/engine.go:77)

type EngineAuthConfig struct {
    Type          string
    Audience      string
    AzureTenantID string
    AzureClientID string
    AzureScope    string
    AzureCloud    string
}

Missing fields for Anthropic WIF:

  • AnthropicFederationRuleID
  • AnthropicOrganizationID
  • AnthropicServiceAccountID
  • AnthropicWorkspaceID

Impact: parseEngineAuthConfig (line ~602) silently drops Anthropic frontmatter fields, and applyEngineAuthEnv (line ~628) never emits AWF_AUTH_ANTHROPIC_* env vars.

2. ClaudeEngine hardcodes ANTHROPIC_API_KEY (pkg/workflow/claude_engine.go:55,61)

func (e *ClaudeEngine) GetRequiredSecretNames(...) []string {
    return append([]string{"ANTHROPIC_API_KEY"}, ...)
}

func (e *ClaudeEngine) GetSecretValidationStep(...) GitHubActionStep {
    return BuildDefaultSecretValidationStep(..., []string{"ANTHROPIC_API_KEY"}, ...)
}

Impact: WIF-configured workflows fail the validate_multi_secret.sh ANTHROPIC_API_KEY step before the agent ever runs, since WIF intentionally has no static API key.

Proposed Solution

Extend EngineAuthConfig

Add Anthropic WIF fields alongside existing Azure fields:

type EngineAuthConfig struct {
    Type          string
    Audience      string
    Provider      string // "azure" or "anthropic"
    // Azure
    AzureTenantID string
    AzureClientID string
    AzureScope    string
    AzureCloud    string
    // Anthropic
    AnthropicFederationRuleID string
    AnthropicOrganizationID   string
    AnthropicServiceAccountID string
    AnthropicWorkspaceID      string
}

Wire through parseEngineAuthConfig / applyEngineAuthEnv

When Auth.Type == "github-oidc" and Auth.Provider == "anthropic", emit:

AWF_AUTH_ANTHROPIC_FEDERATION_RULE_ID
AWF_AUTH_ANTHROPIC_ORGANIZATION_ID
AWF_AUTH_ANTHROPIC_SERVICE_ACCOUNT_ID
AWF_AUTH_ANTHROPIC_WORKSPACE_ID
AWF_AUTH_TYPE=github-oidc
AWF_AUTH_PROVIDER=anthropic

These are the env vars the firewall's api-proxy already reads (added in PRs #3979 and #4012).

Branch ClaudeEngine on auth type

func (e *ClaudeEngine) GetRequiredSecretNames(workflowData *WorkflowData) []string {
    if workflowData.EngineConfig.Auth.Type == "github-oidc" &&
       workflowData.EngineConfig.Auth.Provider == "anthropic" {
        // WIF — no static key needed
        return collectCommonMCPSecrets(workflowData)
    }
    return append([]string{"ANTHROPIC_API_KEY"}, collectCommonMCPSecrets(workflowData)...)
}

Same pattern for GetSecretValidationStep — omit or relax the validation when WIF is configured.

Example workflow frontmatter (target state)

engine: claude
engine-auth:
  type: github-oidc
  provider: anthropic
  federation-rule-id: fr_01ABC
  organization-id: org_01XYZ
  service-account-id: sa_01DEF
  workspace-id: ws_01GHI

Related

Acceptance Criteria

  • EngineAuthConfig extended with Anthropic WIF fields
  • parseEngineAuthConfig parses provider: anthropic frontmatter fields
  • applyEngineAuthEnv emits AWF_AUTH_ANTHROPIC_* env vars
  • ClaudeEngine.GetRequiredSecretNames skips ANTHROPIC_API_KEY when WIF configured
  • ClaudeEngine.GetSecretValidationStep skips/relaxes validation when WIF configured
  • Integration test: Claude WIF workflow compiles without requiring ANTHROPIC_API_KEY secret

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions