Appearance
Managed Identity Evaluation — Cortex XDR API Key
Status: Decided — managed identity not applicable Decision date: 2026-04-16 Decision owner: Rory Review cadence: Annual, or on any Cortex XDR auth model change SOC2 controls: CC6.1 Logical Access Security, CC6.3 Role-Based Access
Question
Can the stored Cortex XDR API key currently held in Azure Key Vault (cirius-openai-kv-prod) be replaced with an Azure managed identity so that no long-lived credential exists anywhere in the environment?
Verdict
No. Managed identity cannot replace the Cortex XDR API key.
This is a platform constraint of Cortex XDR, not a Cirius design choice.
Why Not — The Technical Reality
1. Managed identity is Azure-tenant-scoped
Azure managed identity is an Entra ID (Microsoft) OAuth 2.0 identity that is only honoured by Azure Resource Manager, Microsoft Graph, and downstream services that explicitly trust Entra tokens. It is Microsoft's identity fabric.
The access token a managed identity produces is a JWT issued by login.microsoftonline.com with an aud claim scoped to a specific Azure resource (Key Vault, Storage, Cosmos DB, etc.) or Graph. It has no meaning outside that ecosystem.
2. Cortex XDR is a Palo Alto SaaS outside Azure's trust boundary
Cortex XDR runs on Palo Alto Networks infrastructure (*.xdr.*.paloaltonetworks.com). The public_api/v1/* endpoints accept only Palo Alto's own API key scheme:
x-xdr-auth-id— numeric API key IDAuthorization— either the raw key (Standard) or HMAC-SHA256 ofkey + nonce + timestamp(Advanced)
There is no Entra federation, no SAML for the API surface, no OIDC exchange, and no "Bring Your Own Identity" workflow on the Cortex XDR public API as of this evaluation. The official Palo Alto SDK ships the same HMAC-over-API-key pattern that scripts/cortex-audit.py implements.
3. The key rotates by hand in the Cortex XDR console
New keys are created in Settings → Configurations → Integrations → API Keys and supersede old ones only on rotation. The action is manual, performed by an admin user in the Cortex tenant. It cannot be driven by an Azure identity.
What About Workload Identity Federation?
Workload Identity Federation (WIF) lets Entra ID accept an external OIDC provider's tokens and exchange them for Entra tokens. That still ends with an Entra token. It cannot produce a Cortex-XDR-compatible credential.
Cortex XDR would have to publish an OIDC-federated API for this to change. They have not.
Compensating Controls — What We Do Instead
Since the Cortex XDR API key is an unavoidable long-lived secret, it is managed under the standard long-lived-secret discipline:
| Control | Implementation |
|---|---|
| Storage | Azure Key Vault cirius-openai-kv-prod, CMK-encrypted, private endpoint, soft delete on |
| Access | RBAC — Key Vault Secrets User only, granted to: (a) github-deploy-main service principal for workflow OIDC, (b) the SecOps Container App managed identity for runtime reads. No broad Secret Reader assignments. |
| Rotation | Quarterly — calendar reminder on Rory's runbook. New key generated in Cortex console, stored to KV with new version, old version disabled after one workflow cycle confirms success. |
| Expiry monitoring | scripts/credential_expiry_agent.py (SECRETS-033) flags the KV entry 30/14/7 days before expiry if expires_on is set. Rotation SOP requires setting expires_on on each new version. |
| Auditing | Key Vault diagnostic logs → cirius-logging-law-central; 6-year archive. Any SecretGet on this secret from an identity other than github-deploy-main or the SecOps Container App managed identity fires a HIGH finding. |
| Principle-of-least-privilege | Cortex API key is Advanced role, scoped to the minimum endpoints cortex-audit.py actually calls: endpoints/get_endpoints, incidents/get_incidents, alerts/get_alerts, vulnerabilities/get_vulnerabilities. No write scopes granted. |
| Blast radius | One key across the weekly audit + CMDB upsert + (future) syslog CEF pull. Rotating does not require coordinating with human operators — only the KV version flips. |
Where Managed Identity Is Used at Cirius
For context, and so future readers don't re-ask this question for every integration, here is where managed identity does replace stored secrets in the Cirius environment:
| Integration | Identity type | Replaces |
|---|---|---|
SecOps Container App → PostgreSQL psql-secops-prod | System-assigned managed identity | Stored DB password |
SecOps Container App → Key Vault cirius-openai-kv-prod | System-assigned managed identity | KV access policy with stored SP credential |
| GitHub Actions → Azure ARM (terraform plan/apply) | OIDC federated credential on github-deploy-main SP | Stored SP client secret |
| GitHub Actions → AWS (SES, S3, Security Hub) | OIDC federated credential on IAM role | Stored AWS access key |
| Azure VMs → Key Vault / Storage | System-assigned managed identity on each VM | Stored service account creds |
Azure OpenAI (cirius-openai-prod) → clients | Entra auth where client supports it | Stored API key (where the client supports it; some still need the key) |
Anywhere an Azure identity is honoured, we use managed identity or federated credential. The Cortex XDR API key is one of the few places where the downstream service genuinely does not support it.
Re-evaluation Triggers
Revisit this decision if any of the following happens:
- Palo Alto publishes OIDC federation on the Cortex XDR public API.
- Cortex XDR introduces an Entra-backed service account model.
- Palo Alto releases an Azure-native integration with managed-identity auth (e.g., an Azure Marketplace offering that exchanges an Azure token for a Cortex session).
- We migrate off Cortex XDR entirely.
Until any of those happen, the compensating controls above are the full answer.
Related Documents
security/unavoidable-long-lived-secrets.md— inventory of secrets that cannot be eliminatedsecurity/graph-api-cert-auth-eval.md— parallel evaluation for Graph API app registrations (different answer — cert auth is available there)security/edr-cortex-xdr.md— Cortex XDR architecture and coveragecompliance/— SOC2 evidence surface for CC6.1 / CC6.3