Automation

Microsoft Sentinel : valider un playbook de remédiation avant de l’autoriser en production

Un runbook de production pour borner un playbook Microsoft Sentinel entre déclencheur, entités, identité, dry run, approbation, traces, canari et rollback avant toute action de remédiation.

02 sept. 2026 azuremicrosoft-sentinellogic-appssecurityautomationmanaged-identityincident-responseobservabilityguardrailsrunbookrollbackproduction

Un incident Microsoft Sentinel contient une identité, une machine et une adresse IP considérées comme suspectes. Le playbook sait déjà enrichir l’incident et notifier l’équipe. L’étape suivante semble naturelle : désactiver le compte, isoler l’hôte ou bloquer l’IP automatiquement. C’est aussi le moment où une erreur de corrélation devient une action de production.

Le cas d’usage est un playbook Azure Logic Apps déclenché depuis une règle d’automatisation Sentinel. Il reçoit l’incident, qualifie ses entités, collecte des preuves puis transmet une remédiation à un outil autorisé. L’objectif n’est pas d’automatiser toute réponse de sécurité. Il est de décider si ce playbook précis peut rester en enrichissement, préparer une action, demander une approbation ou exécuter une remédiation bornée avec un rollback vérifiable.

Figer le contrat avant le workflow

Un playbook de remédiation ne doit pas déduire son périmètre à partir d’un titre d’incident ou d’un champ libre. Décrivez le déclencheur, les entités acceptées, les preuves minimales, l’action autorisée et le chemin de retour.

yaml sentinel-remediation-contract.yml
playbook: sentinel-contain-compromised-entity-prod
trigger:
type: microsoft_sentinel_incident
events: [created, updated]
automation_rule: ar-high-confidence-containment

accepted_entities:
- account_with_tenant_and_object_id
- host_with_stable_device_or_resource_id
- ip_with_observed_direction_and_window

required_evidence:
- incident_id
- analytics_rule_id
- alert_ids
- entity_identifiers
- first_seen_utc
- last_seen_utc
- source_product
- confidence_reason

execution_modes:
observe: enrich_and_comment
propose: build_action_without_state_change
enforce: execute_after_policy_and_approval

reject_when:
- entity_identifier_is_ambiguous
- incident_is_closed_or_test_data
- target_scope_is_not_production_approved
- same_action_is_already_running
- rollback_or_expiry_is_missing

Ce contrat sépare l’intention du connecteur. Un incident peut contenir plusieurs comptes portant le même nom, une IP partagée par un NAT ou un hostname réutilisé. Une action sensible doit partir d’un identifiant stable et d’un contexte, pas de la première chaîne qui ressemble à une entité.

Séparer le déclenchement de la décision

Une règle d’automatisation peut appeler un playbook lors de la création ou de la mise à jour d’un incident. Une mise à jour n’est pas toujours une nouvelle preuve : changement de propriétaire, ajout d’un commentaire ou retour du playbook peuvent eux-mêmes modifier l’incident. Sans garde, le workflow peut se rappeler ou appliquer deux fois la même action.

Construisez une clé d’idempotence avec l’incident, le type d’action, la cible stable et la version du contrat. Conservez-la avant toute écriture. Le playbook doit répondre « déjà traité » si une exécution réussie ou encore active possède la même clé.

text remediation-idempotency.txt
Idempotency key
incident_id + action_type + target_id + contract_version

Before state change
Reject missing or duplicate target identifiers
Read current target state
Check active execution with the same key
Record requested action and expiry

After state change
Record external operation ID
Record resulting target state
Add a bounded comment to the Sentinel incident
Never retrigger enforcement from that comment alone

Le déclencheur transporte l’incident. Il ne constitue pas la décision. Les conditions de la règle d’automatisation réduisent le bruit, tandis que le playbook revalide encore l’état, les entités et la politique juste avant l’action.

Prouver les identités qui interviennent

Trois niveaux de droits sont souvent confondus : l’opérateur qui configure la règle, le service Microsoft Sentinel autorisé à lancer le playbook, puis l’identité du workflow qui appelle Sentinel et les systèmes de remédiation. Les élargir ensemble rend l’audit illisible.

Microsoft Sentinel doit pouvoir exécuter les playbooks du resource group concerné. Le workflow, lui, doit utiliser une identité managée ou une connexion explicitement inventoriée, avec des droits limités aux actions prévues. Un playbook qui ajoute un commentaire à l’incident n’a pas besoin du même rôle qu’un connecteur qui désactive une identité ou isole un poste.

bash inventory-playbook-identities.sh
RG="rg-secops-automation-prod"
LOGIC_APP="la-sentinel-containment-prod"

# Adapter la commande au type Consumption ou Standard réellement déployé.
az resource show \
--resource-group "$RG" \
--name "$LOGIC_APP" \
--resource-type Microsoft.Logic/workflows \
--query "{id:id, identity:identity, state:properties.state}" \
--output json

PRINCIPAL_ID="<managed-identity-principal-id>"
az role assignment list \
--assignee "$PRINCIPAL_ID" \
--all \
--query "[].{role:roleDefinitionName, scope:scope}" \
--output table

La sortie attendue est une matrice lisible : identité, rôle, scope, connecteur et action. Refusez la promotion si un secret personnel, une connexion partagée ou un rôle au niveau subscription empêche d’attribuer précisément l’action.

Tester en mode observation puis proposition

