Cloud

Azure APIM : valider une rotation de Named Values avant de casser une API privée

Un runbook de production pour qualifier une rotation de secrets APIM avec Named Values, Key Vault, identité managée, backend privé, logs, validation applicative et rollback.

02 juil. 2026 azureapimapi-managementkey-vaultnamed-valuesmanaged-identityprivate-apiobservabilitykqlrunbookrollbacksecurityautomation

Une rotation de secret APIM paraît souvent simple : changer une valeur nommée, mettre à jour une référence Key Vault, renouveler une clé backend ou remplacer un certificat. En production, cette opération peut casser une API privée alors que le réseau, le backend et la policy APIM n’ont pas changé. Le symptôme arrive côté client sous forme de 401, 403, 500, 502 ou timeout, et l’équipe risque de partir trop vite sur le WAF, le Private Endpoint ou le code applicatif.

Le cas d’usage est une API exposée par Azure API Management interne, parfois derrière Application Gateway WAF, avec un backend privé Azure Function, App Service ou API interne. APIM utilise des Named Values pour injecter une clé, un header, une URL, un client secret ou une référence Key Vault dans les policies. Le runbook doit permettre de décider si la rotation peut être déployée, si l’identité APIM n’arrive plus à lire Key Vault, si la policy consomme l’ancienne valeur ou s’il faut rollbacker sans élargir le réseau ni désactiver les contrôles.

Cadrer ce qui tourne réellement

Commencez par décrire la rotation comme un changement de dépendance applicative, pas comme une simple mise à jour de secret. Une Named Value APIM peut être lue par plusieurs APIs, plusieurs policies et plusieurs environnements.

text apim-rotation-scope.txt
Rotation demandee
APIM: apim-prod-internal
API: orders-private-api
Named Value: backend-orders-api-key
Source: Key Vault reference ou valeur APIM protegee
Backend: https://func-orders-prod.azurewebsites.net/api
Chemin: client prive -> Application Gateway WAF -> APIM interne -> backend prive

Questions avant changement
Quelles APIs et policies lisent cette Named Value ?
La valeur est-elle stockee dans APIM ou referencee depuis Key Vault ?
Quelle identite APIM lit le secret ?
Le backend accepte-t-il l'ancienne et la nouvelle valeur pendant la fenetre ?
Quel test prouve que l'API fonctionne sans ouvrir le backend ?

Cette étape évite une erreur classique : corriger l’API privée alors que le problème est une dépendance de configuration partagée par plusieurs policies.

Inventorier les usages APIM

Avant rotation, identifiez toutes les policies qui référencent la Named Value. Le risque n’est pas seulement de casser l’API ciblée, mais de modifier un fragment réutilisé ailleurs.

bash 01-apim-named-value-inventory.sh
APIM_RG="rg-apim-prod"
APIM_NAME="apim-prod-internal"
NAMED_VALUE="backend-orders-api-key"

az apim nv show --resource-group "$APIM_RG" --service-name "$APIM_NAME" --named-value-id "$NAMED_VALUE" --query "{name:name,displayName:displayName,secret:secret,keyVault:keyVault,resourceId:id}" --output json

az apim api list --resource-group "$APIM_RG" --service-name "$APIM_NAME" --query "[].{name:name,path:path,apiRevision:apiRevision,isCurrent:isCurrent}" --output table

Complétez avec une recherche dans le dépôt de policies si elles sont versionnées. Une valeur nommée peut être appelée avec {{backend-orders-api-key}} dans une policy inbound, backend ou outbound, ou dans un fragment partagé.

bash 02-policy-reference-search.sh
rg "\{\{backend-orders-api-key\}\}" apim/policies apim/fragments infrastructure || true
rg "set-header|set-query-parameter|set-backend-service|authentication-managed-identity" apim/policies || true

Si les policies ne sont pas versionnées, la rotation doit rester plus prudente : exporter l’état APIM avant changement et documenter le rollback exact.

Vérifier l’identité qui lit Key Vault

Quand la Named Value pointe vers Key Vault, l’échec peut venir de la valeur elle-même, du secret versionné, du réseau Key Vault ou de l’identité managée APIM. Ne modifiez pas la policy tant que ce chemin n’est pas qualifié.

bash 03-key-vault-reference-check.sh
APIM_RG="rg-apim-prod"
APIM_NAME="apim-prod-internal"
KV_NAME="kv-prod-shared"
SECRET_NAME="backend-orders-api-key"

az apim show --resource-group "$APIM_RG" --name "$APIM_NAME" --query "{name:name,identity:identity}" --output json

az keyvault secret show --vault-name "$KV_NAME" --name "$SECRET_NAME" --query "{id:id,enabled:attributes.enabled,expires:attributes.expires,updated:attributes.updated,contentType:contentType}" --output json

az keyvault show --name "$KV_NAME" --query "{name:name,networkAcls:properties.networkAcls,publicNetworkAccess:properties.publicNetworkAccess}" --output json

Si Key Vault est privé, validez aussi la résolution DNS et le chemin réseau depuis la perspective APIM lorsque l’architecture le permet. Une rotation de secret ne doit pas devenir une ouverture publique temporaire de Key Vault.

