Skip to main content

What you’re setting up

You’re registering a read-only application in your Microsoft Entra tenant and giving it the built-in Reader role in Azure. Lumos signs in as that application with the OAuth 2.0 client credentials grant and reads Azure Resource Manager (ARM), mostly through Azure Resource Graph. Lumos uses it to inventory the non-human identities that hold Azure RBAC roles: managed identities, agent identities and other service principals, the workloads they run on, and the roles, actions and data actions they hold at each scope. There is no custom policy to write. Reader is the only role the connection needs, and you decide what Lumos scans by where you assign it. Recommended setup. Reader assigned to the app on the Tenant Root Group. That covers every subscription in the tenant, including ones created later, and it’s the setup the steps below walk through. To give Lumos less, see Reducing access for what each reduction costs. What Lumos does NOT do:
  • No writes. Reader grants */read on the control plane and nothing else. Lumos cannot create, change or delete resources, role assignments or policies.
  • No content reads. Lumos does not query blob contents, Key Vault secrets, keys or certificates, database rows, queue messages or logs. Reader carries no data actions, though it allows more control-plane reads than Lumos makes. What the Reader role is used for lists every read Lumos makes.
  • No key listing. Calls such as a storage account’s listKeys are actions outside */read, so Reader cannot retrieve storage keys, connection strings or SAS rules.
  • No Microsoft Graph access. The app requests only the https://management.azure.com/.default scope. It needs no Graph permissions and no admin consent. The default User.Read permission on a new registration isn’t used and can be removed.

Prerequisites

Before you start, make sure you have:
  • Application Developer (or higher) in Microsoft Entra, to register the app.
  • Owner, User Access Administrator or Role Based Access Control Administrator on the Tenant Root Group, to assign the Reader role. A Global Administrator without one of these can grant it to themselves with Access management for Azure resources (see Step 3).
  • The Lumos integration page open. You’ll paste the Tenant ID, Client ID and Client Secret into it at the end.
  • An Azure tenant in the global (commercial) Azure cloud. Azure Government and Azure China are not supported.
This integration reads Azure RBAC: which identities hold which roles, where. It does not read the credentials those identities authenticate with. Client secrets and certificates are stored in Microsoft Entra ID, not in Azure Resource Manager, and the Entra ID (NHI) integration reads them, along with the federated credentials on your service principals and managed identities. Connect both to see each identity’s Azure access alongside its credentials.

Step 1: Register the application

  1. Sign in to the Microsoft Entra admin center.
  2. Go to Entra ID → App registrations → New registration.
  3. Set a Name (e.g. Lumos Azure NHI Read-Only).
  4. Under Supported account types, select Single tenant only.
  5. Leave Redirect URI empty.
  6. Click Register.
  7. On the app’s Overview page, copy the Directory (tenant) ID and the Application (client) ID. You’ll paste both into Lumos in Step 4.

Step 2: Create the client secret

  1. In the app, go to Certificates & secrets → Client secrets → New client secret.
  2. Set a Description (e.g. Lumos Azure NHI) and an Expires date. Microsoft caps this at 24 months.
  3. Click Add, then copy the secret’s Value (not the Secret ID). It is shown only once.
When the secret expires Lumos can no longer connect. Create a new secret before the expiry date and paste it into the integration.

Step 3: Assign the Reader role on the Tenant Root Group

Lumos scans whatever the Reader assignment reaches. The Tenant Root Group is the management group above every other management group and subscription in the tenant, so Reader there covers every subscription, including ones created later.
  1. In the Azure portal, go to Management groups and open the Tenant Root Group.
  2. Go to Access control (IAM) → Add → Add role assignment.
  3. On the Role tab, choose Reader and click Next.
  4. On the Members tab, choose User, group, or service principal, click Select members, and search for the app by name.
  5. Click Review + assign.
