Skip to content

Corporate Tenant Registry

ENTERPRISE Feature

The Corporate Tenant Registry requires an ENTERPRISE license. It is not available on STARTER or PRO tiers.

Manage multiple Azure AD (Entra ID) tenants that belong to the same organisation. CertifyClouds discovers, monitors, and rotates credentials across all of them from a single deployment.


Overview

A typical enterprise spans more than one Entra ID tenant: a primary ("home") tenant for day-to-day operations and additional tenants for subsidiaries, acquired companies, geographic regions, or environment boundaries (dev / staging / production). The Corporate Tenant Registry lets you onboard those additional tenants so CertifyClouds can:

  • Discover and monitor Key Vault secrets, certificates, and keys across every onboarded tenant
  • Rotate App Registration credentials in any onboarded tenant
  • Surface all assets in the unified inventory with a per-tenant badge
  • Alert on expiring credentials regardless of which tenant they live in

Corporate Tenants vs B2C Registry

Aspect Corporate Tenant Registry B2C Registry
Tenant type Full Entra ID / Azure AD tenants with Azure subscriptions and Key Vaults Azure AD B2C tenants (identity-only, no Key Vaults)
What is discovered Key Vault secrets, certificates, keys, and App Registration credentials App Registration secrets and certificates
Rotation Key Vault secrets / certificates / keys + App Reg credentials App Reg credentials only
License ENTERPRISE PRO or ENTERPRISE

One organisation, multiple tenants

The Corporate Tenant Registry is for a single organisation that spans multiple Entra ID tenants. It is not a multi-customer isolation model. CertifyClouds runs as one deployment; the registry extends its reach across your organisation's tenant boundary.


Concepts

Home tenant

The tenant in which CertifyClouds itself is deployed. Its Managed Identity (or Service Principal) is the deployment credential. The home tenant is added to the registry automatically at first start; you cannot delete it. Discovery, rotation, and sync for home-tenant assets use the deployment credential as before.

Onboarded tenant

Any additional Entra ID tenant you register in the Corporate Tenant Registry. Each onboarded tenant gets its own dedicated Service Principal (provisioned by the onboarding script) whose client secret is stored encrypted at rest. Credential operations on onboarded-tenant assets always use that tenant's own credential - they never reuse the home deployment credential.

Credential routing

Every Azure write operation resolves its credential at the point of execution:

  • Home assets use the deployment credential.
  • Onboarded-tenant assets use the per-tenant ClientSecretCredential, wrapped in a bounded wrapper that enforces a wall-clock timeout per token acquisition. Credentials are cached with tenant-scoped keys so SP rotation invalidates the cache automatically.

Before any write is executed, the platform verifies that the credential's actual token tid matches the intended tenant. A mismatch is a hard refusal - the write is never sent.


Prerequisites

  • ENTERPRISE license (the multi_tenant feature entitlement)
  • Azure CLI (az) installed on the machine running the onboarding script
  • jq installed (brew install jq on macOS, apt install jq on Debian/Ubuntu)
  • Admin access in the target (onboarded) Entra tenant to create an App Registration and grant admin consent for Microsoft Graph permissions

Step 1: Provision the Service Principal (onboarding script)

Run onboard-corporate-tenant.sh (included in your CertifyClouds delivery package; contact support@certifyclouds.com if your package predates it) in the target tenant to create the App Registration, Service Principal, client secret, and role assignments CertifyClouds needs.

Sign in to the target tenant

The Azure CLI creates App Registrations in the tenant of the current session. You must sign in to the target tenant before running the script:

az login --tenant <TARGET_TENANT_GUID> --allow-no-subscriptions

The script validates that your current session matches --tenant and refuses to run if they differ, preventing accidental provisioning in the wrong directory.

Preview first (no changes)

By default the script is a dry run - it prints every az command it would execute without making any changes:

./onboard-corporate-tenant.sh --tenant <TARGET_TENANT_GUID>

Review the output, then add --apply to actually provision:

./onboard-corporate-tenant.sh --tenant <TARGET_TENANT_GUID> --apply

Flags