Lire les logs comme une chaîne de preuves

Les erreurs APIM doivent être reliées à une requête, une policy, un backend et une période de changement. Les codes HTTP seuls ne suffisent pas.

kusto 04-apim-rotation-evidence.kql
let ApiName = "orders-private-api";
let WindowStart = ago(2h);
ApiManagementGatewayLogs
| where TimeGenerated > WindowStart
| where ApiId has ApiName or OperationId has ApiName
| project TimeGenerated,
        RequestId,
        ApiId,
        OperationId,
        Method,
        Url,
        ResponseCode,
        BackendResponseCode,
        LastErrorReason,
        LastErrorMessage,
        BackendUrl,
        CallerIpAddress
| order by TimeGenerated desc

Ajoutez les événements Key Vault si la valeur est référencée par secret.

kusto 05-key-vault-secret-access.kql
let SecretName = "backend-orders-api-key";
let WindowStart = ago(2h);
AzureDiagnostics
| where TimeGenerated > WindowStart
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName has "SecretGet"
| where id_s has SecretName or requestUri_s has SecretName
| project TimeGenerated,
        OperationName,
        ResultType,
        ResultSignature,
        identity_claim_appid_g,
        identity_claim_oid_g,
        CallerIPAddress,
        requestUri_s
| order by TimeGenerated desc

L’objectif est de prouver si APIM lit bien le secret, si Key Vault refuse l’accès, si APIM exécute une policy avec une valeur absente ou si le backend rejette la nouvelle valeur.

Préparer une rotation compatible production

La rotation la plus robuste évite le basculement brutal. Lorsque le backend le permet, gardez une fenêtre où ancienne et nouvelle valeurs sont acceptées. Sinon, préparez un rollback APIM explicite et un test backend immédiat.

yaml apim-secret-rotation-guardrails.yml
before_rotation:
- export_apim_named_value_and_policy_state
- verify_named_value_references
- verify_apim_managed_identity_can_read_key_vault
- verify_backend_accepts_new_secret_or_has_rollback_window
- run_private_api_probe_before_change

block_rotation_when:
- named_value_used_by_unknown_policy
- key_vault_secret_disabled_or_expired
- apim_identity_not_visible_in_key_vault_logs
- backend_has_no_validation_endpoint
- rollback_value_not_captured

after_rotation:
- force_policy_refresh_or_wait_for_expected_cache_window
- run_private_api_probe_from_client_network
- compare_apim_gateway_logs_before_after
- confirm_key_vault_secret_get_success
- attach_evidence_to_change_ticket

Le point important est la preuve de consommation. Mettre à jour Key Vault ne prouve pas qu’APIM consomme la bonne version au bon moment.

Valider depuis le chemin privé

La validation doit partir d’un client représentatif : subnet applicatif, runner privé, probe synthétique ou poste d’exploitation qui utilise le même chemin privé que les consommateurs.

bash 06-private-api-probe.sh
APIM_HOST="api.internal.example"
API_PATH="/orders/health"
CORRELATION_ID="rotation-$(date +%Y%m%d%H%M%S)"

curl -sS -o /tmp/apim-health.out -w "%{http_code}\n" "https://$APIM_HOST$API_PATH" -H "x-correlation-id: $CORRELATION_ID" -H "Accept: application/json"

echo "correlation_id=$CORRELATION_ID"
cat /tmp/apim-health.out

Ensuite, recherchez le même identifiant dans les logs APIM et backend. Une validation réussie doit montrer le passage par APIM, la policy attendue, le backend privé et une réponse applicative cohérente.

Décider : déployer, corriger ou rollbacker

La décision doit rester opérationnelle. Ne mélangez pas secret, policy, réseau et backend dans une seule correction.

text apim-rotation-decision.txt
Deployer
La Named Value cible est identifiee
Les policies consommatrices sont connues
APIM lit Key Vault avec son identite managée
Le backend accepte la nouvelle valeur
La probe privee reussit et les logs confirment le chemin

Corriger avant rotation
La Named Value est partagee par une API non prevue
Key Vault refuse l'identite APIM
La policy lit une valeur differente de celle documentee
Le backend renvoie 401 ou 403 avec la nouvelle valeur

Rollbacker
Les erreurs APIM augmentent apres rotation
La lecture Key Vault echoue ou devient intermittente
Le backend prive n'accepte pas la nouvelle valeur
La valeur precedente est connue et retestable
Le retour arriere peut etre valide depuis le meme chemin prive

Le rollback n’est pas seulement remettre une ancienne valeur. Il doit prouver que l’API privée répond de nouveau, que Key Vault n’est plus en erreur et que les logs APIM retrouvent le comportement attendu.

Conclusion

Une rotation de secret APIM est un changement de production complet : Named Value, policy, identité managée, Key Vault, backend privé, logs et client réel. La traiter comme une simple mise à jour de configuration pousse les équipes vers de mauvais diagnostics réseau ou des exceptions trop larges.

La bonne décision est simple : déployer quand la chaîne de consommation est prouvée, corriger quand l’écart est localisé, rollbacker quand la valeur ou l’identité n’est plus maîtrisée. C’est ce qui permet de faire tourner les secrets sans transformer une API privée en incident APIM opaque.