Manual Post-Deployment Setup for Dialogs and Python Agents
This documentation is for Kyvos 2026.8.x. To view documentation for other Kyvos versions, click here. |
|---|
Overview
Dialogs & Python Agents — ADLS Gen2 ACLs and Key Vault access
This runbook covers the two manual steps an operator may need to perform after deploying PostCreationDialogsAndPythonAgents.json. These two steps are NOW INDEPENDENT — each is gated by its own checkbox on the Basics tab: (1) Apply per-path ADLS Gen2 ACLs on the Kyvos storage account — required when 'Firewall enabled on Storage account' was checked. (2) Grant the agent managed identities access on the Key Vault keys used for encryption/decryption — required when 'Is Encryption enabled' was checked. If only one box was checked, you only need that one procedure. Both operations require an Azure identity with sufficient privileges on the target resources (see the Prerequisites section for each).
Apply per-path ADLS Gen2 ACLs on the Kyvos storage account.
Grant the agent managed identities access on the Key Vault keys used for encryption/decryption.
Both operations require an Azure identity with sufficient privileges on the target resources (see the Prerequisites section for each).
Prerequisites
Before you begin, collect the following from the deployed resource group:
Item | Where to find it |
Dialogs Agent MI name and Object (Principal) ID | Resource group → User-assigned managed identities → kyvos-dialogs-agent-mi-<UniqueNumber> → Overview |
Code Executor MI name and Object (Principal) ID (only if Dialogs Agent + Python Agents was selected) | kyvos-code-executor-mi-<UniqueNumber> |
Kyvos storage account name | The StorageAccountName parameter you supplied |
Container name | The StorageAccountContainerName parameter |
Kyvos work directory path | The KyvosWorkDir parameter — default /user/engine_work/ |
Key Vault name | The VaultName parameter |
You can also retrieve a principal ID via Azure CLI:
az identity show --resource-group <rg> --name <mi-name> --query principalId --output tsv
Apply ADLS Gen2 ACLs on the Storage Account
ADLS Gen2 uses POSIX-style ACLs. Parent directories require execute (--x) for traversal, and listing a directory requires read + execute (r-x). Write permissions are needed only on the specific subdirectories where the agents produce data.
ACL Model
Apply the following access ACL entries. Where “default ACL” is listed, also add the same permissions under the Default permissions tab so newly-created children inherit them.
Dialogs Agent MI
Path | Access ACL | Default ACL |
/ | --x (Execute only) — REQUIRED for traversal into /user | — |
/user | --x (Execute only) | — |
/user/engine_work | --x | — |
/user/engine_work/setup | r-x (Read + Execute) | — |
/user/engine_work/setup/conf | r-x | — |
/user/engine_work/dialogs | r-x | — |
/user/engine_work/dialogs/deepdive | r-x | — |
/user/engine_work/dialogs/deepdive/chatsessions | r-x | — |
/user/engine_work/dialogs/deepdive/chatsessions/tmp | rwx (Read + Write + Execute) | rwx |
/user/engine_work/dialogs/deepdive/chatsessions/saved | rwx | rwx |
/user/engine_work/logs | rwx | rwx |
Code Executor MI (only if deployed)
Path | Access ACL | Default ACL |
/ | --x (Execute only) — REQUIRED for traversal into /user | — |
/user | --x | — |
/user/engine_work | --x | — |
/user/engine_work/setup | r-x | — |
/user/engine_work/setup/conf | r-x | — |
/user/engine_work/logs | --x (Execute only) — traversal to child | — |
/user/engine_work/logs/codeexecutorlogs | rwx (Read + Write + Execute) | rwx |
The Code Executor needs read access to setup/conf (to download its bundle) and read/write/execute on its own log subfolder logs/codeexecutorlogs (with execute-only traversal on the parent logs directory), plus traversal on the parents. It does not require any access under dialogs/.
Step-by-step in the Azure portal
Permission required: Storage Blob Data Owner on the storage account. Storage Blob Data Contributor is NOT sufficient: it can read/write blob content but cannot set ACLs on items it does not own.
Navigate to your storage account in the Azure portal.
In the left blade, open Storage browser.
Expand Blob containers and click your Kyvos container name.
Apply ACL on the container root FIRST: in Storage browser, right-click the container itself (the row above 'user') → Manage ACL → add the agent MI with Execute only (--x). Then right-click the user folder → Manage ACL. If the folder does not exist yet, create it with + New folder at the top of the container. Repeat for each parent in the path you intend to ACL.
In the Manage ACL blade:
Click + Add principal.
Search for the agent MI by name (kyvos-dialogs-agent-mi-<UniqueNumber> or kyvos-code-executor-mi-<UniqueNumber>).
Select it and click Add.
Under the Access permissions tab, set the Read / Write / Execute checkboxes according to the ACL Model above.
For the rwx + default rwx rows (tmp, saved, logs): switch to the Default permissions tab and check Read / Write / Execute there too.
Click Save.
Repeat steps 4–5 for every directory in the ACL Model, walking shallowest (/user) to deepest (.../dialogs/deepdive/chatsessions/saved).
If you also deployed the Code Executor, repeat the entire procedure for the Code Executor MI on its (shorter) path list.
Verification
In the Storage browser, right-click any path → Manage ACL and confirm the agent MI is listed under Security principal with the expected R/W/X checkboxes.
Note
Read/write permissions only work if the principal also has execute on every ancestor directory, including the container root. Make sure every parent in the path is set to --x for the MI.
Alternatively, from Azure CLI on a machine with VNet line-of-sight to the storage account:
az storage fs access show \
--account-name <storage-account> \
--file-system <container> \
--path user/engine_work/logs \
--auth-mode login
Look for user:<principal-id>:rwx in the returned acl field.
Note
If you re-deploy the template, the agent MIs may receive a new name (the <UniqueNumber> suffix changes). The old MI’s ACL entries will still be on the storage paths but they are harmless — they reference a now-deleted principal. To clean up stale entries:
az storage fs access remove-recursive \
--account-name <storage-account> -f <container> -p user \
--acl "user:<stale-principal-id>" --auth-mode login
Grant Key Vault Access to the Agent MIs
The Dialogs Agent MI needs get, wrapKey, unwrapKey, encrypt, decrypt on the Key Vault keys. The Code Executor MI (if deployed) needs get, unwrapKey, decrypt (read-only crypto operations on encrypted data).
How you grant this depends on the Key Vault's permission model. Note: for Vault-access-policy Key Vaults, the deployment adds these entries automatically when 'Is Encryption enabled' is on, so this section is mainly a fallback (or for verification). For Azure RBAC Key Vaults, the automatic step does not apply and you must grant access manually as below.
Determine your Key Vault’s permission model
Navigate to the Key Vault in the Azure portal.
Open Access configuration in the left blade.
Note the value of Permission model — either Vault access policy (legacy) or Azure role-based access control (RBAC).
If the Key Vault uses Vault access policy
Permission required: Owner or Contributor on the Key Vault, or any role that can add access policies (e.g. Key Vault Administrator).
In the Key Vault, open Access policies.
Click + Create.
Permissions tab → under Key permissions:
Dialogs Agent MI: check Get, Wrap Key, Unwrap Key, Encrypt, Decrypt.
Code Executor MI (separate policy): check Get, Unwrap Key, Decrypt.
Leave Secret permissions and Certificate permissions blank. Click Next.
Principal tab → search for the agent MI by name → select it → Next.
Application (optional) tab → leave blank → Next.
Review + create → Create.
Repeat for the Code Executor MI if applicable. Each MI gets its own policy entry.
If the Key Vault uses Azure RBAC
Permission required: User Access Administrator (or any role that can assign Azure RBAC roles on the Key Vault).
In the Key Vault, open Access control (IAM).
Click + Add → Add role assignment.
For the Dialogs Agent MI:
Role tab → search and select Key Vault Crypto User.
Members tab → Assign access to Managed identity → + Select members → pick the Dialogs Agent MI → Select.
Review + assign.
Repeat for the Code Executor MI:
Role tab → Key Vault Crypto User also covers the read-only ops the Code Executor needs.
Alternatively, for least privilege, assign Key Vault Crypto Service Encryption User (grants only unwrapKey).
Members tab → select the Code Executor MI → assign.
Verification
Run one of the following from any machine with management-plane access to the Key Vault.
Vault access policy mode:
az keyvault show --name <vault-name> \
--query "properties.accessPolicies[?objectId=='<dialog-mi-principal-id>'].permissions.keys" \
--output tsv
# Expected output: get wrapKey unwrapKey encrypt decryptRBAC mode:
az role assignment list \
--assignee <dialog-mi-principal-id> \
--scope /subscriptions/<sub-id>/resourceGroups/<vault-rg>/providers/Microsoft.KeyVault/vaults/<vault-name> \
--query "[].roleDefinitionName" --output tsv
# Expected output: Key Vault Crypto User
Secret access policy (automatic)
Separately from the key permissions above, when a Vault name is supplied the deployment automatically adds an access policy that grants the Dialogs Agent MI get and list on the Key Vault secrets (the accessPolicy-dialogs-kv-secret-* deployment). No manual action is required — this note is for reference only. The manual step in 2.2 still leaves Secret permissions blank, because secrets are handled by this automatic policy entry.
To verify (vault access policy mode:
az keyvault show --name <vault-name> \
--query "properties.accessPolicies[?objectId=='<dialog-mi-principal-id>'].permissions.secrets" \
--output tsv
# Expected output: get list
After both manual steps are complete
The agent VMSS bootstrap downloads its bundle and venv on first boot. If the ACLs or KV access policies were missing at boot time, the agents will have failed silently. To trigger a fresh bootstrap on existing instances:
Navigate to the agent VMSS (e.g. kyvos-dialogs-agent-<UniqueNumber>)
Open Instances → select the VM → Reimage.
Or, for a fresh deployment, scale the VMSS from 0 → 1 (since sku.capacity = 0 by default):Scaling blade → Manual scale → set instance count to 1 → Save.
The first instance will boot, pick up the new ACLs and KV access, and start the agent.
Quick-reference checklist
Collected MI principal IDs for Dialogs Agent (and Code Executor if applicable)
Created the directory tree under /user/engine_work/ if any paths didn’t exist
Applied access ACLs on all paths in the ACL Model (shallowest → deepest)
Applied default ACLs on tmp, saved, logs directories
Verified one ACL via az storage fs access show or the portal
Determined Key Vault permission model (access policy vs RBAC)
Added Dialogs Agent MI to Key Vault with get, wrapKey, unwrapKey, encrypt, decrypt
Added Code Executor MI to Key Vault with get, unwrapKey, decrypt (if deployed)
Confirmed the automatic secret access policy grants the Dialogs Agent MI get, list on Key Vault secrets
Scaled the VMSS up or reimaged existing instances to trigger a fresh bootstrap