Le premier test ne doit modifier ni compte, ni machine, ni règle réseau. Exécutez le playbook manuellement sur un incident de test réaliste et activez seulement l’enrichissement : lecture des alertes et entités, résolution des identifiants, commentaire, journal et calcul de la décision.

Le mode propose construit ensuite la charge utile exacte qui serait envoyée à l’outil de remédiation. Il vérifie schéma, cible, durée, motif, approbateur et rollback, mais remplace l’appel d’écriture par une trace.

json proposed-remediation.json
{
"incidentId": "inc-20260902-042",
"action": "temporary_containment",
"target": {
  "type": "host",
  "id": "stable-resource-or-device-id"
},
"reason": "high-confidence incident with two correlated alerts",
"requestedAtUtc": "2026-09-02T06:20:00Z",
"expiresAtUtc": "2026-09-02T08:20:00Z",
"approval": {
  "required": true,
  "status": "pending"
},
"rollback": {
  "action": "remove_temporary_containment",
  "owner": "secops-on-call"
},
"mode": "propose"
}

Testez au minimum une entité valide, une entité ambiguë, un incident fermé, une mise à jour répétée, une permission manquante, une dépendance indisponible et une réponse partielle. Le chemin d’erreur doit terminer en failed ou held, jamais en succès silencieux.

Lire les incidents et les exécutions sur la même fenêtre

La validation doit relier le signal Sentinel à l’historique Logic Apps et à l’outil cible. Dans Log Analytics, partez de l’incident et de ses alertes ; adaptez les tables et champs aux connecteurs réellement activés dans le workspace.

kusto sentinel-remediation-evidence.kql
let Window = 2h;
let TargetIncidentNumber = 42;
let Incident =
SecurityIncident
| where TimeGenerated > ago(Window)
| where IncidentNumber == TargetIncidentNumber
| summarize arg_max(TimeGenerated, *) by IncidentNumber
| project IncidentNumber, Title, Severity, Status, ProviderIncidentId,
        AlertIds, Owner, Labels, LastModifiedTime;
let Alerts =
SecurityAlert
| where TimeGenerated > ago(Window)
| project AlertTime=TimeGenerated, SystemAlertId, AlertName,
        AlertSeverity, ProductName, Entities, ExtendedProperties;
Incident
| mv-expand AlertId = AlertIds
| extend AlertId = tostring(AlertId)
| join kind=leftouter Alerts on $left.AlertId == $right.SystemAlertId
| project IncidentNumber, ProviderIncidentId, Title, Severity, Status,
        AlertTime, AlertName, AlertSeverity, ProductName, Entities
| order by AlertTime asc

Le résultat doit produire une chronologie unique : incident reçu, preuve lue, décision calculée, approbation, appel externe, état résultant et éventuel rollback.

Les diagnostics Logic Apps doivent conserver le run ID, la branche exécutée, le code de réponse et la durée sans journaliser de jeton, de secret ou de contenu sensible inutile. L’outil cible doit fournir son propre identifiant d’opération ; un run Logic Apps Succeeded ne prouve pas à lui seul que la cible est dans l’état attendu.

Canariser l’autorisation de production

Ne passez pas directement d’un incident de test à toutes les alertes critiques. Activez d’abord un canari identifiable : une analytics rule, un type d’entité, un environnement et une plage horaire d’astreinte. Gardez l’approbation humaine pour toute action qui change l’état.

yaml sentinel-playbook-promotion-gate.yml
promotion_gate:
automation_rule_scope:
  analytics_rules: [rule-approved-high-confidence]
  severities: [High]
  entity_types: [Host]
  environments: [production-canary]

require:
  - stable target identifier
  - two independent evidence signals
  - no duplicate execution
  - managed identity at bounded scope
  - approved action payload
  - target operation ID returned
  - post-action state verified
  - expiry or rollback scheduled

stop_when:
  - entity resolution is ambiguous
  - false-positive rate exceeds the agreed threshold
  - target API returns partial or unknown state
  - incident update causes a duplicate run
  - audit trail cannot join incident, run and target operation

Mesurez séparément la précision de sélection et la fiabilité d’exécution. Un playbook peut appeler parfaitement le mauvais hôte ; à l’inverse, une bonne décision peut échouer faute de permission. Ces deux risques ne se corrigent pas avec le même changement.

Décider, valider ou rollbacker

La promotion est acceptable lorsque le playbook rejette les entités ambiguës, reste idempotent, utilise une identité bornée, exige l’approbation prévue et prouve l’état final dans le système cible. Conservez une version du workflow et de la règle d’automatisation avec chaque décision.

Si le canari déclenche une action injustifiée ou perd sa traçabilité, désactivez d’abord l’étape d’exécution ou la règle d’automatisation, puis annulez les remédiations temporaires à partir des identifiants d’opération enregistrés. Ne supprimez pas les runs ni les commentaires qui permettent de reconstruire l’incident. Revenez au mode observe pendant la correction.

Conclusion

Un playbook Microsoft Sentinel n’est prêt pour la production que lorsque son déclencheur, sa décision et son action peuvent être expliqués séparément. Le contrat d’entité, l’idempotence, les identités, le mode proposition et la preuve côté cible comptent davantage qu’un workflow marqué Succeeded.

La décision finale est simple : rester en enrichissement, préparer une action avec approbation, ouvrir un canari borné ou revenir en observation. Tant que la cible, le droit utilisé ou le rollback ne sont pas prouvés, le playbook ne doit pas modifier la production.