Azure Identity & Permissions Configuration¶
Complete Azure Entra ID, Managed Identity, and RBAC Setup for MazeVault
Document Version: 1.0.0
Last Updated: 2026-04-09
License Tier: Enterprise+
This document specifies every Azure identity object that MazeVault requires. It is intended as a precise handoff for the infrastructure team — follow each section in order to configure all app registrations, managed identities, RBAC role assignments, and federated credentials.
Per-Environment Separation
Create separate app registrations and managed identities for each environment (e.g., NPR, PRO). Never share credentials across environments.
1. Overview¶
graph TB
subgraph EntraID["🆔 Azure Entra ID"]
SSO["App Reg #1<br/><b>MazeVault SSO</b><br/>User login + OBO"]
Email["App Reg #2<br/><b>MazeVault Email</b><br/>Graph Mail.Send"]
EntraMgmt["App Reg #3<br/><b>MazeVault Entra Mgmt</b><br/>App/credential CRUD"]
TFSP["Service Principal<br/><b>Terraform / CI-CD</b><br/>Infrastructure deploy"]
end
subgraph Azure["☁️ Azure Resources"]
MI["🔐 User-Assigned<br/>Managed Identity"]
KVgw["🗝️ Gateway<br/>Key Vault"]
KVproj["🗝️ Project<br/>Key Vault(s)"]
SQL["🗄️ Azure SQL"]
AKS["☸️ AKS Cluster"]
ACR["📦 Container<br/>Registry"]
end
subgraph AKSPods["☸️ AKS Pods"]
BEPod["⚙️ Backend Pod"]
GWPod["🌐 Gateway Pod"]
ESO["🔄 External Secrets<br/>Operator"]
end
SSO -->|OBO tokens| BEPod
Email -.->|Mail.Send grant| MI
EntraMgmt -->|Graph API| BEPod
MI -->|RBAC| KVgw
MI -->|RBAC| KVproj
BEPod -->|Workload Identity| MI
GWPod -->|Workload Identity| MI
ESO -->|Workload Identity| MI
ESO -->|Sync secrets| KVgw
BEPod -->|SQL Auth| SQL
TFSP -->|Admin| KVgw
TFSP -->|Admin| KVproj
AKS -.->|AcrPull| ACR
classDef identity fill:#E8EAF6,stroke:#3F51B5,stroke-width:2px,color:#283593
classDef resource fill:#E8F5E9,stroke:#4CAF50,stroke-width:2px,color:#2E7D32
classDef pod fill:#FFF8E1,stroke:#FF9800,stroke-width:2px,color:#E65100
class SSO,Email,EntraMgmt,TFSP identity
class MI,KVgw,KVproj,SQL,AKS,ACR resource
class BEPod,GWPod,ESO pod
Summary Table¶
| # | Identity Object | Type | Purpose | Configured Via |
|---|---|---|---|---|
| 1 | MazeVault SSO | App Registration | User login + OBO resource access | Environment variables |
| 2 | MazeVault Email | App Registration | Email notifications via Graph API | Environment variables |
| 3 | MazeVault Entra Management | App Registration | App credential rotation & sync | MazeVault UI (per-integration) |
| 4 | MazeVault System Identity | User-Assigned Managed Identity | Background Key Vault & HSM ops | Environment variables |
| 5 | Workload Identity Federation | Federated Credential on MI | AKS pods → MI authentication | AKS + MI configuration |
| 6 | Azure DevOps PAT | Personal Access Token | CI/CD variable & Helm sync | MazeVault UI (per-integration) |
| 7 | Terraform / CI-CD SP | Service Principal | Infrastructure provisioning | CI/CD pipeline |
2. App Registration #1 — MazeVault SSO + On-Behalf-Of¶
Purpose: User single sign-on via OpenID Connect and On-Behalf-Of (OBO) token exchange so the backend can access Azure resources (Key Vaults, subscriptions, SQL servers) in the user's security context.
Suggested name: APP_MZV_INT_{ENV}_01 (e.g., APP_MZV_INT_PRO_01)
2.1 API Permissions¶
Delegated Permissions (require user sign-in)¶
| API | Permission | Permission GUID | Admin Consent | Purpose |
|---|---|---|---|---|
| Microsoft Graph | openid |
37f7f235-527c-4136-accd-4a02d197296e |
No | OIDC login |
| Microsoft Graph | profile |
14dad69e-099b-42c9-810b-d002981feec1 |
No | User display name |
| Microsoft Graph | email |
64a6cdd6-aab1-4aaf-94b8-3cc8405e90d0 |
No | User email address |
| Microsoft Graph | User.Read |
e1fe6dd8-ba31-4d61-89e7-88639da4683d |
No | Read user profile |
| Microsoft Graph | GroupMember.Read.All |
bc024368-1153-4739-b217-4326f2e966d0 |
Yes | Group-to-role mapping |
| Microsoft Graph | offline_access |
7427e0e9-2fba-42fe-b0c0-848c9e6a8182 |
No | Refresh token for OBO |
| Azure Key Vault | user_impersonation |
f53da476-18e3-4152-8e01-aec403e6edc0 |
No | User Key Vault browsing |
| Azure Service Management | user_impersonation |
41094075-9dad-400e-a0bd-54e686782033 |
No | Subscription & resource discovery |
API Resource IDs
- Microsoft Graph:
00000003-0000-0000-c000-000000000000 - Azure Key Vault:
cfa8b339-82a2-471a-a3c9-0fc0be7a4093 - Azure Service Management:
797f4846-ba00-4fd7-ba43-dac1f8f63013
Application Permissions (no user context — fallback only)¶
| API | Permission | Permission GUID | Admin Consent | Purpose |
|---|---|---|---|---|
| Microsoft Graph | Application.Read.All |
9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30 |
Yes | App registration discovery (fallback when OBO unavailable) |
2.2 Authentication Platform¶
| Setting | Value |
|---|---|
| Platform type | Web |
| Redirect URI | https://<BACKEND_OR_PUBLIC_API_HOST>/api/v1/auth/sso/entra/callback |
| ID tokens | ✅ Enabled |
| Access tokens | ❌ Disabled |
Redirect URI
Replace <BACKEND_OR_PUBLIC_API_HOST> with the actual public API host used by MazeVault backend (for example https://mazevault.company.com). The callback path /api/v1/auth/sso/entra/callback is required for this deployment model.
2.3 Client Secret¶
Create a client secret and store the value securely in Azure Key Vault. This secret is required for:
- Authorization code exchange (confidential client)
- Refresh token exchange (OBO flow)
2.4 RBAC Mapping — App Roles and Security Groups¶
MazeVault maps Entra ID users to internal roles using two mechanisms. App Roles are the recommended primary method. Security Groups are supported as an alternative.
App Roles (Recommended)¶
App Roles are defined in the App Registration manifest and assigned to users on the Enterprise Application. When assigned, they appear automatically as the roles claim in the ID token — no optional claim configuration is needed.
Step 1 — Define App Roles in the App Registration:
- Navigate to App registrations → your SSO app → App roles → Create app role
- Configure:
| Field | Value |
|---|---|
| Display name | e.g. APP_MZV_PRO_ADMIN |
| Allowed member types | Users/Groups |
| Value | e.g. APP_MZV_PRO_ADMIN (this value appears in the roles claim) |
| Description | MazeVault administrator role |
Repeat for each MazeVault role you want to map (e.g. APP_MZV_PRO_OPERATOR, APP_MZV_PRO_VIEWER).
Step 2 — Assign users to App Roles on the Enterprise Application:
- Navigate to Entra ID → Enterprise applications → find the corresponding Enterprise App
- Users and groups → Add user/group
- Select the user, then select the App Role to assign
- Click Assign
Step 3 — Create the mapping in MazeVault:
In the MazeVault UI under Access Control → Group/App Role Mappings, create a mapping where the External ID matches the App Role value (e.g. APP_MZV_PRO_ADMIN) and the target is the desired MazeVault role.
How it works
When a user with an assigned App Role logs in via SSO, the ID token contains a roles claim with the App Role values. MazeVault matches these values against configured mappings and assigns the corresponding role. No additional token configuration or optional claims are needed for App Roles.
Security Groups (Alternative)¶
If you prefer to use Entra ID Security Groups instead of App Roles, add the groups optional claim:
- Navigate to Token configuration → Add optional claim → ID token → select
groups
| Claim | Token Type | Additional Properties |
|---|---|---|
groups |
ID Token | — |
Then set groupMembershipClaims to SecurityGroup in the App Registration manifest.
In MazeVault, create a mapping where the External ID is the Security Group Object ID (UUID).
Do NOT enable emit_as_roles
When adding the groups optional claim, Azure offers an emit_as_roles checkbox. Do NOT enable this. It converts group Object IDs into the roles claim, which conflicts with App Role values and breaks RBAC mapping. This was validated as a breaking misconfiguration.
Groups Overage
When a user is a member of more than 150 groups, Azure omits the groups claim from the token. MazeVault automatically detects this and fetches group memberships via the Microsoft Graph API (/me/memberOf). No additional configuration is needed — the GroupMember.Read.All delegated permission handles this.
Optional Claims Summary¶
Configure these optional claims on the ID token:
| Claim | Token Type | Additional Properties | Required? |
|---|---|---|---|
email |
ID Token | — | Yes (always) |
groups |
ID Token | — (do NOT check emit_as_roles) |
Only if using Security Groups |
2.5 On-Behalf-Of (OBO) Token Exchange — How It Works¶
The backend stores the user's encrypted refresh token and exchanges it for scoped access tokens. The delegated user_impersonation permissions on Key Vault and Service Management APIs are what enable this.
Scopes exchanged at runtime:
| Scope | Resource | MazeVault Feature |
|---|---|---|
https://graph.microsoft.com/.default |
Microsoft Graph | App registration discovery, group membership |
https://management.azure.com/.default |
Azure Resource Manager | Subscription, Key Vault, SQL server discovery |
https://vault.azure.net/.default |
Azure Key Vault | User-context Key Vault secret browsing |
https://database.windows.net/.default |
Azure SQL | SQL federated authentication (future) |
No Additional API Permissions Needed
The OBO scopes above use the user_impersonation permissions already configured in Section 2.1. No extra API permission registration is needed — the scopes are resolved at runtime via the .default suffix.
Critical: Application vs Delegated Permission Types
The token exchange uses grant_type: refresh_token. Tokens obtained this way only contain Delegated permissions — Application permissions are never included.
Common misconfiguration: Adding Graph permissions like Directory.Read.All, Group.Read.All, or User.Read.All as Application permissions instead of the required Delegated permissions. This causes silent failures:
- OBO exchange for
https://graph.microsoft.com/.defaultreturns a token without sufficient scope GET /v1.0/applicationsfails (needsApplication.Read.Alldelegated or equivalent)/me/memberOffails → group-to-role mapping breaks (needsGroupMember.Read.Alldelegated)
If OBO token exchange fails, verify:
- ✅ All permissions in Section 2.1 are configured as Delegated (not Application)
- ✅
offline_accessis present as Delegated — without it, no refresh token is issued and all OBO exchanges will fail - ✅
GroupMember.Read.Allis Delegated —Group.Read.All(Application) does NOT substitute for it - ✅ Admin consent has been granted for
GroupMember.Read.All - ✅ The user has re-authenticated after permission changes (existing sessions use old tokens)
Permissions that are NOT needed on this app registration:
Directory.Read.All (App), Group.Read.All (App), User.Read.All (App), RoleManagement.Read.Directory (App) — these are not used by MazeVault SSO and should be removed to follow least-privilege.
2.6 Environment Variables¶
| Variable | Value | Description |
|---|---|---|
ENTRA_ENABLED |
true |
Enable Entra ID SSO |
ENTRA_TENANT_ID |
<your-tenant-id> |
Azure AD tenant ID |
ENTRA_CLIENT_ID |
<app-client-id> |
Application (client) ID from this registration |
🔐 ENTRA_CLIENT_SECRET |
<client-secret> |
Client secret value — store in Key Vault |
ENTRA_REDIRECT_URI |
https://<BACKEND_OR_PUBLIC_API_HOST>/api/v1/auth/sso/entra/callback |
Must match the redirect URI configured above |
2.7 Azure Portal — Step by Step¶
- Entra ID → App registrations → New registration
- Name:
APP_MZV_INT_{ENV}_01 - Supported account types: Single tenant
- Redirect URI: Web —
https://<BACKEND_OR_PUBLIC_API_HOST>/api/v1/auth/sso/entra/callback - API permissions → Add a permission → Add each permission from Section 2.1
- Grant admin consent for the tenant (required for
GroupMember.Read.AllandApplication.Read.All) - Certificates & secrets → New client secret → Copy and store in Key Vault
- Token configuration → Add optional claim → ID token →
email. If using Security Groups, also addgroups(do NOT checkemit_as_roles) - App roles → Create app role → Define roles matching your MazeVault RBAC mappings (e.g.
APP_MZV_PRO_ADMIN) - Enterprise Applications → Find the corresponding Enterprise App → Users and groups → Assign users to App Roles
- Authentication → Implicit grant → Check ID tokens only
3. App Registration #2 — MazeVault Email (Office 365)¶
Purpose: Send email notifications (password resets, certificate expiry alerts, rotation status) via the Microsoft Graph sendMail API.
Suggested name: APP_MZV_EMAIL_{ENV}_01
3.1 API Permissions¶
| API | Permission | Type | Permission GUID | Admin Consent |
|---|---|---|---|---|
| Microsoft Graph | Mail.Send |
Application | b633e1c5-b582-4048-a93e-9f11b44c7e96 |
Yes |
Application Permission
Mail.Send is an Application permission (not Delegated). This allows the backend to send emails as a daemon without user interaction. Admin consent is mandatory.
3.2 Authentication Method¶
MazeVault supports three authentication methods for this app registration. Managed Identity is recommended for Azure-hosted deployments:
No client secret is needed at runtime. The backend authenticates using the User-Assigned Managed Identity (Identity #4).
The app registration is still required for the Mail.Send API permission grant — but runtime authentication goes through the Managed Identity.
| Variable | Value |
|---|---|
O365_EMAIL_ENABLED |
true |
O365_TENANT_ID |
<tenant-id> |
O365_CLIENT_ID |
<this-app-client-id> |
O365_SENDER_EMAIL |
noreply@company.com |
O365_AUTH_METHOD |
managed_identity |
O365_MANAGED_IDENTITY_CLIENT_ID |
Same value as AZURE_MANAGED_IDENTITY_CLIENT_ID |
| Variable | Value |
|---|---|
O365_EMAIL_ENABLED |
true |
O365_TENANT_ID |
<tenant-id> |
O365_CLIENT_ID |
<this-app-client-id> |
🔐 O365_CLIENT_SECRET |
<client-secret> |
O365_SENDER_EMAIL |
noreply@company.com |
O365_AUTH_METHOD |
client_secret |
| Variable | Value |
|---|---|
O365_EMAIL_ENABLED |
true |
O365_TENANT_ID |
<tenant-id> |
O365_CLIENT_ID |
<this-app-client-id> |
O365_SENDER_EMAIL |
noreply@company.com |
O365_AUTH_METHOD |
certificate |
O365_CERTIFICATE_PATH |
/path/to/cert.pfx |
🔐 O365_CERTIFICATE_PASSWORD |
<pfx-password> |
Sender Email
The O365_SENDER_EMAIL must be a valid mailbox or shared mailbox in your tenant. The Managed Identity or service principal must have permission to send as that mailbox.
3.3 Azure Portal — Step by Step¶
- Entra ID → App registrations → New registration
- Name:
APP_MZV_EMAIL_{ENV}_01 - Supported account types: Single tenant
- No redirect URI needed
- API permissions → Add a permission → Microsoft Graph → Application permissions →
Mail.Send - Grant admin consent for the tenant
4. App Registration #3 — MazeVault Entra Management¶
Purpose: Manage Azure AD app registrations, rotate client secrets and certificates, sync service principals. Used by the Entra Token Rotation feature.
Suggested name: APP_MZV_ENTRA_{ENV}_01
Configuration Method
This identity is NOT configured via environment variables. It is configured in the MazeVault UI: Project → Integrations → Add Integration → Microsoft Entra ID.
4.1 API Permissions¶
| API | Permission | Type | Permission GUID | Admin Consent |
|---|---|---|---|---|
| Microsoft Graph | Application.ReadWrite.All |
Application | 1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9 |
Yes |
| Microsoft Graph | Directory.Read.All |
Application | 7ab1d382-f21e-4acd-a863-ba3e13f7da61 |
Yes |
Future (Phase 5):
| API | Permission | Type | Permission GUID | Admin Consent |
|---|---|---|---|---|
| Microsoft Graph | AppRoleAssignment.ReadWrite.All |
Application | 06b708a9-e830-4db3-a914-8e69da51d44f |
Yes |
4.2 Authentication Methods¶
This registration supports three authentication methods, configured in the MazeVault integration settings:
| Method | Config Keys | Use Case |
|---|---|---|
| Client Secret | tenant_id, client_id, client_secret |
Default — service-to-service |
| Managed Identity | tenant_id, client_id (optional) |
Azure-hosted deployments |
| Certificate | tenant_id, client_id, certificate_path, certificate_password |
Enhanced security |
4.3 Microsoft Graph Operations Performed¶
This identity performs the following Graph API operations:
| Operation | Graph Endpoint | HTTP Method |
|---|---|---|
| List app registrations | /v1.0/applications |
GET |
| Create app registration | /v1.0/applications |
POST |
| Update app registration | /v1.0/applications/{id} |
PATCH |
| Delete app registration | /v1.0/applications/{id} |
DELETE |
| Add client secret | /v1.0/applications/{id}/addPassword |
POST |
| Remove client secret | /v1.0/applications/{id}/removePassword |
POST |
| Add certificate | /v1.0/applications/{id}/addKey |
POST |
| Remove certificate | /v1.0/applications/{id}/removeKey |
POST |
| List service principals | /v1.0/servicePrincipals |
GET |
| Create service principal | /v1.0/servicePrincipals |
POST |
| Update service principal | /v1.0/servicePrincipals/{id} |
PATCH |
| Delete service principal | /v1.0/servicePrincipals/{id} |
DELETE |
| List app role assignments | /v1.0/servicePrincipals/{id}/appRoleAssignments |
GET |
| List OAuth2 grants | /v1.0/servicePrincipals/{id}/oauth2PermissionGrants |
GET |
| Test connection | /v1.0/organization |
GET |
4.4 Azure Portal — Step by Step¶
- Entra ID → App registrations → New registration
- Name:
APP_MZV_ENTRA_{ENV}_01 - Supported account types: Single tenant
- No redirect URI needed
- API permissions → Add a permission → Microsoft Graph → Application permissions →
Application.ReadWrite.All,Directory.Read.All - Grant admin consent for the tenant
- Certificates & secrets → Create client secret (or upload certificate)
- Copy Tenant ID, Client ID, and Client Secret — enter them in MazeVault when creating the Entra ID integration
5. User-Assigned Managed Identity¶
Purpose: System-level authentication for background operations — Key Vault secret rotation, certificate push/pull, HSM key generation and signing, External Secrets Operator sync.
Suggested name: id-mazevault-{env}-{region} (e.g., id-mazevault-pro-gwc)
5.1 Create Managed Identity¶
5.2 Azure RBAC Role Assignments¶
Gateway Key Vault (configuration vault)¶
| Role | Purpose | Operations |
|---|---|---|
| Key Vault Secrets User | Read configuration secrets (Entra creds, DB URL, TLS certs) | GetSecret, ListSecrets |
az role assignment create \
--assignee <managed-identity-principal-id> \
--role "Key Vault Secrets User" \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<gateway-kv>
Project Key Vault(s) (secret & certificate storage)¶
| Role | Purpose | Operations |
|---|---|---|
| Key Vault Secrets Officer | Read/write secrets during rotation and sync | GetSecret, SetSecret, DeleteSecret, ListSecrets |
| Key Vault Crypto Officer | HSM key operations for certificate signing | CreateKey, Sign, GetKey, DeleteKey, Verify |
# Secrets access
az role assignment create \
--assignee <managed-identity-principal-id> \
--role "Key Vault Secrets Officer" \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<project-kv>
# HSM / Crypto access
az role assignment create \
--assignee <managed-identity-principal-id> \
--role "Key Vault Crypto Officer" \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<project-kv>
Crypto Officer vs Crypto User
If you do not use HSM-backed key generation (only signing with existing keys), Key Vault Crypto User is sufficient instead of Key Vault Crypto Officer.
5.3 Key Vault Operations Reference¶
The Managed Identity performs these Azure SDK operations:
Secrets (azsecrets SDK):
| Operation | Used By | Direction |
|---|---|---|
SetSecret() |
Secret rotation, certificate export, post-rotation sync | Write |
GetSecret() |
Pre-rotation sync, fetch for comparison | Read |
DeleteSecret() |
Cleanup (optional) | Delete |
ListSecrets() |
Health check, change watching | Read |
Keys/HSM (azkeys SDK):
| Operation | Used By | Direction |
|---|---|---|
CreateKey() |
RSA-HSM / EC-HSM key pair generation | Write |
Sign() |
Certificate signing (RS256) | Compute |
GetKey() |
Public key retrieval | Read |
DeleteKey() |
Key lifecycle cleanup | Delete |
5.4 Environment Variables¶
| Variable | Value | Description |
|---|---|---|
AZURE_MANAGED_IDENTITY_CLIENT_ID |
<mi-client-id> |
Client ID of the user-assigned managed identity |
AZURE_TENANT_ID |
<tenant-id> |
Azure AD tenant ID |
6. Workload Identity Federation (AKS ↔ Managed Identity)¶
Purpose: Allow AKS pods to authenticate as the Managed Identity (#5) using OIDC token exchange — no credentials stored in the cluster.
6.1 AKS Cluster Configuration¶
Ensure the AKS cluster has workload identity enabled:
az aks update \
--resource-group rg-mazevault-<env> \
--name aks-mazevault-<env> \
--enable-oidc-issuer \
--enable-workload-identity
Enable Key Vault CSI driver with auto-rotation:
az aks enable-addons \
--resource-group rg-mazevault-<env> \
--name aks-mazevault-<env> \
--addons azure-keyvault-secrets-provider \
--enable-secret-rotation \
--rotation-poll-interval 2m
6.2 Federated Identity Credentials¶
Create federated credentials on the Managed Identity for each service account:
External Secrets Operator (ESO):
az identity federated-credential create \
--identity-name id-mazevault-<env>-<region> \
--resource-group rg-mazevault-<env> \
--name fic-mazevault-eso \
--issuer <AKS_OIDC_ISSUER_URL> \
--subject system:serviceaccount:mazevault:mazevault-sa \
--audiences api://AzureADTokenExchange
Gateway / Backend Pod:
az identity federated-credential create \
--identity-name id-mazevault-<env>-<region> \
--resource-group rg-mazevault-<env> \
--name fic-mazevault-gateway-sa \
--issuer <AKS_OIDC_ISSUER_URL> \
--subject system:serviceaccount:mazevault:mazevault-gateway-sa \
--audiences api://AzureADTokenExchange
Subject must match exactly
If the federated credential subject differs from the real service account, pod secret mount fails with AADSTS700213.
OIDC Issuer URL
Get the issuer URL with:
az aks show --name aks-mazevault-<env> --resource-group rg-mazevault-<env> --query "oidcIssuerProfile.issuerUrl" -o tsv
6.3 External Secrets Operator — Synced Secrets¶
ESO syncs these secrets from the Gateway Key Vault to Kubernetes every 5 minutes:
| K8s Secret Key | Key Vault Secret Name | Refresh Interval |
|---|---|---|
DATABASE_URL |
mazevault-database-url |
5 min |
REDIS_URL |
mazevault-redis-url |
5 min |
MAZEVAULT_MASTER_KEY |
mazevault-master-key |
5 min |
MAZEVAULT_JWT_KEY |
mazevault-jwt-key |
5 min |
MAZEVAULT_SESSION_SECRET |
mazevault-session-secret |
5 min |
ENTRA_TENANT_ID |
mazevault-entra-tenant-id |
5 min |
ENTRA_CLIENT_ID |
mazevault-entra-client-id |
5 min |
ENTRA_CLIENT_SECRET |
mazevault-entra-client-secret |
5 min |
ENTRA_REDIRECT_URI |
mazevault-entra-redirect-uri |
5 min |
| TLS Certificate | mazevault-tls-cert |
1 hour |
| TLS Private Key | mazevault-tls-key |
1 hour |
Key Vault Secret Names
The secret names in Key Vault (right column) must match exactly. Seed them during infrastructure provisioning before the first deployment.
7. Azure DevOps Integration (PAT)¶
Purpose: Sync rotated secrets to Azure DevOps pipeline variable groups or update Helm chart values in Git repositories.
Configuration Method
Azure DevOps integration is NOT an app registration. It uses a Personal Access Token (PAT) configured in the MazeVault UI: Project → Integrations → Add Integration → Azure DevOps.
7.1 PAT Scopes Required¶
| Scope | Access Level | Purpose |
|---|---|---|
| Code | Read & Write | Update Helm values files in Git |
| Build | Read & Execute | Trigger pipeline runs after variable updates |
| Variable Groups | Read & Manage | Update pipeline variable group values |
7.2 Supported Sync Modes¶
| Mode | API Used | Description |
|---|---|---|
| Variable Group | dev.azure.com/{org}/{project}/_apis/distributedtask/variablegroups/{id} |
Updates pipeline variables directly |
| Helm Values | dev.azure.com/{org}/{project}/_apis/git/repositories/{repo}/pushes |
Commits updated YAML values to Git |
7.3 Configuration in MazeVault¶
When creating the integration, provide:
| Field | Description |
|---|---|
| Organization | Azure DevOps organization name |
| Project | Project name |
| Token | Personal Access Token with scopes above |
| Mode | variable_group or helm_values |
| Group ID | Variable group ID (for variable_group mode) |
| Repository | Git repo name (for helm_values mode) |
| Branch | Target branch (for helm_values mode) |
| File Path | Path to values YAML file (for helm_values mode) |
8. Terraform / CI-CD Service Principal¶
Purpose: Infrastructure provisioning — Terraform apply, Key Vault secret seeding, AKS management.
8.1 Required Roles¶
| Target Resource | Role | Purpose |
|---|---|---|
| Gateway Key Vault | Key Vault Administrator |
Seed initial secrets |
| Project Key Vault(s) | Key Vault Administrator |
Seed initial secrets |
| Resource Group | Contributor |
Create/manage resources |
| Container Registry | AcrPull |
Allow AKS to pull images |
9. Key Vault RBAC Matrix¶
Summary of all identities and their Key Vault access:
| Identity | Gateway KV | Project KV(s) | Purpose |
|---|---|---|---|
| Managed Identity | Secrets User | Secrets Officer + Crypto Officer | Background rotation, sync, HSM |
| OBO (SSO users) | — | Delegated (per-user Azure RBAC) | User-context browsing via UI |
| SSO App Service Principal (APP #1) | — | Secrets User or Secrets Officer | Integration flows using client_secret auth |
| Terraform SP | Administrator | Administrator | Infrastructure provisioning |
| ESO | Secrets User (via MI) | — | Sync config to K8s |
Principle of Least Privilege
The Managed Identity has Secrets User (read-only) on the Gateway KV because it only needs to read configuration. It has Secrets Officer (read/write) on Project KVs where secret rotation happens.
9.1 Mandatory OBO RBAC for Azure Discovery and Key Vault Browsing¶
To avoid "0 subscriptions found" and OBO browse failures, users testing via Entra SSO must have:
| Scope | Minimum Role | Why it is required |
|---|---|---|
| Subscription | Reader |
Required for GET /subscriptions and ARM discovery endpoints |
| Project Key Vault | Key Vault Secrets User |
Required for ListSecrets/GetSecret in user context |
Assign roles (example):
az role assignment create \
--role "Reader" \
--assignee <user-object-id-or-upn> \
--scope /subscriptions/<subscription-id>
az role assignment create \
--role "Key Vault Secrets User" \
--assignee <user-object-id-or-upn> \
--scope /subscriptions/<subscription-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault-name>
Important runtime behavior
GET /api/v1/azure/user-permissions-summary can return 200 with an empty subscription list when OBO token exchange succeeds but the user has no Reader role on any subscription.
10. Azure SQL — Password Rotation¶
SQL Authentication — Not Azure AD
MazeVault uses SQL native authentication (username + password) for database password rotation. You do not need to enable Azure AD authentication on your SQL servers for this feature.
What the Infrastructure Team Needs to Provide¶
| Requirement | Description |
|---|---|
| Network access | MazeVault backend must be able to reach the SQL server on port 1433 |
| Admin account | SQL admin credentials with ALTER USER and CREATE USER privileges |
| Firewall rules | Whitelist MazeVault pod IP range or use Private Endpoints |
Azure SQL Server Discovery¶
MazeVault can discover Azure SQL servers for easier onboarding. This uses the OBO flow (App Registration #1) with the https://management.azure.com/.default scope:
- API:
GET https://management.azure.com/subscriptions/{id}/providers/Microsoft.Sql/servers?api-version=2023-05-01-preview - Permission: The logged-in user must have at least
Readerrole on the subscription - No additional Azure identity configuration needed beyond what is in Section 2
11. Kubernetes RBAC (In-Cluster)¶
MazeVault's rotation pipeline can update Kubernetes secrets and trigger pod restarts directly (without going through an agent). The backend pod needs K8s RBAC for this.
Required ClusterRole¶
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: mazevault-rotation
rules:
# Update K8s secrets after rotation
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "update"]
# Trigger rolling restarts
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: mazevault-rotation-binding
subjects:
- kind: ServiceAccount
name: mazevault-gateway
namespace: mazevault
roleRef:
kind: ClusterRole
name: mazevault-rotation
apiGroup: rbac.authorization.k8s.io
Scope
If rotation targets are limited to a single namespace, use a Role + RoleBinding instead of ClusterRole for tighter security.
12. Admin Consent Checklist¶
After creating all app registrations, the following permissions require tenant administrator consent:
| App Registration | Permission | Type |
|---|---|---|
| #1 SSO | GroupMember.Read.All |
Delegated |
| #1 SSO | Application.Read.All |
Application |
| #2 Email | Mail.Send |
Application |
| #3 Entra Management | Application.ReadWrite.All |
Application |
| #3 Entra Management | Directory.Read.All |
Application |
To grant consent: Entra ID → Enterprise applications → Select the app → Permissions → Grant admin consent for {tenant}
13. Complete Environment Variable Map¶
| Variable | Identity Source | Feature |
|---|---|---|
ENTRA_ENABLED |
— | true to enable SSO |
ENTRA_TENANT_ID |
App Reg #1 | SSO |
ENTRA_CLIENT_ID |
App Reg #1 | SSO |
🔐 ENTRA_CLIENT_SECRET |
App Reg #1 | SSO + OBO |
ENTRA_REDIRECT_URI |
App Reg #1 | SSO callback |
O365_EMAIL_ENABLED |
— | true to enable Graph email |
O365_TENANT_ID |
App Reg #2 | |
O365_CLIENT_ID |
App Reg #2 | |
O365_SENDER_EMAIL |
— | Sender address |
O365_AUTH_METHOD |
— | managed_identity (recommended) |
O365_MANAGED_IDENTITY_CLIENT_ID |
MI #5 | Email via MI |
AZURE_MANAGED_IDENTITY_CLIENT_ID |
MI #5 | Background operations |
AZURE_TENANT_ID |
— | Tenant ID |
See Environment Variables Reference for the full variable list.
14. Verification¶
MazeVault provides built-in API endpoints to verify Azure permissions after setup.
Managed Identity Check¶
Tests the Managed Identity's access to all configured Azure integrations. Returns per-integration status (success/failed/skipped) with the MI Client ID.
Managed Identity execution boundary
Managed Identity authentication only works in a runtime that has Azure IMDS/Workload Identity available (for example AKS gateway pods). A local Docker Primary backend does not have IMDS and will fail with ManagedIdentityCredential timeout.
Proxy fallback
In the current release, integration Test Connection and manual integration sync run in the backend where the request is executed. Automatic fallback from local Primary to Azure gateway is not performed for these endpoints.
User OBO Permissions Summary¶
Aggregates the logged-in user's visible Azure subscriptions, Key Vaults, and SQL servers via OBO. Useful for verifying that SSO + OBO is working correctly.
Health Check¶
Returns component-level health including database, Redis, and Key Vault connectivity.
Related¶
- Azure AKS Deployment — Kubernetes cluster setup
- Environment Variables Reference — Full variable list
- Authentication — SSO configuration
- Entra Token Rotation Guide — Using the Entra credential rotation feature
- Helm Charts — Helm values reference