Skip to content
Merged
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
36 changes: 36 additions & 0 deletions internal/oidc/azure_factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,39 @@ func TestNewSignerFromEnv_AzureHalfConfigured(t *testing.T) {
})
}
}

// ---------------------------------------------------------------------------
// #1464 -- Azure factory branch fully configured (both env vars set)
// ---------------------------------------------------------------------------

// TestNewSignerFromEnv_AzureFullyConfigured verifies that NewSignerFromEnv
// reaches NewAzureKeyVaultSigner's client-construction path when both Azure
// env vars are set. It overrides the package-level newAzureKeyVaultClient
// factory hook with a fake so the test never spawns the real
// azidentity.NewDefaultAzureCredential chain (az/pwsh, macOS keychain
// prompts) that made this branch untestable before #1464.
func TestNewSignerFromEnv_AzureFullyConfigured(t *testing.T) {
t.Setenv(envSourceCloud, "azure")
t.Setenv(envAWSSigningKeyID, "")
t.Setenv(envGCPKeyResource, "")

const wantVaultURL = "https://my-vault.vault.azure.net/"
t.Setenv(envAzureVaultURL, wantVaultURL)
t.Setenv(envAzureKeyName, "my-key")

key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)

var gotVaultURL string
origFactory := newAzureKeyVaultClient
newAzureKeyVaultClient = func(vaultURL string) (AzureKeyVaultClient, error) {
gotVaultURL = vaultURL
return &fakeAzureKeyVaultClient{key: &key.PublicKey}, nil
}
t.Cleanup(func() { newAzureKeyVaultClient = origFactory })

signer, err := NewSignerFromEnv(context.Background())
require.NoError(t, err)
require.NotNil(t, signer)
assert.Equal(t, wantVaultURL, gotVaultURL, "factory must receive the configured vault URL")
}
25 changes: 19 additions & 6 deletions internal/oidc/azure_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ type AzureKeyVaultSigner struct {
once sync.Once
}

// newAzureKeyVaultClient builds the real AzureKeyVaultClient using the
// standard azidentity default credential chain. It is a package-level var
// (rather than a call baked into NewAzureKeyVaultSigner) so tests can
// override it with a fake and exercise the fully-configured factory branch
// without spawning the live credential chain (az/pwsh, macOS keychain, etc).
var newAzureKeyVaultClient = func(vaultURL string) (AzureKeyVaultClient, error) {
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
return nil, fmt.Errorf("oidc: azure default credential: %w", err)
}
client, err := azkeys.NewClient(vaultURL, cred, nil)
if err != nil {
return nil, fmt.Errorf("oidc: azkeys client: %w", err)
}
return client, nil
}

// NewAzureKeyVaultSigner constructs a signer against a Key Vault using
// the standard azidentity default credential chain. vaultURL is the
// full vault URL (e.g. https://cudly-vault.vault.azure.net/); keyName
Expand All @@ -39,13 +56,9 @@ func NewAzureKeyVaultSigner(ctx context.Context, vaultURL, keyName string) (*Azu
if vaultURL == "" || keyName == "" {
return nil, fmt.Errorf("oidc: azure key vault signer requires vaultURL + keyName")
}
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
return nil, fmt.Errorf("oidc: azure default credential: %w", err)
}
client, err := azkeys.NewClient(vaultURL, cred, nil)
client, err := newAzureKeyVaultClient(vaultURL)
if err != nil {
return nil, fmt.Errorf("oidc: azkeys client: %w", err)
return nil, err
}
return NewAzureKeyVaultSignerFromClient(client, keyName, ""), nil
}
Expand Down
Loading