Repro
On the RI Exchange page, selecting the Azure provider tab shows:
Failed to load Azure reservations: Internal server error
Exchange History is empty as a downstream symptom.
Root cause
internal/api/handler_ri_exchange.go ~line 181, buildAzureExchangeClient calls azidentity.NewDefaultAzureCredential(nil) directly, bypassing the project's per-subscription credential resolver (internal/credentials/resolver.go, internal/secrets/azure_resolver.go, OIDC/WIF). In Lambda there is no ambient Azure identity in the default chain, so credential construction or armreservations NextPage fails, ListExchangeableReservations/collectExchangeableReservations wraps it, and the handler returns 500. The subscription_id query param is effectively ignored for auth.
PR #906 only added AWS account scoping and did not touch the Azure path.
Expected behaviour
- When an Azure CloudAccount is registered for the requested subscription, the page loads the Active Convertible RIs table.
- When no Azure account is configured, the page shows a graceful empty state rather than an opaque 500 error banner.
Fix
Replace azidentity.NewDefaultAzureCredential with credentials.ResolveAzureTokenCredentialWithOpts, scoped to the subscription_id query param. Mirror the exact pattern used by scheduler.collectAzureForAccount and purchase/execution.go:resolveAzureProvider.
Repro
On the RI Exchange page, selecting the Azure provider tab shows:
Exchange History is empty as a downstream symptom.
Root cause
internal/api/handler_ri_exchange.go~line 181,buildAzureExchangeClientcallsazidentity.NewDefaultAzureCredential(nil)directly, bypassing the project's per-subscription credential resolver (internal/credentials/resolver.go,internal/secrets/azure_resolver.go, OIDC/WIF). In Lambda there is no ambient Azure identity in the default chain, so credential construction orarmreservationsNextPagefails,ListExchangeableReservations/collectExchangeableReservationswraps it, and the handler returns 500. Thesubscription_idquery param is effectively ignored for auth.PR #906 only added AWS account scoping and did not touch the Azure path.
Expected behaviour
Fix
Replace
azidentity.NewDefaultAzureCredentialwithcredentials.ResolveAzureTokenCredentialWithOpts, scoped to thesubscription_idquery param. Mirror the exact pattern used byscheduler.collectAzureForAccountandpurchase/execution.go:resolveAzureProvider.