Nasazení Azure Gateway¶
Nasazení MazeVault Gateway v Azure pro hybridní on-premise + cloud architekturu
Verze dokumentu: 1.0.0
Poslední aktualizace: 2026-03-19
Licenční úroveň: Enterprise
1. Přehled architektury¶
MazeVault Gateway rozšiřuje vaši on-premise instalaci MazeVault do Azure a poskytuje bezpečnou správu tajemství a automatizaci životního cyklu certifikátů pro cloudové workloady. Gateway komunikuje s vaším on-premise Primary backendem přes šifrovaný mTLS + E2EE kanál.
flowchart TB
subgraph OnPremise["🏢 On-Premise (Primary)"]
FE["🖥️ MazeVault Frontend"]
BE["⚙️ MazeVault Backend<br/>(Orchestrator Mode)"]
DB_OP["🗄️ PostgreSQL"]
RD_OP["⚡ Redis"]
end
subgraph Azure["☁️ Azure Cloud"]
subgraph GWC["🌍 Primární region (např. Germany West Central)"]
subgraph AKS_GWC["AKS Cluster"]
GW["🌐 MazeVault Gateway<br/>(1 replika)"]
AGENT["🤖 MazeVault Agent<br/>(DaemonSet)"]
end
PG["🗃️ Azure Database for<br/>PostgreSQL Flexible Server"]
Redis["⚡ Azure Cache<br/>for Redis"]
KV_GW["🔐 Key Vault<br/>(Gateway Secrets)"]
KV_PRJ["🔑 Key Vault<br/>(Projektové Secrets)"]
MI["🆔 Managed Identity"]
end
subgraph WE["🛡️ DR Region (např. West Europe) — Cold Standby"]
AKS_DR["⏸️ AKS — Zastavený"]
PG_DR["⏸️ PostgreSQL — Zastavený"]
KV_DR["✅ Key Vault — Aktivní"]
end
EA["🆔 Entra ID<br/>App Registration"]
ACR["📦 Container Registry"]
end
FE --> BE
GW -->|"mTLS + E2EE<br/>Port 8443"| BE
GW --> PG
GW --> Redis
GW --> KV_GW
GW --> KV_PRJ
MI -.-> KV_GW
MI -.-> KV_PRJ
AGENT -.-> GW
AKS_GWC -.->|Pull| ACR
KV_GW -.->|Geo-replikace| KV_DR
classDef onprem fill:#E8EAF6,stroke:#3F51B5,stroke-width:2px,color:#283593
classDef azure fill:#EBF5FB,stroke:#2196F3,stroke-width:2px,color:#1565C0
classDef data fill:#E8F5E9,stroke:#4CAF50,stroke-width:2px,color:#2E7D32
classDef security fill:#FFF8E1,stroke:#FF9800,stroke-width:2px,color:#E65100
classDef dr fill:#F5F5F5,stroke:#9E9E9E,stroke-width:2px,color:#424242
classDef identity fill:#FCE4EC,stroke:#E91E63,stroke-width:2px,color:#880E4F
class FE,BE,DB_OP,RD_OP onprem
class GW,AGENT,PG,Redis azure
class KV_GW,KV_PRJ security
class AKS_DR,PG_DR,KV_DR dr
class MI,EA,ACR identity
Klíčové komponenty¶
| Komponenta | Účel |
|---|---|
| MazeVault Gateway | Backend v režimu gateway — synchronizuje se s on-premise Primary |
| Azure Key Vault (Gateway) | Ukládá provozní tajemství (master key, JWT, DB přihlašovací údaje) |
| Azure Key Vault (Projekt) | Ukládá projektová tajemství spravovaná MazeVault (Orchestrator Mode) |
| Managed Identity | Systémový přístup ke Key Vaultům (čtení gateway secrets, čtení/zápis projektových secrets) |
| Entra ID App Registration | Uživatelský přístup přes OBO flow — každý Key Vault má vlastní RBAC |
| MazeVault Agent | Distribuuje tajemství/certifikáty na aplikační servery |
Binárky agentů¶
Agenti připojení ke Gateway stahují instalátory i aktualizace z Gateway. Gateway vydává verzi agenta přibalenou ve svém image a každou jinou verzi si stáhne z Primary přes své stávající spojení, takže verze agentů nezávisí na verzi Gateway. Podpis každé binárky Gateway ověřuje sama. Verze, které Primary nemá přibalené, vyžadují licenci Primary a přístup do registry MazeVault; Gateway samotná nepotřebuje ani jedno.
2. Předpoklady¶
2.1 Požadavky na Azure¶
- [ ] Azure Subscription s rolemi Contributor + User Access Administrator
- [ ] Azure CLI (
az) 2.50+ nainstalováno - [ ]
kubectlnainstalováno - [ ] Helm 3.12+ nainstalováno
- [ ] Terraform 1.5+ nainstalováno
2.2 Požadavky na On-Premise¶
- [ ] MazeVault Primary backend běžící v Orchestrator Mode
- [ ] Primary backend dostupný z Azure (VPN/ExpressRoute nebo veřejný endpoint s IP whitelistem)
- [ ] Admin přístup k MazeVault Primary (pro generování bootstrap tokenu)
2.3 Požadavky na Entra ID¶
- [ ] Role Global Administrator nebo Application Administrator v Entra ID
- [ ] Možnost udělit admin consent pro API oprávnění
3. Síťové požadavky¶
3.1 Síťová topologie¶
flowchart LR
subgraph OnPrem["🏢 On-Premise"]
FW["🛡️ Firewall"]
PRIMARY["⚙️ Primary Backend<br/>:8443"]
end
subgraph Azure["☁️ Azure"]
NSG["🛡️ NSG"]
AKS["🌐 AKS Gateway"]
end
subgraph Entra["🆔 Microsoft služby"]
LOGIN["login.microsoftonline.com"]
GRAPH["graph.microsoft.com"]
MGMT["management.azure.com"]
KVEP["*.vault.azure.net"]
end
AKS -->|"HTTPS :8443"| FW --> PRIMARY
AKS -->|"HTTPS :443"| LOGIN
AKS -->|"HTTPS :443"| GRAPH
AKS -->|"HTTPS :443"| MGMT
AKS -->|"HTTPS :443"| KVEP
classDef onprem fill:#E8EAF6,stroke:#3F51B5,stroke-width:2px,color:#283593
classDef azure fill:#EBF5FB,stroke:#2196F3,stroke-width:2px,color:#1565C0
classDef entra fill:#FFF8E1,stroke:#FF9800,stroke-width:2px,color:#E65100
class FW,PRIMARY onprem
class NSG,AKS azure
class LOGIN,GRAPH,MGMT,KVEP entra
3.2 Pravidla firewallu — On-Premise¶
| Směr | Zdroj | Cíl | Port | Protokol | Účel |
|---|---|---|---|---|---|
| Příchozí | Azure AKS Subnet | Primary Backend | TCP 8443 | HTTPS/mTLS | Gateway heartbeat, registrace, podepisování CSR, reconciliace write queue |
3.3 NSG pravidla — Azure (odchozí z AKS)¶
| Směr | Zdroj | Cíl | Port | Účel |
|---|---|---|---|---|
| Odchozí | AKS Subnet | On-Premise Primary IP | TCP 8443 | Gateway → Primary komunikace |
| Odchozí | AKS Subnet | login.microsoftonline.com |
TCP 443 | Entra ID SSO přihlášení |
| Odchozí | AKS Subnet | graph.microsoft.com |
TCP 443 | Graph API (skupiny, RBAC) |
| Odchozí | AKS Subnet | management.azure.com |
TCP 443 | Azure Management API (KV RBAC discovery) |
| Odchozí | AKS Subnet | *.vault.azure.net |
TCP 443 | Přístup ke Key Vault |
| Odchozí | AKS Subnet | PostgreSQL Private Endpoint | TCP 5432 | Databáze |
| Odchozí | AKS Subnet | Redis Private Endpoint | TCP 6380 | Cache (TLS) |
4. Registrace aplikace v Entra ID¶
Kritický krok
Tento krok musí být dokončen před nasazením gateway. Bez správné konfigurace Entra ID nebude fungovat SSO přihlášení ani OBO přístup ke Key Vault.
4.1 Vytvoření App Registration¶
- Přejděte na Azure Portal → Entra ID → App registrations → New registration
- Vyplňte:
| Pole | Hodnota |
|---|---|
| Name | APP_{PROJEKT}_{ZÓNA}_{PROSTŘEDÍ}_01 (např. APP_MZV_INT_PRO_01) |
| Supported account types | Single tenant (pouze tento adresář organizace) |
| Redirect URI (Web) | https://{vaše-api-doména}/api/v1/auth/sso/entra/callback |
4.2 Konfigurace API oprávnění¶
Přejděte na API permissions → Add a permission:
| API | Oprávnění | Typ | Účel |
|---|---|---|---|
| Microsoft Graph | openid |
Delegované | SSO přihlášení |
| Microsoft Graph | profile |
Delegované | Informace o profilu uživatele |
| Microsoft Graph | email |
Delegované | Email uživatele |
| Microsoft Graph | User.Read |
Delegované | Čtení profilu uživatele |
| Microsoft Graph | GroupMember.Read.All |
Delegované | Čtení skupin pro mapování RBAC |
| Azure Key Vault | user_impersonation |
Delegované | OBO přístup ke Key Vault jménem uživatele |
| Azure Service Management | user_impersonation |
Delegované | KV RBAC discovery přes Management API |
Udělení Admin Consent
Po přidání všech oprávnění klikněte na Grant admin consent for {tenant}. Bez toho OBO flow selže s chybou AADSTS65001.
4.3 Vytvoření Client Secret¶
- Přejděte na Certificates & secrets → New client secret
- Popis:
MazeVault Gateway Secret - Expirace: 24 měsíců (doporučeno)
- Okamžitě zkopírujte hodnotu — nebude znovu zobrazena
4.4 Konfigurace App Roles (Doporučeno pro RBAC mapování)¶
App Roles jsou doporučený mechanismus pro mapování uživatelů Entra ID na role v MazeVault. Po přiřazení se automaticky zobrazí jako claim roles v ID tokenu.
- Přejděte na App registrations → vaše SSO aplikace → App roles → Create app role
- Nastavte Allowed member types na Users/Groups
- Nastavte Value na identifikátor používaný v mapováních MazeVault (např.
APP_MZV_PRO_ADMIN) - Přejděte na Enterprise Applications → najděte odpovídající Enterprise App → Users and groups → Add user/group → Přiřaďte uživatele k vytvořeným App Roles
V MazeVault vytvořte mapování pod Access Control → Group/App Role Mappings, kde External ID odpovídá hodnotě App Role value.
Volitelný claim není potřeba
Hodnoty App Roles se v claimu roles objevují automaticky. Pro tento mechanismus není potřeba konfigurace volitelných claims.
4.5 Konfigurace claims tokenů (Volitelné)¶
Přejděte na Token configuration → Add optional claim:
| Claim | Typ tokenu | Účel |
|---|---|---|
email |
ID Token | E-mailová adresa uživatele (doporučeno) |
groups |
ID Token | Členství v Security Groups pro RBAC mapování (potřeba pouze při použití Security Groups místo App Roles) |
NEPOVOLUJTE emit_as_roles
Při přidávání claimu groups NEZAŠKRTÁVEJTE možnost emit_as_roles. Převádí Object ID skupin do claimu roles, čímž dochází ke konfliktu s hodnotami App Roles a k rozbití RBAC mapování.
4.6 Zaznamenání konfiguračních hodnot¶
Tyto hodnoty budete potřebovat pro Terraform nasazení:
| Hodnota | Kde najít | Proměnná prostředí |
|---|---|---|
| Tenant ID | Entra ID → Overview | ENTRA_TENANT_ID |
| Client ID | App Registration → Overview → Application (client) ID | ENTRA_CLIENT_ID |
| Client Secret | App Registration → Certificates & secrets → Value | ENTRA_CLIENT_SECRET |
| Redirect URI | App Registration → Authentication → Redirect URIs | ENTRA_REDIRECT_URI |
5. Jmenná konvence zdrojů¶
MazeVault používá konfigurovatelnou jmennou konvenci pro Azure zdroje. Výchozí vzor:
5.1 Produkční prostředí (PRO, PRE, DRN, MIG, EOY, HOT)¶
5.2 Neprodukční prostředí (DEV, ITG, TST)¶
5.3 Příklady¶
| Zdroj | Vzor | Příklad |
|---|---|---|
| Key Vault | {fi}{pr}{zo}{pj}{rg}kv{nn} |
crdprointmzvgwckv01 |
| PostgreSQL | {fi}-{pr}-{zo}-{pj}-{rg}-psql{nn} |
crd-pro-int-mzv-gwc-psql01 |
| Redis | {fi}-{pr}-{zo}-{pj}-{rg}-redis{nn} |
crd-pro-int-mzv-gwc-redis01 |
| AKS | {fi}-{pr}-{zo}-{pj}-{rg}-aks{nn} |
crd-pro-int-mzv-gwc-aks01 |
| Enterprise App | APP_{PJ}_{ZO}_{PR}_{nn} |
APP_MZV_INT_PRO_01 |
| Resource Group | rg-{fi}-{pr}-{zo}-{pj}-{rg} |
rg-crd-pro-int-mzv-gwc |
Přizpůsobitelné
Jmennou konvenci lze přizpůsobit per zákazník v MazeVault UI pod Organization Settings → Config Templates → Naming Convention.
6. Kroky nasazení¶
Důležité: lokální stack vs Azure deployment
docker compose up mění pouze lokální Compose stack; AKS workloady se tím nemění. Gateway v AKS běží z podepsaných image z MazeVault Harboru a aktualizuje se přes helm upgrade (Krok 5).
Krok 1: Vygenerování bootstrap tokenu na Primary¶
Na vašem on-premise MazeVault Primary serveru:
# Přihlášení jako admin
TOKEN=$(curl -sk -X POST https://PRIMARY_URL/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@mazevault.com","password":"VAŠE_HESLO"}' | jq -r '.token')
# Vygenerování bootstrap balíčku
curl -sk -X POST https://PRIMARY_URL/api/v1/gateways/bootstrap \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"azure-gateway-gwc-01"}'
Uložte vrácenou hodnotu token — budete ji potřebovat jako gateway_bootstrap_token.
Krok 2: Konfigurace Terraform proměnných¶
Vytvořte nebo aktualizujte terraform.tfvars:
# Jmenná konvence
company_code = "crd" # Vaše 3písmenná zkratka firmy
project_code = "mzv" # Kód projektu MazeVault
environment = "pro" # Prostředí (pro, pre, dev, atd.)
is_nonprod = false # true pro DEV/ITG/TST
location_zone = "int" # Síťová zóna (int nebo dmz)
# Regiony
primary_region = "germanywestcentral"
primary_region_code = "gwc"
dr_region = "westeurope"
dr_region_code = "we"
dr_enabled = false
# Infrastruktura
kubernetes_version = "1.32"
aks_node_count = 2
aks_vm_size = "Standard_D2s_v3"
enable_redis = true
Citlivé hodnoty nastavte přes proměnné prostředí:
export TF_VAR_primary_backend_url="https://váš-primary.example.com:8443"
export TF_VAR_gateway_bootstrap_token="token-z-kroku-1"
export TF_VAR_entra_tenant_id="váš-tenant-id"
export TF_VAR_gateway_frontend_url="https://mazevault.vaše-doména.internal"
Krok 3: Nasazení infrastruktury pomocí Terraform¶
cd deploy/terraform/azure-gateway
# Inicializace
terraform init \
-backend-config="resource_group_name=rg-terraform-state" \
-backend-config="storage_account_name=stterraformstate" \
-backend-config="container_name=tfstate" \
-backend-config="key=mazevault-gateway.tfstate"
# Plán
terraform plan -var-file=terraform.tfvars -out=tfplan
# Aplikace
terraform apply tfplan
Krok 4: Získání chartu a image z MazeVault Harboru¶
MazeVault publikuje podepsané image a zákaznický chart mazevault-customer do MazeVault Harboru (registry.mazevault.com/mazevault); release vX.Y.Z má image s tagem vX.Y.Z a chart ve verzi X.Y.Z. Použijte robot účet, který MazeVault vydal vaší firmě:
helm registry login registry.mazevault.com -u 'robot$mazevault+yourcompany'
# Stažení chartu; obsahuje examples/values-gateway-azure.yaml
helm pull oci://registry.mazevault.com/mazevault/mazevault-customer --version X.Y.Z --untar
cp mazevault-customer/examples/values-gateway-azure.yaml values-gateway.yaml
Zvolte, odkud AKS stahuje image gateway:
-
Přímo z Harboru. Vytvořte pull secret v namespace z Kroku 5 (example values na něj odkazují jako
mazevault-registry): -
Z ACR vytvořeného v Kroku 3 (AKS z něj už stahovat může; použijte, pokud AKS nemá cestu do Harboru). Spusťte
mirror-to-registry.shz Compose kitu (On-Premise nasazení) na stroji, který dosáhne na oba registry, a pak vvalues-gateway.yamlnastavtebackend.image.repositoryna<acr-login-server>/mazevault/mazevault-backenda odstraňteglobal.imagePullSecrets:
Krok 5: Nasazení Gateway do AKS¶
Gateway je chart mazevault-customer se zapnutým pouze backendem v režimu gateway. Runtime secrety dostává z gateway Key Vaultu přes External Secrets Operator a Workload Identity.
# Získání AKS přihlašovacích údajů
az aks get-credentials \
--resource-group $(terraform output -raw gwc_resource_group) \
--name $(terraform output -raw gwc_aks_cluster_name)
# External Secrets Operator (přeskočte, pokud už v clusteru je)
helm repo add external-secrets https://charts.external-secrets.io
helm upgrade --install external-secrets external-secrets/external-secrets \
-n external-secrets --create-namespace
# Vytvoření namespace
kubectl create namespace mazevault
KV=$(terraform output -json helm_values_summary | jq -r '.kv_gateway_name')
# Session secret (Terraform ukládá master key, JWT key a connection stringy, tento ne)
az keyvault secret set --vault-name "$KV" --name mazevault-session-secret \
--value "$(openssl rand -base64 32 | tr -d '\n/+=')"
# Bootstrap token z Kroku 1, který Terraform uložil do gateway Key Vaultu
kubectl create secret generic mazevault-gateway-bootstrap -n mazevault \
--from-literal=token="$(az keyvault secret show --vault-name "$KV" --name gateway-bootstrap-token --query value -o tsv)"
Doplňte values-gateway.yaml:
| Hodnota | Zdroj |
|---|---|
global.workloadIdentity.clientId, backend.config.AZURE_MANAGED_IDENTITY_CLIENT_ID |
terraform output -raw gwc_managed_identity_client_id |
global.keyVault.secretStore.vaultUrl |
https://<kv_gateway_name>.vault.azure.net/ (terraform output -json helm_values_summary) |
global.keyVault.secretStore.tenantId, backend.config.AZURE_TENANT_ID |
tenant_id z helm_values_summary |
backend.image.tag, backend.config.MAZEVAULT_VERSION |
nasazovaný release (vX.Y.Z / X.Y.Z) |
backend.config.PRIMARY_BACKEND_URL |
URL vašeho Primary backendu (TF_VAR_primary_backend_url) |
backend.config.GATEWAY_NAME |
název použitý pro bootstrap token v Kroku 1 |
backend.config.MAZEVAULT_GATEWAY_ENVIRONMENT (nebo …_ENVIRONMENTS) |
slug(y) prostředí, která gateway obsluhuje, malými písmeny, např. pro |
backend.config.MAZEVAULT_GATEWAY_ROLE |
primary, pro DR gateway dr-standby |
backend.config.MAZEVAULT_CUSTOMER_*, MAZEVAULT_COMPANY_ID |
stejné hodnoty jako na Primary |
Example ponechává název service accountu mazevault-gateway, který očekává federovaný credential managed identity z Kroku 3. Pak nasaďte:
# Nejdřív dry run
helm template mazevault-gateway oci://registry.mazevault.com/mazevault/mazevault-customer \
--version X.Y.Z -n mazevault -f values-gateway.yaml > /dev/null
helm upgrade --install mazevault-gateway oci://registry.mazevault.com/mazevault/mazevault-customer \
--version X.Y.Z \
-n mazevault \
-f values-gateway.yaml \
--wait --timeout 10m
Při pozdější aktualizaci gateway změňte verzi v --version, backend.image.tag a MAZEVAULT_VERSION a spusťte stejný helm upgrade.
Krok 6: Ověření nasazení¶
# Kontrola stavu podů
kubectl get pods -n mazevault
# Kontrola logů
kubectl logs -f deployment/mazevault-gateway-backend -n mazevault
# Očekávaný výstup:
# Starting MazeVault in gateway mode
# Registering gateway with primary...
# Setting up mTLS...
# Gateway registered successfully: <UUID>
# Heartbeat loop started (60s interval)
# Health check
kubectl port-forward svc/mazevault-gateway-backend 8080:8080 -n mazevault
curl -s http://localhost:8080/api/v1/health
curl -s http://localhost:8080/ # Vrátí: {"mode":"gateway"}
7. Konfigurace po nasazení¶
7.1 Přidání Key Vault integrace v MazeVault UI¶
Na vašem Primary MazeVault frontendu:
- Přejděte na Settings → Integrations → Add Integration
- Vyberte Azure Key Vault
- Nakonfigurujte:
- Vault URL:
https://{kv_project_name}.vault.azure.net/ - Auth Method:
on_behalf_of - Tenant ID: Váš Entra ID Tenant ID
- Client ID: Client ID App Registration
- Client Secret: Client Secret App Registration
- Klikněte na Test Connection pro ověření OBO flow
7.2 Konfigurace Sync Rules¶
- Přejděte na Integrations → Vyberte vaši Key Vault integraci
- Klikněte na Sync Rules → Add Rule
- Nakonfigurujte směr synchronizace (Bidirectional, Push nebo Pull)
- Nastavte rozsah (per projekt/prostředí)
8. RBAC model Key Vault¶
Každý Key Vault má vlastní RBAC
MazeVault respektuje Azure Key Vault RBAC. Uživatelé mohou přistupovat pouze k tajemstvím v Key Vaultech, kde jim byly uděleny příslušné role.
8.1 Systémový přístup (Managed Identity)¶
| Key Vault | Role | Účel |
|---|---|---|
| Gateway KV | Key Vault Secrets User (Čtení) | Čtení provozních tajemství |
| Project KV | Key Vault Secrets Officer (Čtení/Zápis) | Synchronizace a rotace projektových tajemství |
8.2 Uživatelský přístup (OBO Token)¶
Když uživatel přistupuje k tajemstvím přes MazeVault UI, systém používá On-Behalf-Of (OBO) flow:
- Uživatel se přihlásí přes Entra ID SSO
- MazeVault vymění uživatelský token za token s Key Vault scope
- Key Vault zkontroluje RBAC role assignments uživatele
- Přístup je povolen nebo zamítnut na základě individuálních oprávnění uživatele
Pro udělení přístupu uživateli ke Key Vault:
# Udělení přístupu pro čtení
az role assignment create \
--role "Key Vault Secrets User" \
--assignee uzivatel@firma.com \
--scope /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{kv-name}
# Udělení přístupu pro čtení/zápis
az role assignment create \
--role "Key Vault Secrets Officer" \
--assignee uzivatel@firma.com \
--scope /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{kv-name}
9. Disaster Recovery¶
9.1 DR architektura¶
DR region (West Europe) obsahuje všechny zdroje ve stavu stopped/deallocated:
- AKS cluster — zastavený
- PostgreSQL — zastavený
- Redis — zastavený
- Key Vault — aktivní (pro geo-replikaci tajemství)
9.2 Postup aktivace DR¶
- Spusťte AKS cluster v DR regionu
- Spusťte PostgreSQL (obnovení ze zálohy nebo geo-repliky)
- Spusťte Redis
- Vygenerujte nový bootstrap token na Primary
- Aktualizujte bootstrap token v DR Key Vault
- Gateway se automaticky zaregistruje u Primary
10. Řešení problémů¶
Gateway se neregistruje¶
# Ověřte, že PRIMARY_BACKEND_URL je dostupný z AKS
kubectl exec -n mazevault deploy/mazevault-gateway-backend -- \
curl -sk https://PRIMARY_URL/api/v1/health
# Zkontrolujte bootstrap token
kubectl exec -n mazevault deploy/mazevault-gateway-backend -- \
env | grep GATEWAY_BOOTSTRAP_TOKEN
Přístup ke Key Vault zamítnut¶
# Ověřte, že Managed Identity má správnou roli
az role assignment list \
--assignee $(terraform output -raw gwc_managed_identity_client_id) \
--scope $(terraform output -raw gwc_key_vault_gateway_id)
# Zkontrolujte, zda byl udělen admin consent
# Azure Portal → Entra ID → App registrations → API permissions