Flag Purpose
--tenant <guid> (Required) Target Entra tenant GUID
--apply Execute the changes. Without this the script only previews
--with-rotation Also grant write permissions for credential rotation (see below)
--with-resource-updates Also grant Contributor on consuming resources for full-stack rotation (opt-in, broad)
--subscription <guid> Scope role grants to one subscription. Repeatable. Omit to grant across all subscriptions in the target tenant
--display-name <name> App Registration display name. Default: CertifyClouds Corporate Tenant Workload (Production)

Grants by mode

Grant Scope Purpose
Reader Subscription Enumerate subscriptions, vaults, resources
Key Vault Reader Subscription Read vault and secret/certificate/key metadata
Microsoft Graph Application.Read.All Tenant-wide Read App Registrations and Service Principals

All discovery grants, plus:

Grant Scope Purpose
Key Vault Secrets Officer Subscription Create/update secret versions
Key Vault Certificates Officer Subscription Create/update certificate versions
Key Vault Crypto Officer Subscription Rotate keys, KV-to-KV replication
Microsoft Graph Application.ReadWrite.All Tenant-wide Rotate App Registration credentials

All rotation grants, plus:

Grant Scope Purpose
Website Contributor Subscription Update App Service configuration after rotation
SQL Server Contributor Subscription Update SQL Server connection strings after rotation
Container Apps Contributor Subscription Update Container Apps secrets after rotation
Logic App Contributor Subscription Update Logic App connections after rotation

Subscription-scoped write access

The write roles above are granted at subscription scope, meaning they cover every resource of that type in the subscription. If your security policy requires least-privilege, re-create the role assignments at resource-group or vault scope after provisioning and remove the subscription-scoped ones.

Application.Read.All (and Application.ReadWrite.All when --with-rotation is used) are application permissions that require tenant-wide admin consent from a Global Administrator. The script attempts to grant consent automatically. If your account lacks that role, it prints the portal steps to hand to an admin:

  1. Azure Portal > Microsoft Entra ID > App registrations
  2. Open the app (e.g. CertifyClouds Corporate Tenant Workload (Production))
  3. Go to API permissions
  4. Click Grant admin consent for [Tenant Name] and confirm

Key Vault and subscription discovery work without consent. App Registration discovery in the onboarded tenant requires consent before it returns results.

Script output

On a successful --apply run, the script prints the values to paste into the CertifyClouds UI:

  Tenant ID (GUID):     xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
  Tenant domain:        yourcompany.onmicrosoft.com
  App (client) ID:      yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
  Client secret:        <secret value>
  Secret expires:       <date>

Copy the client secret now

The client secret value is shown once and cannot be retrieved again. Copy it immediately into the CertifyClouds form, or store it in a vault.

Key Vault firewalls on onboarded tenants

CertifyClouds can enumerate a Key Vault resource with Azure RBAC while still receiving data-plane 403 (ForbiddenByFirewall) responses when it tries to list secrets, certificates, or keys. If the vault firewall is off (properties.networkAcls.defaultAction is Allow, or the vault has no network ACLs), there is nothing to configure. If it is Deny, grant the CertifyClouds deployment a network path using one of the three options below. All three keep the vault firewalled to everyone else.

Which option to choose:

Your situation Use
Deployment subnet has the Microsoft.KeyVault service endpoint (the usual case — it does whenever your home-tenant vaults use subnet rules) Option 1 — virtual-network rule (recommended, simplest)
Deployment subnet has no service endpoint, and you can route outbound through a stable public IP Option 2 — NAT gateway + IP allowlist
You need a fully-private path (no public Key Vault endpoint at all), or neither of the above fits Option 3 — Private Endpoint

Option 1 (recommended): cross-tenant virtual-network rule

A Deny vault admits CertifyClouds when its networkAcls.virtualNetworkRules lists the subnet the CertifyClouds deployment runs on. The subnet lives in your home (deployment) tenant; the vault lives in the onboarded tenant. Because the Corporate Tenant Registry is one organisation spanning several Entra tenants (not separate companies), an administrator with rights in both tenants adds the rule directly — Key Vault virtual-network rules do work across the Entra tenants of one organisation.

