Azure Container Apps hides the Kubernetes control plane, but it does not hide the identity, network and secret decisions that decide whether a container app is safe. Every app can hold managed identities, Key Vault references and plain-text secrets, every environment sits on a network you choose once and cannot change, and several built-in roles quietly allow anyone holding them to read secret values. This guide covers how identity and access work in Container Apps, which roles are privileged, how managed identities and secrets should be wired, what to log, and a hardening baseline with the misconfigurations that recur. It is written for cloud engineers and security architects running workloads on Azure. For the wider platform, see the Azure Security Checklist.
This is an independent guide from NHI Mgmt Group, based on Microsoft's public documentation as of November 2026. It is not sponsored or reviewed by Microsoft. Product features change, so confirm settings against Microsoft's current documentation.
Key takeaways
- Contributor-style roles can read every secret. Microsoft documents that the
listSecretsaction returns secret values in plain text and that Container Apps Contributor, Container Apps Operator and the Jobs roles include it through wildcard actions. - Starting a job is a secret read. A user with
Microsoft.App/jobs/start/actioncan override the job's image and command and read any secret or identity the job holds. - Managed identities should be scoped by lifecycle. The
identitySettingslifecycle valuesInit,Main,AllandNonekeep an image-pull or Key Vault identity out of reach of application code. - The network choice is permanent. Environment network type cannot change after creation, so internal, VNet-integrated workload profile environments must be chosen up front for anything sensitive.
- Built-in authentication defaults are broad. Any user in your Entra tenant can get a token for an app until you restrict the app registration, and ingress IP restrictions allow everything until the first rule is added.
How identity and access work in Azure Container Apps
Three separate identity planes meet in a container app, and confusing them is the root of most mistakes.
| Plane | Who or what authenticates | Mechanism | Where it is controlled |
|---|---|---|---|
| Control plane | Engineers and pipelines managing apps, environments and jobs | Azure RBAC on Microsoft.App resources | Role assignments at subscription, resource group or resource scope |
| Workload identity | The app calling Azure services (Key Vault, Storage, ACR, queues) | System-assigned or user-assigned managed identity | identity block, identitySettings, RBAC on the target service |
| Inbound callers | Users and clients calling the app | Built-in authentication sidecar, client certificates, IP restrictions, or app code | Ingress configuration and the Entra app registration |
Inbound authentication
- Built-in authentication: a middleware sidecar on each replica handles sign-in with Microsoft Entra ID, Facebook, GitHub, Google, X or any OpenID Connect provider, then injects identity headers such as
X-MS-CLIENT-PRINCIPAL-NAMEandX-MS-CLIENT-PRINCIPAL-ID. Microsoft states that external requests cannot set these headers, so the app can trust them when the sidecar is in front. - Restrict access setting: "Require authentication" rejects unauthenticated requests (browsers redirect to
/.auth/login/<provider>, API clients get HTTP 401); "Allow unauthenticated access" defers the decision to your code. The second option is a frequent cause of open endpoints. - Tenant-wide by default: Microsoft notes that any user in your Entra tenant can obtain a token for the app by default. Set "assignment required" on the enterprise application and assign groups, or check roles in claims. See the Azure RBAC and Service Principals Guide.
- Client certificates:
clientCertificateModetakesrequire,acceptorignore. Inrequireoracceptmode the certificate is passed to the app inX-Forwarded-Client-Cert(hash, PEM certificate and chain). Microsoft's guidance is that your code parses and validates it; the presence of a certificate is not proof of trust. - IP restrictions: rules are IPv4 CIDR ranges, all of one type (allow or deny, never mixed). With no rules, all inbound traffic is allowed.
Admin roles and privileged access
Microsoft's secrets documentation is unusually direct: the listSecrets action returns values in plain text, and several built-in roles grant it through wildcard actions even though their names suggest narrower rights.
| Role or permission | What it can reach | Treat as |
|---|---|---|
Container Apps Contributor, Container Apps Operator (Microsoft.App/containerApps/*/action) | App secrets via listSecrets | Secret reader for every app in scope |
Container Apps Jobs Contributor, Jobs Operator (Microsoft.App/jobs/*/action) | Job secrets; jobs/start/action can override image, command and environment | Secret reader and identity user for the job |
| Container Apps ManagedEnvironments Contributor, ConnectedEnvironments Contributor | Dapr component secrets | Secret reader for the environment |
| Anyone who can update the app template | Can deploy an image that reads mounted secrets and requests tokens for every identity with lifecycle Main or All | Equivalent to the app's managed identities |
| AcrPull on the registry | Image pull only (Microsoft.ContainerRegistry/registries/pull/read) | Low privilege, correct for the pull identity |
- Custom roles for operators: Microsoft recommends custom roles that list specific actions, omit
listSecretsand avoid wildcards. Give on-call staff restart and revision actions without secret read. - Scope carefully: an assignment at resource group or subscription scope applies to every app and job inside it. Separate sensitive apps into their own resource groups.
- Privileged access for humans: use Privileged Identity Management or equivalent just-in-time elevation for Contributor-level roles, and keep deployment rights with pipelines, not people.
This pattern of a role that looks safe but reaches secret values is not unique to Container Apps, so review any role that can change access settings on a secret store as if it could read the secrets.
Integrations, API tokens and service accounts
Managed identities
- System-assigned: one per app, deleted with the app (and removed from Entra ID when you remove it). Best when the identity serves only that app.
- User-assigned: standalone, shareable and survives the app. Needed when an identity must exist before the app (for example, to pull the first image) or be shared. Code must specify its client ID. Sharing one user-assigned identity across many apps widens blast radius, so share only within one trust boundary.
- Lifecycle scoping: from API version
2024-02-02-preview,identitySettingssets each identity's lifecycle. UseNonefor identities used only by the platform (ACR pull, scale rules, Key Vault references), so application code cannot request tokens for them;Initfor bootstrap-only identities (workload profile consumption environments only); andMainfor the application's own identity. - Scale rules: KEDA scale rules can authenticate with the
identityproperty instead of a connection string inauth. Prefer it: it removes a storage or Service Bus key from your secret list. - Token caching: the identity back end caches tokens per resource for about 24 hours and forced refresh is not supported, so revoking an RBAC assignment may take up to a day to bite. Plan incident containment accordingly (remove the identity or stop the app, not just the role). See the Azure Managed Identities Security Guide.
Secrets
| Option | How it works | When to use |
|---|---|---|
| Container Apps secret (inline value) | Name and value stored on the app | Development only; readable by any role with listSecrets |
| Key Vault reference, versioned URI | Managed identity with Key Vault Secrets User reads a pinned version | Production where rollouts must be controlled |
| Key Vault reference, unversioned URI | Picks up new versions within about 30 minutes; revisions using it as an environment variable restart automatically | Production with automated rotation |
| Managed identity, no secret | App requests Entra tokens for the target service | Best option wherever the target supports Entra authentication |
- Delivery: secrets reach containers as environment variables (
secretRef) or as files on a secret volume. Files are easier to keep out of crash dumps and debug output than environment variables. - Change behaviour: secrets are app-level and changing them does not create a revision; existing revisions keep the old value until restarted or replaced. Rotation runbooks must include the restart.
- Firewalled egress: with a UDR through Azure Firewall, allow the
AzureKeyVaultservice tag andlogin.microsoft.com, or Key Vault references fail.
See the Azure Key Vault Security Guide and the Secrets Management Guide.
Logging and detection
Container Apps offers three log destinations per environment: Azure Log Analytics (the default, CLI value log-analytics), Azure Monitor diagnostic settings (azure-monitor, up to five settings per environment) and "Don't save logs" (none, live log stream only). Microsoft notes that sending logs directly to a Log Analytics workspace over Private Link is not supported; use Azure Monitor diagnostic settings to the same workspace instead. The two log categories are ContainerAppConsoleLogs (stdout and stderr) and ContainerAppSystemLogs (platform events).
| Signal | Source | Why it matters |
|---|---|---|
listSecrets calls on apps and jobs | Azure Activity Log | Secret reads by humans are rare and should alert |
jobs/start with template overrides | Activity Log | Possible secret or identity abuse through a one-off execution |
Changes to ingress (external, allowInsecure, IP rules, client certificate mode) and auth settings | Activity Log | Exposure changes |
New or changed identity assignments and identitySettings | Activity Log | Privilege added to a workload |
| Revision created with a new image or registry | ContainerAppSystemLogs, Activity Log | Unapproved image deployment |
| Managed identity sign-ins to unusual resources | Entra managed identity sign-in logs | Stolen token use (ATT&CK T1078.004 Cloud Accounts) |
Do not log secrets: review application logging so Key Vault values and tokens never reach ContainerAppConsoleLogs. See the Azure Monitor, Activity Log and Diagnostic Settings Guide.
Metrics
- Inline secrets: count of Container Apps secrets that are inline values rather than Key Vault references; target zero in production.
- Secret readers: number of principals holding
listSecretson production apps, trending down. - Identity scoping: percentage of platform-only identities with lifecycle
None. - Exposure: share of production apps in internal environments or behind a WAF, and apps with "Allow unauthenticated access".
- Logging coverage: environments with a persistent log destination; target 100%.
Hardening baseline
- Choose the environment correctly at creation: a workload profiles environment (the default) on a dedicated subnet of at least
/27, internal (--internal-only) for anything that does not need direct internet exposure. Workload profiles support UDRs, NAT Gateway and private endpoints; consumption-only environments do not. - Follow Microsoft's three network recommendations: internal environment, Application Gateway with WAF in front, and a UDR sending outbound traffic through Azure Firewall. If you use public network access, set it to
Disabledwhen you adopt private endpoints. See the Azure Virtual Network Security Guide. - Set ingress per app: internal ingress for back-end services, external only where needed; keep
allowInsecuredisabled; add IP allow rules for admin apps; validate client certificates in code when usingrequire. TreatX-Forwarded-Forcarefully: Microsoft states only the rightmost address is provided by Azure. - Turn on built-in authentication with "Require authentication" for internal tools, and restrict the Entra app registration to assigned groups.
- Pull images with a managed identity: AcrPull only, lifecycle
None, no registry passwords. Pin images by digest in production templates. - Move every production secret to Key Vault references or, better, to managed identity authentication with no secret at all.
- Replace built-in Contributor and Operator roles for day-to-day operators with custom roles that omit
listSecrets; restrictjobs/start/action. - Configure persistent logging through Azure Monitor diagnostic settings to a central workspace, and alert on the Activity Log events above.
Testing and rollback: apply changes to a new revision first, use traffic splitting to send a small percentage of traffic to it, watch system logs and error rates, then shift traffic. Rolling back is moving traffic back to the previous revision. Network type changes cannot be rolled back: they need a new environment and a migration.
Small vs large teams: a small team can run one internal workload profiles environment with Key Vault references and custom roles. Larger organisations should separate environments per trust boundary, manage apps through infrastructure as code with policy checks, and use Azure Policy to deny external environments in production subscriptions. See the Azure Policy and Management Groups Guide.
Common misconfigurations
- Operators given Container Apps Contributor: they only needed to restart apps, but now every secret in the resource group is one API call away.
- Inline secrets copied from development: connection strings stored as Container Apps secrets survive into production and are never rotated.
- All identities left at lifecycle
All: application code, and anything that compromises it, can request tokens for the image-pull and Key Vault identities. - "Allow unauthenticated access" left on: the team assumed built-in authentication was enforcing sign-in, but the app code never checks the principal headers.
- Consumption-only environment for regulated workloads: without UDR support, egress cannot be forced through a firewall, and the network type cannot be changed later.
- Secret rotation without restart: the Key Vault value changed but pinned or inline revisions kept the old credential, so the "rotated" secret was still in use.
Framework mapping
| Framework | Reference | Container Apps control |
|---|---|---|
| NIST SP 800-53 Rev. 5 | AC-6 Least Privilege | Custom roles without listSecrets; identity lifecycle scoping |
| NIST SP 800-53 Rev. 5 | IA-5 Authenticator Management | Key Vault references, managed identities instead of secrets |
| NIST SP 800-53 Rev. 5 | SC-7 Boundary Protection; SC-8 Transmission Confidentiality | Internal environments, ingress rules, TLS, client certificates |
| NIST SP 800-53 Rev. 5 | AU-2, AU-12, SI-4 | Diagnostic settings, Activity Log alerts |
| NIST SP 800-53 Rev. 5 | CM-6, CM-7 | Environment configuration, ingress disabled where not needed |
| NIST CSF 2.0 | PR.AA-05, PR.DS-02, PR.PS-04 | Access policy, data in transit, log generation |
| MITRE ATT&CK | T1552.007 Container API; T1078.004 Cloud Accounts | Secret reads via management API, stolen identity tokens |
Practitioner checklist
- List every principal with
listSecretsorjobs/start/actionon production Container Apps and replace broad built-in roles with custom roles. - Convert inline Container Apps secrets to Key Vault references or managed identity authentication.
- Set
identitySettingslifecycle toNonefor ACR pull, scale rule and Key Vault identities. - Confirm production environments are workload profiles, VNet-integrated and internal where possible.
- Check every external app:
allowInsecureoff, authentication required or enforced in code, IP rules for admin apps. - Restrict Entra app registrations used by built-in authentication to assigned users and groups.
- Send logs through Azure Monitor diagnostic settings to a central workspace and alert on secret reads, ingress changes and identity changes.
- Add restart or new revision steps to every secret rotation runbook.
- Pin production images by digest and pull them with an AcrPull-only managed identity.
Standards and references
- Microsoft Learn: Manage secrets in Azure Container Apps
- Microsoft Learn: Managed identities in Azure Container Apps
- Microsoft Learn: Ingress in Azure Container Apps
- Microsoft Learn: Authentication and authorisation in Azure Container Apps
- Microsoft Learn: Networking in Azure Container Apps environment
- Microsoft Learn: Log storage and monitoring options in Azure Container Apps
- NIST: SP 800-53 Rev. 5
- MITRE ATT&CK: Container API
Related NHI Mgmt Group resources: Azure Managed Identities Security Guide · Azure Key Vault Security Guide · Azure Kubernetes Service Security Hardening Guide · Azure App Service Security Guide