Skip to content

Replication RBAC

Replication needs read permissions on the source vault and write permissions on the target vault. This page lists the Azure role assignments required, both the built-in roles (fastest) and a least-privilege custom role (recommended for production).

Verify against your tenant

The data actions listed below are the set CertifyClouds calls on the source and target vaults. Azure's live RBAC reference is authoritative, verify this list against your specific tenant configuration before relying on it as a compliance artifact.


Identity

Replication uses the same Azure identity CertifyClouds is already authenticated with: managed identity, service principal, or Azure CLI. There is no separate replication identity.

You can confirm which principal your deployment is using from Settings > Azure Identity, or via:

# For managed identity deployments
az vm identity show --resource-group <rg> --name <vm> --query principalId -o tsv

# For service principal deployments
echo $AZURE_CLIENT_ID

Replace PRINCIPAL_ID in the examples below with the output of the command above.


Required Data Actions

These are the exact data actions the engine invokes.

Source vault (read)

Operation Data Action
Read secret value Microsoft.KeyVault/vaults/secrets/getSecret/action
List secrets and soft-deleted secrets Microsoft.KeyVault/vaults/secrets/readMetadata/action
Read certificate metadata, list certificates and deleted certificates Microsoft.KeyVault/vaults/certificates/read
Download certificate with its private key (uses underlying secret) Microsoft.KeyVault/vaults/secrets/getSecret/action
Read key version (sync check), list keys and deleted keys Microsoft.KeyVault/vaults/keys/read
Back up a key Microsoft.KeyVault/vaults/keys/backup/action

Listing soft-deleted items has no separate data action: Key Vault authorises it with the same list permission as live items. CertifyClouds lists both live and soft-deleted items during every check so it can distinguish a recoverable source from a permanently missing one. If the soft-deleted-items listing is refused (403), the copy is kept, missed checks are held, and the sync queue shows Source check unavailable until a later check succeeds.

Target vault (write)

Operation Data Action
Set secret value Microsoft.KeyVault/vaults/secrets/setSecret/action
Read secret (conflict check) Microsoft.KeyVault/vaults/secrets/getSecret/action
Import certificate Microsoft.KeyVault/vaults/certificates/import/action
Read certificate (conflict check) Microsoft.KeyVault/vaults/certificates/read
Restore key from backup Microsoft.KeyVault/vaults/keys/restore/action
Read key (conflict and version checks) Microsoft.KeyVault/vaults/keys/read
Delete a secret copy (propagate deletes only) Microsoft.KeyVault/vaults/secrets/delete
Delete a certificate copy (propagate deletes only) Microsoft.KeyVault/vaults/certificates/delete

The two delete actions are needed only when propagate deletes is on. Without them a removal fails, the copy is kept, and the sync queue shows Removal pending with the Azure error until the permission is granted.

CertifyClouds never deletes a standalone key, so Microsoft.KeyVault/vaults/keys/delete is not required for replication and is deliberately not requested.

Both subscriptions (key replication: vault region)

Operation Action (control plane)
Look up each vault's Azure region, to confirm source and target share a geography before any key is replicated Microsoft.KeyVault/vaults/read

This is the one control-plane action replication uses, and only keys depend on it: the lookup lists the vaults of each subscription that hosts the source or target vault, so grant it on those subscriptions, not only on the vaults. The built-in Reader role includes it, and the standard CertifyClouds setup already assigns Reader on every scanned subscription. The Key Vault data-plane roles in both options below do not include it.

Without it, the region cannot be read: Validate connection reports "vault region could not be read" (code location_unresolved) naming the vault and subscription, and every key is held back with the reason "Azure region could not be read ... the identity needs Microsoft.KeyVault/vaults/read" instead of replicating. Secrets and certificates are unaffected. Once the permission is granted, Check now resolves the region straight away; worker checks otherwise retry the lookup at most once a day.

Replication never creates, deletes, or modifies the vaults themselves, only the items inside them.


Option A, Built-in Roles (fastest)

Fastest way to unblock yourself. Broader than strictly necessary.

Setup script grants these on --pro

setup-certifyclouds-access.sh --apply --pro already assigns Key Vault Secrets Officer, Key Vault Certificates Officer, and Key Vault Crypto Officer per vault, so a PRO deployment has the target-side replication roles. The manual commands below remain useful for granting only the source/target pair, or for custom least-privilege roles (Option B).

Source vault

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Secrets User" \
  --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<source-vault>

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Certificate User" \
  --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<source-vault>

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Crypto User" \
  --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<source-vault>

Target vault

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Secrets Officer" \
  --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<target-vault>

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Certificates Officer" \
  --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<target-vault>

az role assignment create \
  --assignee $PRINCIPAL_ID \
  --role "Key Vault Crypto Officer" \
  --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<target-vault>

Cert + secret overlap is expected

Azure stores the private key portion of certificates in the underlying secret store. The getSecret action appears on both the source and target data-action lists for this reason, it is not a duplicate, it's how certificate private keys are fetched.


Two custom roles, one for source, one for target, with exactly the data actions listed above and nothing else. Use these in production. If you replicate keys, the identity also needs Microsoft.KeyVault/vaults/read on both subscriptions (see above); these vault-scoped roles do not carry it.

JSON definitions

The canonical definitions live alongside this doc:

Deploy

  1. Download both files.

  2. Edit the AssignableScopes array in each file to your subscription IDs.

  3. Create the roles:

    az role definition create --role-definition custom-role-source.json
    az role definition create --role-definition custom-role-target.json
    
  4. Assign to your principal:

    az role assignment create \
      --assignee $PRINCIPAL_ID \
      --role "CertifyClouds Replication - Source" \
      --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<source-vault>
    
    az role assignment create \
      --assignee $PRINCIPAL_ID \
      --role "CertifyClouds Replication - Target" \
      --scope /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<target-vault>
    

Scope the assignment to individual vaults when you can, narrower blast radius.


Verifying

After role assignments, run the Validate connection step in the config wizard. It verifies CertifyClouds can read from the source vault and write to the target vault under the deployment's identity, surfaces the geography of each side, and lists any RBAC gaps or soft-deleted items it found. The wizard refuses to save until validation returns clean.

If issues are reported, see Troubleshooting for how to interpret each one.

RBAC propagation lag

Azure role assignments can take up to 5 minutes to propagate. If validate fails immediately after role assignment, wait a few minutes and retry before debugging further.


Known Scope Constraints

  • One control-plane action, for keys only. Microsoft.KeyVault/vaults/read on the source and target subscriptions resolves vault regions; everything else is data-plane.
  • No cross-subscription role design in v1. You assign at the vault level (or subscription level if you prefer) in each subscription that hosts a source or target vault.
  • Same identity for source and target. Source and target must use the same CertifyClouds identity; separate identities per subscription are not supported.
  • Tenant boundary is hard. Both vaults must be in the same Microsoft Entra ID tenant. Cross-tenant replication is not supported (see index).

Key data actions are listed in Azure permissions for Microsoft.KeyVault.