The Azure portal can't add this rule: its "Add a virtual network" picker only lists subnets in the vault's own subscription, so a cross-tenant deployment subnet cannot be selected there. Add it with the CLI below (or the onboarding script), using the subnet's full resource ID.

Prerequisite: the deployment subnet has the Microsoft.KeyVault service endpoint enabled (already true whenever your home-tenant vaults use subnet rules).

az keyvault network-rule add \
  --name <onboarded-vault> \
  --subscription <onboarded-subscription> \
  --subnet "/subscriptions/<home-sub>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<deployment-subnet>"

The onboarding script automates this: ./onboard-corporate-tenant.sh --tenant <GUID> --subnet <deployment-subnet-id> --apply.

Keep defaultAction=Deny — the rule grants access only to the CertifyClouds subnet, so the vault stays firewalled to everyone else while CertifyClouds reads its secrets, certificates, and keys using the onboarded tenant's Service Principal.

Option 2: NAT gateway + public IP allowlist

Key Vault IP rules only match a public source IP. That works only when the deployment subnet does not have the Microsoft.KeyVault service endpoint — otherwise traffic reaches the vault over the Azure backbone with no public source IP (the audit log shows CallerIPAddress 0.0.0.0) and an IP rule can never match.

To use IP allowlisting deliberately: attach a NAT gateway with a static public IP to the deployment subnet (and do not enable the Key Vault service endpoint on that subnet), so all outbound traffic egresses via that one stable IP. Then allowlist it:

# find the deployment's stable egress IP (NAT gateway public IP; Container Apps: outboundIpAddresses)
az containerapp show --name <app> --resource-group <rg> --query properties.outboundIpAddresses
az keyvault network-rule add --name <onboarded-vault> --subscription <onboarded-subscription> --ip-address <egress-ip>/32

The onboarding script automates the IP-rule add: ./onboard-corporate-tenant.sh --tenant <GUID> --ip-address <egress-ip>/32 --apply. Note: Azure Container Apps NAT-gateway/custom egress requires a workload-profile environment; a consumption-only environment has a large rotating egress pool that cannot be allowlisted, so use Option 1 or 3 there.

Option 3: cross-tenant Private Endpoint (fully private)

Gives the onboarded vault a private IP inside your deployment VNet, so the vault can disable public network access entirely and CertifyClouds still discovers and reads its contents over the private endpoint.

  1. Create a Private Endpoint in the CertifyClouds deployment VNet (a dedicated subnet with private-endpoint network policies disabled), targeting the onboarded-tenant vault, in manual-request mode.
  2. A Key Vault admin in the onboarded tenant approves the pending private-endpoint connection.
  3. Add a privatelink.vaultcore.azure.net private DNS zone linked to the deployment VNet, with an A record for the vault name pointing at the Private Endpoint's private IP, so the deployment resolves the vault privately.
  4. Optionally set the vault's publicNetworkAccess to Disabled once the Private Endpoint is confirmed working.

This is a multi-party manual flow (two tenants, DNS), so it is not automated by the onboarding script — follow the steps above per vault.

Symptom of a missing network path

Vaults appear in discovery, but the items inside them show zero results, or discovery logs show Key Vault data-plane 403 (ForbiddenByFirewall) responses.


Step 2: Register the tenant in CertifyClouds

  1. Go to Settings > Corporate Tenants
  2. Click Add Tenant
  3. Enter the values from the script output:

    Field Value
    Tenant ID Target tenant GUID
    Tenant Domain e.g. yourcompany.onmicrosoft.com
    Display Name A friendly name for the tenant
    Client ID App Registration (client) ID
    Client Secret Secret from the onboarding script
  4. Click Test Connection to verify. A successful test confirms CertifyClouds can authenticate to the tenant.

  5. Click Register Tenant to save.

Step 3: Run discovery

After registering a tenant, trigger an initial discovery scan:

  • All tenants at once: go to Assets > Discovery and click Start Scan. The scan runs across the home tenant and all active onboarded tenants sequentially.
  • Via the API: POST /api/assets/discovery/scan with { "corporateTenantId": <id> } to scan a single onboarded tenant.

Discovered assets are tagged with their owning tenant. The unified inventory shows all assets together; filter by tenant using the tenant switcher in the header or the corporateTenantId filter on the Assets page.


