Built-in Authentication (Easy Auth)¶
Azure Container Apps (ACA) provides built-in authentication and authorization, often referred to as "Easy Auth." This allows you to secure your Python application without writing complex authentication code.
How it Works¶
When you enable authentication, the platform's built-in authentication middleware intercepts incoming requests and validates the user's identity before forwarding the request to your application container.
sequenceDiagram
participant U as User Browser
participant P as Easy Auth Middleware
participant I as Identity Provider
participant A as Container App
U->>P: Request /protected
P->>I: Redirect for sign-in
I-->>P: Token/claims
P->>A: Forward request with X-MS-* headers
A-->>U: Authenticated response Easy Auth does not replace app authorization
Easy Auth authenticates users, but your application still must enforce role/tenant/resource-level authorization rules.
Enabling Authentication¶
To enable authentication with Microsoft Entra ID (formerly Azure AD):
export RG="rg-myapp"
export APP_NAME="ca-myapp"
export CLIENT_ID="<client-id>"
export CLIENT_SECRET="<client-secret>"
export TENANT_ID="<tenant-id>"
az containerapp auth microsoft update \
--name "$APP_NAME" \
--resource-group "$RG" \
--client-id "$CLIENT_ID" \
--client-secret "$CLIENT_SECRET" \
--tenant-id "$TENANT_ID" \
--action RedirectToLoginPage
Use secret references for client secrets
Avoid storing raw client secrets directly in scripts. Use secure secret handling workflows and rotate credentials regularly.
Accessing User Information¶
Once a user is authenticated, the platform middleware adds headers to the request that your Python application can use:
X-MS-CLIENT-PRINCIPAL-NAME: The user's username or email.X-MS-CLIENT-PRINCIPAL-ID: The user's unique identifier.X-MS-CLIENT-PRINCIPAL: A base64-encoded JSON object containing the user's claims.
Python Example¶
import base64
import json
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def home():
principal_header = request.headers.get('X-MS-CLIENT-PRINCIPAL')
if principal_header:
# Decode the principal header
principal = json.loads(base64.b64decode(principal_header).decode('utf-8'))
user_name = principal.get('name', 'Unknown User')
return f"Hello, {user_name}!"
return "Hello, anonymous user!"
Why use Easy Auth?¶
- Simplicity: No need to implement OAuth/OpenID Connect flows in your Python code.
- Security: Managed by Azure, ensuring it's always up to date with the latest security standards.
- Flexibility: Supports multiple identity providers, including Google, Facebook, and GitHub.
Easy Auth Capability Matrix¶
| Capability | Easy Auth Coverage | App Responsibility |
|---|---|---|
| Authentication handshake | Built-in | Configure provider correctly |
| Token/header injection | Built-in (X-MS-*) | Validate claim assumptions |
| Business authorization | Partial | Enforce route/resource policies |
| Session/user experience | Partial | Handle app-specific redirects and UX |