Backend / Cloud: Azure / 03_key_vault_storage_and_identity.md

Key Vault, Storage and managed identity

Updated 6 interview angles 4 min read source
On this page5
  1. Managed identity first
  2. Key Vault
  3. Blob Storage
  4. Related
  5. Interview angle

Key Vault, Storage and managed identity

Config, secrets and blobs on Azure. The thread connecting all three is managed identity, which is the answer to almost every “where do the credentials live” question.

Managed identity first

A managed identity is an Entra ID principal attached to your compute. The platform issues short-lived tokens to it, so your app authenticates to Azure services without a stored secret.

python
from azure.identity.aio import DefaultAzureCredential
from azure.keyvault.secrets.aio import SecretClient

cred = DefaultAzureCredential()
client = SecretClient(VAULT_URL, cred)
secret = await client.get_secret("db-password")

DefaultAzureCredential tries a chain of sources: environment variables, then managed identity, then the Azure CLI login. That is what lets the same code run on your laptop under az login and in App Service under a managed identity, with no branching.

The chain is also the thing that confuses people in production. If an environment variable holds a stale service principal, it wins over the managed identity you intended, and the failure is a confusing permission error. Being explicit is better where it matters:

python
cred = ManagedIdentityCredential(client_id=UAMI_ID)

Two kinds exist: system-assigned (tied to one resource, deleted with it) and user-assigned (a standalone object several resources can share). Use user-assigned when more than one service needs the same permissions, or when you want the identity to outlive a redeploy.

Key Vault

Key Vault stores secrets, keys and certificates, with access controlled by Entra ID rather than a vault-specific password.

The design point worth stating: do not fetch secrets on every request. Key Vault is rate-limited and adds latency. Load at startup, or use the App Service reference syntax so the platform resolves it into an environment variable:

text
@Microsoft.KeyVault(SecretUri=
  https://v.vault.azure.net/secrets/db-pw/)

The app then reads an ordinary environment variable and never imports the SDK. Rotation still requires a restart or a slot swap unless you handle refresh explicitly, which is the tradeoff for the simplicity.

Access control comes in two models - the older access policies and Azure RBAC. Use RBAC: it is the same permission model as the rest of Azure, and access policies are the legacy path.

Blob Storage

Azure’s object store. The mapping to S3 is close enough that the concepts transfer, with different names:

Azure AWS
Storage account (no equivalent)
Container Bucket
Blob Object
SAS token Presigned URL

The storage account is the piece with no AWS analogue and it matters: it is the billing, throughput and redundancy boundary, and its name is globally unique. Throughput limits apply per account, so putting every workload in one account creates a shared bottleneck.

Redundancy is chosen at creation: LRS (one datacentre), ZRS (across zones), GRS (paired region). Changing it later is a migration, not a setting.

SAS tokens

A SAS token is a signed URL granting scoped, time-limited access, so a client uploads directly to storage rather than streaming through your API.

python
sas = generate_blob_sas(
    account_name=ACCOUNT,
    container_name="uploads",
    blob_name=name,
    permission=BlobSasPermissions(write=True),
    expiry=utcnow() + timedelta(minutes=15),
)

Prefer a user delegation SAS, signed with an Entra ID credential rather than the account key. An account-key SAS cannot be revoked without rotating the key itself, which invalidates every other SAS at the same time.

MinIO is S3-compatible, so a self-hosted or on-prem deployment usually targets the S3 API rather than the Azure one - worth knowing when a job description names both.

Interview angle 6

  • “How does your app authenticate to Azure services?” - a managed identity, an Entra ID principal attached to the compute, receiving short-lived platform-issued tokens. No credential is stored anywhere, which removes the secret that would otherwise need rotating.
  • “What does DefaultAzureCredential actually do?” - walks a chain: environment variables, managed identity, then CLI login. That is why the same code works locally and deployed, and also why a stale environment variable can silently outrank the managed identity in production.
  • “System-assigned or user-assigned identity?” - system-assigned is tied to one resource and deleted with it; user-assigned is standalone and shareable across resources, which is what you want when several services need the same permissions or the identity should survive a redeploy.
  • “How should an app read secrets from Key Vault?” - at startup, or through App Service Key Vault references so the platform resolves them into environment variables. Fetching per request adds latency and hits rate limits.
  • “What is a storage account and why does it matter?” - the billing, throughput and redundancy boundary, with a globally unique name and no direct AWS equivalent. Throughput caps apply per account, so consolidating unrelated workloads creates a shared bottleneck.
  • “How do you let a client upload a large file?” - a SAS token so the client writes to Blob Storage directly rather than through your API. Use a user delegation SAS signed by Entra ID, because an account-key SAS can only be revoked by rotating the key, which breaks every other token at once.