Per-tenant discovery

The platform discovers each onboarded tenant using that tenant's own Service Principal credential. The home subscription allow-list does not apply to onboarded-tenant scans - each onboarded tenant is scanned across all subscriptions visible to its Service Principal.

Assets inherit their tenant from their subscription: after a scan, each asset's corporate_tenant_id is set to match the subscription it lives in. This tag propagation is idempotent and only updates rows whose tag is stale.


Per-tenant rotation

Rotation for onboarded-tenant assets follows the same flow as home-tenant rotation (confirm dialog, real-time progress stream, grace window, history entry with a tenant badge), with the routing layer ensuring the correct credential is used:

  1. The rotation engine resolves which tenant owns the operation's legs (vault, subscription, App Registration). If any leg belongs to an onboarded tenant, the routing resolves to that tenant's credential.
  2. Before each Azure write, the token tid is verified to match the intended tenant. A mismatch is a hard refusal.
  3. The rotation record is stamped with the resolved corporate_tenant_id so the history table reflects which tenant was written.

Cross-tenant operations (where rotation legs span more than one tenant) are refused. Each rotation job is single-tenant.


Tenant isolation model

Layer Isolation mechanism
Credential storage Per-tenant SP client secret stored encrypted at rest. The home tenant has no stored secret; it uses the deployment credential.
Credential routing Every Azure write resolves its credential from the tenant tag on the target resource. The home credential is never used for onboarded-tenant writes.
Token verification Before each write, the platform decodes the acquired token's tid claim and refuses if it does not match the intended tenant.
Discovery isolation Each onboarded tenant is scanned with its own credential. The vanished-asset reconcile is scoped to (subscription, vault), so a scan for one tenant never disables assets belonging to another.
Scope Within-organisation isolation: prevents wrong-tenant writes. Not a network isolation or data-residency boundary.

Service Principal expiry

The onboarded tenant's Service Principal secret has a 2-year validity by default. The tenant card in Settings > Corporate Tenants shows the expiry date alongside a status badge so you can see at a glance when renewal is due.

CertifyClouds does not currently monitor this expiry or rotate it automatically. Set a calendar reminder before the expiry date. If the secret expires, discovery and rotation for that tenant will fail until it is renewed by re-running the onboarding script with --apply and updating the client secret in the tenant registration form in the UI.


Troubleshooting

Symptom Likely cause Resolution
"Connection failed" on test Wrong Client ID or secret Re-run the onboarding script with --apply to mint a fresh secret
No App Registrations discovered Admin consent not granted Grant consent in the Azure portal (API permissions page)
Assets not appearing for onboarded tenant Discovery not run after registration Run a scan from Assets > Discovery
Rotation refused for onboarded-tenant asset --with-rotation grants not provisioned Re-run the onboarding script with --with-rotation --apply
"Multi-tenant rotation is disabled" Operational kill-switch off Enable the ENABLE_MULTI_TENANT_ROTATION flag under Settings > Advanced > App Behaviour
"Tenant not on allowlist" Tenant allowlist configured Add the tenant GUID to the MULTI_TENANT_ALLOWLIST environment variable on the deployment (a JSON array of tenant GUIDs, e.g. ["<guid>"]). Unset or empty means all onboarded tenants are allowed — this only appears if your deployment set the variable.

Security best practices

  1. Least privilege: use --with-rotation only if you need CertifyClouds to rotate credentials in that tenant. Discovery-only onboarding does not require write grants.
  2. Rotation write grants are subscription-scoped: after onboarding, narrow them to a resource group or vault if your security policy requires least-privilege.
  3. Monitor SP expiry: the onboarded tenant's SP secret expires in 2 years. The expiry date is shown on the tenant card. Set a calendar reminder and renew by re-running the onboarding script with --apply, then updating the client secret in the tenant registration form.
  4. Review access: periodically review the CertifyClouds App Registration in each onboarded tenant's Azure portal to confirm permissions remain as expected.

  • B2C Registry - monitor App Registration credentials in Azure AD B2C tenants
  • Secret Rotation - rotation mechanics for Key Vault secrets and App Registrations
  • Asset Discovery - how CertifyClouds scans your Azure estate