Skip to content

Federated identity credentials for managed identities - #154

Merged
oncicaradupopovici merged 4 commits into
mainfrom
feature/federated-identity-credentials
Oct 14, 2026
Merged

oncicaradupopovici merged 4 commits into
mainfrom
feature/federated-identity-credentials

Conversation

@oncicaradupopovici

@oncicaradupopovici oncicaradupopovici commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Lets Kubernetes workloads authenticate to Azure SQL as the managed identities that AzureDatabase / AzureManagedDatabase already provision, through AKS Workload Identity.

  • managedIdentities[].serviceAccounts ({name, namespace?}): for each ServiceAccount a federated identity credential is created on the (tenant-scoped) identity, with subject system:serviceaccount:<namespace>:<name> (namespace defaults to the CR's), audience api://AzureADTokenExchange and issuer AZURE_AKS_OIDC_ISSUER_URL.
    • Credential name <namespace>_<name> (dots in the name become -): _ is illegal in Kubernetes names, so distinct ServiceAccounts can't collide.
    • Credentials on one identity are created sequentially (Azure rejects concurrent writes with 409); the first waits for the identity through identity.Name.
    • Never retained on delete nor imported: they hold no state and are recreated from the spec, and a retained identity must not stay usable from the cluster. After a lost Pulumi state, PULUMI_IMPORT_ALL can't adopt existing credentials: delete them (az identity federated-credential delete) and the next reconcile recreates them (documented in the README).
    • Validated before any of the CR's resources is created: issuer set and an https:// URL, name/namespace present, valid and unique credential names, at most 20 per identity. Like other spec validation errors, a failure stops the reconcile of the whole tenant/domain stack.
    • The ServiceAccount is not created and needs no client-id annotation; workloads select the identity by the exported identityClientId.
  • Migration jobs: per-tenant clones now keep the template pod's azure.workload.identity/* labels and annotations (and nothing else), so the webhook injects tokens into migration pods. Templates without such keys produce the same clones as before.
  • Chart: AZURE_AKS_OIDC_ISSUER_URL from the optional azure-config key aksOidcIssuerUrl; clusters without the key are unchanged.
  • CRDs regenerated with controller-gen v0.22.0 (Makefile installs @latest), hence the version annotation change on every CRD.

Test plan

  • go test on all packages
  • New unit tests: credential inputs (issuer verbatim incl. trailing slash, subject, name, parent identity, audience), sequential order, not retained, dot sanitizing, namespace/name split collisions, validation cases (incl. non-https issuer), AzureDatabase + AzureManagedDatabase integration, migration clone metadata (fixture from a real template job)
  • Mutation checks: breaking ordering / retain / identity dependency / copying all labels makes the tests fail
  • helm template: only the new env lines differ; absent when Azure is disabled
  • Runtime: federated credential created in QA and a pod authenticating to SQL with it

🤖 Generated with Claude Code

oncicaradupopovici and others added 3 commits October 14, 2026 16:26
managedIdentities[].serviceAccounts creates, per ServiceAccount, a federated
identity credential on the identity trusting the AKS cluster's OIDC issuer
(AZURE_AKS_OIDC_ISSUER_URL), so workloads can authenticate as the identity
through AKS Workload Identity. Credentials are created sequentially, are never
retained on delete nor imported. Applies to AzureDatabase and
AzureManagedDatabase. CRDs regenerated with controller-gen v0.22.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Per-tenant migration jobs now copy the template pod's azure.workload.identity/*
labels and annotations, so the AKS Workload Identity webhook injects tokens into
their pods. Nothing else is copied: templates without such keys produce the same
clones as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The provisioner reads the AKS OIDC issuer from the optional azure-config key
aksOidcIssuerUrl; clusters without it are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fraliv13
fraliv13 previously approved these changes Oct 14, 2026
Federated credential names join namespace and ServiceAccount with '_' (illegal
in Kubernetes names) so distinct ServiceAccounts can't collide, and
AZURE_AKS_OIDC_ISSUER_URL must be an https URL. README documents the naming,
the manual recovery step after a lost Pulumi state (no import) and that an
invalid spec fails the whole stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oncicaradupopovici
oncicaradupopovici merged commit f60fee1 into main Oct 14, 2026
1 check passed
@oncicaradupopovici
oncicaradupopovici deleted the feature/federated-identity-credentials branch October 14, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants