T Techclick ← All lessons
Microsoft · Azure security · Lesson 5 of 10

Key Vault: the app uses identity, not a copied secret

pay-api’s connection string is in appsettings.json on the VM disk and in the Git repo. Someone screenshotted it into chat. The fix is not a longer password. Put the secret in kv-tc-lab and let the VM’s managed identity get it. Humans stop copying secrets. Rotate in the vault.

Updated 2026-08-18·18 min read·L2 primary·Quiz at end

After this page you can

The ticket

Repo leak. The SQL password is in plaintext. Junior “rotates” it by pasting a new string into appsettings and restarting IIS. Three other copies remain: a pipeline variable, a screenshot, last week’s backup VHD.

Quick interview answer

Key Vault holds secrets, keys, and certificates. The workload authenticates with a managed identity (system-assigned on pay-api, or user-assigned if several apps share it) — no client secret in config. Data plane: prefer Azure RBAC (e.g. Key Vault Secrets User) over the older access-policy model; do not mix both unless you enjoy debugging denials. Turn on soft-delete (recover a deleted secret/vault) and purge protection (block immediate purge). Control plane RBAC is who can touch the vault resource; data plane is who can read secret values.

Hero · no paste
VM managed identity fetching a secret from Key Vault
The VM is the identity. The secret never lives in the repo.
Lab data · dummy only

Tenant techclick-lab.in · MG tc-root / tc-landing / tc-workloads · subs sub-hub sub-spoke-app · hub VNet 10.40.0.0/16 · spoke 10.41.0.0/16 · Azure Firewall 10.40.0.4 · VPN GW public 203.0.113.50 · on-prem FortiGate WAN 203.0.113.10. Not a live tenant.

Mental model

WrongThis lab
Where the secret livesappsettings / Git / ticketkv-tc-lab secret pay-api-sql
How the app authenticatesCopied client secretSystem-assigned MI on pay-api
Who may Get the secretEveryone with VM loginMI → Secrets User (RBAC)
Delete accidentGone foreverSoft-delete + purge protection
Token, not a pasted password
pay-api VM system-assigned MI Entra token audience = vault kv-tc-lab Get pay-api-sql

No client-id/secret pair in the repo. Rotate the vault value; recycle the app.

How to choose

ChoiceUseSkip when
System-assigned MIOne VM / one app, this labYou need the same identity on many resources
User-assigned MISeveral compute share one identityYou want it to die with the VM
Vault RBACNew vaults — recommended modelA legacy vault still on access policies (migrate, don’t mix blindly)
https://portal.azure.com
Training mock · not live
HomeMicrosoft Entra IDVirtual networksAzure Firewall
Key vaults → kv-tc-lab → Access control (IAM)

Key Vault Secrets User

kv-tc-lab
Azure role-based access control
Key Vault Secrets User
Managed identity pay-api
On / On
MI + data-plane RBAC. Not a secret in appsettings. Training mock.

Runbook

  1. Side A — vault

    Create kv-tc-lab with Azure RBAC, soft-delete, purge protection. Put pay-api-sql in as a secret. Firewall the vault (private endpoint in the next lesson).

  2. Side B — identity

    Enable system-assigned MI on the pay-api VM. Grant that object Key Vault Secrets User on the vault (or the secret, if you scope tight).

  3. Side C — prove

    From the VM, token + GET secret. Delete the value from appsettings and Git history plan. Rotate the vault version. App still works.

az · dummy
az keyvault show -n kv-tc-lab --query "[properties.enableSoftDelete, properties.enablePurgeProtection, properties.enableRbacAuthorization]" -o tsv
# true
# true
# true

az vm identity show -g rg-spoke -n pay-api --query principalId -o tsv
# 33333333-3333-3333-3333-333333333333

az role assignment list --scope /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/rg-spoke/providers/Microsoft.KeyVault/vaults/kv-tc-lab -o table
# Principal                          Role
# 33333333-3333-3333-3333-333333333333  Key Vault Secrets User

Four failures

1 · Secret still in appsettings

Vault is decoration. Grep the disk and the repo.

2 · Access policy + RBAC both on

One allow, one deny, three opinions. Pick a model. Prefer RBAC on new vaults.

3 · Soft-delete off / purge protection off

Malware or a bad script purges the vault. You have no holdback.

4 · Human Owner can also Get secrets

Standing data-plane read for people. Use PIM / just-in-time, not Owner-as-reader.

How to prove it

Close only when

1) MI principal has data-plane read. 2) App retrieves the secret without a copied credential. 3) Soft-delete and purge protection are on. 4) The old string is gone from config.

Traps

SymptomLook at
403 from the vaultRBAC vs access-policy model, and control plane vs data plane
Works in portal, fails on VMYour user has access; the MI does not
Deleted secret “gone”Soft-delete recovery — unless you purged

Knowledge check

Judgment items. One best answer. Reasons send you back to the matching section.

Q1

pay-api should fetch kv-tc-lab secrets with…

Correct: b. MI, not a copied secret.
Q2

Soft-delete + purge protection exist so that…

Correct: b. Retention / anti-purge.
Q3

On a new vault, prefer…

Correct: a. Recommended model.
Q4

Portal Get works, VM Get fails. Likely?

Correct: a. Trap.
Q5

System-assigned MI dies when…

Correct: b. Lifecycle is the resource.
Q6

A secret in Git plus a vault copy means…

Correct: b. Failure 1.

Azure security class series: Shared + Entra · Landing zone · NSG vs Firewall vs WAF · Conditional Access · Key Vault + MI · Private Link · Defender + Sentinel · Hub-spoke · Identity path · Interview

Sources

Related: Azure session factory · Migration series.