Lumos checks that the app can read at least one whole subscription: every resource type, plus the subscription’s role assignments and role definitions. Reader on the subscription or on a management group above it passes, whether it’s assigned to the app directly or to a group the app belongs to. A broader role such as Contributor or Owner, or a custom role that reads every resource type, also passes. Reader assigned only on resource groups or individual resources does not. If you are a Global Administrator without an Azure role. In the Azure portal, go to Microsoft Entra ID → Properties, set Access management for Azure resources to Yes, and save. Sign out and back in to pick up the change. This gives you User Access Administrator at the root scope /, which lets you assign Reader on the Tenant Root Group or anywhere below it. Set it back to No once the assignment is made. Optional: Reader at the root scope /. The Tenant Root Group is a management group, not the root scope / above it. Role assignments made on tenant-level services, such as /providers/Microsoft.Capacity, are visible only to an app that holds Reader at /. Without it, everything else is unaffected; those assignments just don’t appear in Lumos. Role assignments made at / itself and on management groups don’t need this: Lumos sees them with Reader on any subscription below them. The portal can’t assign roles at /, so use the Azure CLI:
  1. Turn on Access management for Azure resources as described above, then sign out and back in.
  2. Run the following, with the Application (client) ID from Step 1:
  3. Set Access management for Azure resources back to No.
Azure Resource Graph takes a short time to reflect a new role assignment (under a minute in our testing). If validation in Step 4 says the app can’t see any Azure subscriptions, wait a few minutes and try again.

Step 4: Connect in Lumos

  1. In the Lumos app, go to Integrations, open the Discover tab, and search for “Microsoft Azure (NHI)”.
  2. Paste the values you collected:
    • Tenant ID: Directory (tenant) ID from Step 1
    • Client ID: Application (client) ID from Step 1
    • Client Secret: secret Value from Step 2
  3. Select Connect. When Connected appears, select Complete.
When Azure is reachable, Lumos checks the credentials and the app’s access before saving. If Azure is throttling requests or unavailable at that moment, Lumos saves the connection without finishing the check; if the first sync then fails or comes back empty, recheck Step 3. When the check fails, the message names what to fix: After you connect, the connector’s “Integrations” tab shows its sync status. Synced means the first run completed. See NHI Connector Sync Status for what each status means.

What Lumos inventories

Non-human accounts Service principals with no Azure role assignment are not listed. The Entra ID (NHI) integration lists service principals from the directory, whether or not they hold an Azure role. Workloads. Lumos links a managed identity to the resource it runs on for these services: virtual machines and scale sets, Azure Arc servers, AKS clusters, App Service apps and slots, Container Apps and Container Apps jobs, Container Instances, Logic Apps, Data Factory, Automation accounts, API Management, AI Search, Batch pools, and Azure Machine Learning computes, online endpoints and batch endpoints. An identity on any other service is treated as its own workload. Roles and scopes. Lumos reads built-in and custom role definitions, the actions and data actions each role grants (wildcards kept as written), and the role assignments that place them on a scope. Scopes are modelled as a tree: the tenant root, management groups, subscriptions, resource groups, and individual resources, plus tenant-level services. A role assigned on a scope is shown as reaching every scope beneath it. Individual resources appear only when they matter for access: resources with a role assigned directly on them, resources a custom role is limited to, and workloads.

Sync behavior

  • Cadence: Lumos syncs this integration every 4 hours by default. To change the schedule, contact your Lumos account team. You can also start a sync at any time with “Sync” on the connector’s “Integrations” tab.
  • Authentication: Lumos uses the client secret to request short-lived ARM access tokens with the OAuth 2.0 client credentials grant.
  • How Lumos reads: almost every read is a tenant-wide Azure Resource Graph query, so Lumos makes one paged query per data set instead of one call per subscription. Azure Machine Learning computes are the exception: Resource Graph doesn’t index them, so Lumos reads them per ML workspace through ARM.
  • Rate limits: Resource Graph allows 15 queries per 5 seconds per caller. Lumos stays under that limit and retries when Azure throttles it.
  • Tenant size: if the app can read more than 10,000 subscriptions, the sync fails instead of returning partial data. Resource Graph only answers from the first 10,000 subscriptions, so a partial inventory would look complete when it isn’t.

