Skip to content

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 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:

  1. Navigate to App registrations → your SSO app → App rolesCreate app role
  2. 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:

  1. Navigate to Entra IDEnterprise applications → find the corresponding Enterprise App
  2. Users and groupsAdd user/group
  3. Select the user, then select the App Role to assign
  4. Click Assign

Step 3 — Create the mapping in MazeVault:

In the MazeVault UI under Access ControlGroup/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:

  1. Navigate to Token configurationAdd optional claimID 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/.default returns a token without sufficient scope
  • GET /v1.0/applications fails (needs Application.Read.All delegated or equivalent)
  • /me/memberOf fails → group-to-role mapping breaks (needs GroupMember.Read.All delegated)

If OBO token exchange fails, verify:

  1. ✅ All permissions in Section 2.1 are configured as Delegated (not Application)
  2. offline_access is present as Delegated — without it, no refresh token is issued and all OBO exchanges will fail
  3. GroupMember.Read.All is DelegatedGroup.Read.All (Application) does NOT substitute for it
  4. ✅ Admin consent has been granted for GroupMember.Read.All
  5. ✅ 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

  1. Entra IDApp registrationsNew registration
  2. Name: APP_MZV_INT_{ENV}_01
  3. Supported account types: Single tenant
  4. Redirect URI: Web — https://<BACKEND_OR_PUBLIC_API_HOST>/api/v1/auth/sso/entra/callback
  5. API permissionsAdd a permission → Add each permission from Section 2.1
  6. Grant admin consent for the tenant (required for GroupMember.Read.All and Application.Read.All)
  7. Certificates & secretsNew client secret → Copy and store in Key Vault
  8. Token configurationAdd optional claim → ID token → email. If using Security Groups, also add groups (do NOT check emit_as_roles)
  9. App rolesCreate app role → Define roles matching your MazeVault RBAC mappings (e.g. APP_MZV_PRO_ADMIN)
  10. Enterprise Applications → Find the corresponding Enterprise App → Users and groups → Assign users to App Roles
  11. 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

  1. Entra IDApp registrationsNew registration
  2. Name: APP_MZV_EMAIL_{ENV}_01
  3. Supported account types: Single tenant
  4. No redirect URI needed
  5. API permissionsAdd a permission → Microsoft Graph → Application permissionsMail.Send
  6. 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

  1. Entra IDApp registrationsNew registration
  2. Name: APP_MZV_ENTRA_{ENV}_01
  3. Supported account types: Single tenant
  4. No redirect URI needed
  5. API permissionsAdd a permission → Microsoft Graph → Application permissionsApplication.ReadWrite.All, Directory.Read.All
  6. Grant admin consent for the tenant
  7. Certificates & secrets → Create client secret (or upload certificate)
  8. 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

az identity create \
  --resource-group rg-mazevault-<env> \
  --name id-mazevault-<env>-<region>

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 Reader role 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.


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 Email
O365_CLIENT_ID App Reg #2 Email
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

POST /api/v1/admin/azure/mi-permissions-check
Authorization: Bearer <admin-jwt>

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

GET /api/v1/azure/user-permissions-summary
Authorization: Bearer <user-jwt>

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

GET /api/v1/health

Returns component-level health including database, Redis, and Key Vault connectivity.