What the Reader role is used for

Lumos uses a small part of what Reader allows. Resource Graph returns only what the app can already read, so the scope of your Reader assignment is the scope of the scan.

Reducing access

The recommended setup gives Lumos a complete inventory of the tenant. You can narrow it by where you assign Reader, at the cost listed below. A narrower role than Reader won’t help much: the connection check needs read access to every resource type on at least one whole subscription. With either change, Lumos still reads role assignments made at / and on the management groups above each scanned subscription.

Known limitations

  • No Entra credentials. Client secrets and certificates are stored in Microsoft Entra ID. They, and federated credentials, come from the Entra ID (NHI) integration, not this one.
  • No last activity. Every account shows as active. Azure exposes no status or last-used time for managed identities or service principals through ARM.
  • Roles held through an Entra group are not shown on the group’s member service principals. Resolving group membership needs Microsoft Graph, which this integration doesn’t call.
  • Access granted outside Azure RBAC is not read: Key Vault access policies, database Entra admins, and local keys or logins such as storage account keys, SAS rules, the Container Registry admin user and SQL logins. Identities that can retrieve a key still show through roles that include its listKeys action.
  • Role conditions (ABAC) are ignored. A role assignment with a condition is shown as granting the role in full, which can overstate access.
  • PIM-eligible role assignments are not shown. Only active assignments are read.
  • Deny assignments are not read.
  • New Foundry agents show their identity and roles but no workload, as they exist only in Foundry’s own API.
  • Child resources such as Automation runbooks are placed under their resource group, not under their parent resource.
  • Excluded actions (notActions) are listed, not subtracted. A role such as Contributor shows * as an implied action. The actions it excludes, such as the authorization writes, are listed in the role’s description in Lumos, not removed from what it implies.

Security FAQ

Does Lumos access data inside my Azure subscriptions (blobs, secrets, database rows)? No. Lumos reads only what What the Reader role is used for lists: subscriptions, the scope tree, resources with a managed identity, and role assignments and definitions. It does not query blob contents, Key Vault secrets, keys or certificates, database rows or logs. The built-in Reader role grants the */read control-plane actions and no data actions. Retrieving storage keys or connection strings needs actions such as listKeys, which are outside */read. Reader does allow more reads than Lumos uses, so the limit there is what Lumos calls, not what the role allows. Can I use a custom role instead of Reader? Yes, if it reads every resource type plus role assignments and role definitions on at least one whole subscription; the connection check fails otherwise. A custom role limited to some resource types doesn’t pass. Can I see what Lumos read? Partly. Azure’s Activity Log records changes and actions, not reads, so Lumos’s reads don’t appear there. Each time Lumos signs in as the app to get a token, Microsoft Entra records it under Service principal sign-ins in the sign-in logs. Entra keeps sign-in logs for 7 days on Entra ID Free and 30 days on P1 or P2. To keep them longer, route them to a storage account with Azure Monitor. How are credentials handled? Lumos stores the client secret encrypted at rest in its secrets manager, separately for each connection, and uses it to request short-lived ARM access tokens with the OAuth 2.0 client credentials grant. The secret is the only long-lived credential involved. Rotate it in Entra and update it in Lumos as part of your normal rotation schedule, or sooner if you suspect compromise. Can I limit what Lumos scans? Yes, by where you assign Reader. Reducing access lists the options and what each costs. Can I remove the integration later? Yes. Remove the app’s Reader assignment, delete the client secret, or delete the app registration. Once the change takes effect, Lumos’s reads fail. A removed role assignment can take several minutes to apply. Deleting the secret or the app doesn’t revoke an access token that was already issued; it stays valid until it expires, usually within 60 to 90 minutes.