> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lumos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Entra ID (NHI)

## What You're Setting Up

You're registering a read-only OAuth application in your Microsoft Entra tenant that Lumos uses, via the OAuth 2.0 client credentials grant, to call Microsoft Graph. Lumos uses that registration to inventory non-human identities in your tenant and surface non-human-identity risk.

**What Lumos does NOT do:**

* **No data-plane access** — Lumos never reads mailboxes, OneDrive/SharePoint files, Teams messages, calendar contents, or any user-owned data. None of the permissions below grant access to that data.
* **No writes** — every permission requested is a read permission. Lumos cannot create, modify, or delete users, groups, apps, role assignments, or policies.
* **No secret-value reads** — Lumos reads app credential *metadata* (key IDs, expiry dates, types) but cannot retrieve client-secret values or certificate private keys.
* **No conditional-access bypass or role elevation** — the app cannot assign itself additional roles or grant itself consent.

Every Graph call Lumos makes is available in your Entra Audit Logs so you can audit exactly what ran.

***

## Prerequisites

Before you start, make sure you have:

* A **Global Administrator** or **Privileged Role Administrator** in the Entra tenant you want to connect (required to grant admin consent for application permissions).
* The Lumos integration page open — you'll paste **Client ID**, **Client Secret**, and **Tenant ID** into it at the end.
* For full finding coverage, no extra Entra add-ons are required, but the following enrich findings:
  * **Entra ID P1 or P2** — required to read conditional-access policies via `Policy.Read.All`. Without P1/P2 these findings won't surface.
  * **Sign-in logs retention** — Lumos relies on `AuditLog.Read.All` for inactivity and active-compromise signals. Default retention is 7 days (free) / 30 days (P1+); longer retention yields better dormant-account detection.
  * Optional, for last-updated timestamps: Entra's directory audit logs are the only place Microsoft exposes a modification time for service principals, federated identity credentials and synchronization secrets. How far back Lumos can populate those timestamps depends on how long your tenant retains audit events, which depends on your Entra plan. Leaving this off costs you one field and nothing else.
  * **Custom security attributes** — if your org uses them to classify workload identities, Lumos will incorporate them via `CustomSecAttributeDefinition.Read.All` and `CustomSecAttributeAssignment.Read.All`.
* If you're connecting multiple tenants, repeat this setup per tenant.

***

## Step 1 — Register the application

1. Go to the [Microsoft Entra admin center](https://entra.microsoft.com/).
2. Navigate to **Entra ID → App registrations** and click **New registration**.
3. Set a **Name** (e.g. `Lumos NHI Read-Only`).
4. Under **Supported account types**, select **Single tenant only — \<your organization>**.
5. Under **Redirect URI**, select **Web** and enter:

```plaintext theme={null}
https://app.lumosidentity.com/integrations/ics_oauth2_callback
```

6. Click **Register**.
7. From the app's Overview page, copy the **Application (client) ID** — you'll paste it into Lumos in Step 5.

## Step 2 — Configure API permissions

1. Open the app you just registered → **Manage → API permissions**.

2. Click **Add a permission → Microsoft Graph → Application permissions** and add the permissions below:
   * `Application.Read.All`
   * `CrossTenantInformation.ReadBasic.All`
   * `Directory.Read.All`
   * `Policy.Read.All`
   * `RoleManagement.Read.Directory`
   * `Synchronization.Read.All`
   * `CustomSecAttributeDefinition.Read.All`
   * `CustomSecAttributeAssignment.Read.All`
   * `AuditLog.Read.All` — only if you plan to turn on **Populate Timestamps From Audit Logs** in Step 5

3. Click **Grant admin consent for \<your organization>** and confirm. The status column should turn green for all nine entries.

You can grant fewer than the full list. **Tailoring the permissions** below details what purpose each serves and what stops working without it.

> A note on the read-only model: every permission above ends in `.Read.*` or `.ReadBasic.*`. There is no `.ReadWrite.*` and no `Directory.AccessAsUser.All` — Lumos has no path to modify your directory or impersonate users.

## Step 3 — Create the client secret

1. In the app → **Manage → Certificates & secrets**.
2. Click **New client secret**.
3. Set a **Description** (e.g. `Lumos NHI`) and an **Expiration** (Microsoft caps this at 24 months — note the expiry; you'll need to rotate before then).
4. Click **Add**, then **immediately copy the Value** (not the Secret ID — the *Value*). It's only shown once.

## Step 4 — Collect the Tenant ID

1. In the Entra admin center, go to **Entra ID → Overview** (or **Tenant properties**).
2. Copy the **Tenant ID**.

## Step 5 — Connect in Lumos

1. In the Lumos app, go to **Integrations → Add Integration** and search for **"Microsoft Entra ID (NHI)"**.
2. Paste the values you collected:
   * **Client ID** — Application (client) ID from Step 1
   * **Client Secret** — secret Value from Step 3
   * **Tenant ID** — Tenant ID from Step 4
3. **Populate Timestamps From Audit Logs (optional)** — off by default. Turn it on only if you granted `AuditLog.Read.All` in Step 2. With it on, Lumos reads Entra's directory audit logs to fill in last-updated timestamps for service principals, federated identity credentials and synchronization secrets.

***

## Scan behavior

* **Cadence:** Follows the NHI security agent configuration. Lumos does not pull Entra data on a fixed schedule by default unless the agent is configured to run on one.
* **Token lifetime:** each scan acquires a short-lived Microsoft Graph access token via OAuth client credentials grant (typically 1 hour). Tokens are not persisted across scans; the client secret is the only long-lived credential and is stored encrypted at rest.
* **Agent identities:** Lumos reports Entra Agent ID service principals (service principal type `ServiceIdentity`) with their own type instead of `unknown`.
* **Federated identity credentials:** each federated identity credential on a service principal, such as a GitHub Actions trust, appears as its own `FederatedPrincipal` non-human account. The account is named after the credential, takes its status from its service principal, and is linked to the service principal it signs in as. A flexible credential with no fixed subject appears as a wildcard account. Credentials issued by an AKS cluster are treated as pods, not external identities. Lumos shows them in the access graph as AKS service accounts that run as the service principal.
* **Managed identities:** a system-assigned managed identity reports the Azure resource it belongs to as its workload. When that resource is a compute host, such as a virtual machine, App Service app or container app, Lumos also adds the host to the access graph as the workload that runs as the identity.
* **Audit log reads:** when **Populate Timestamps From Audit Logs** is on, Lumos queries Entra's directory audit endpoint at a much lower rate than the rest of the scan — Microsoft caps the identity reporting endpoints at 5 requests per 10 seconds per app per tenant — so enabling it lengthens a scan in proportion to how many identities you have.

***

## Tailoring the permissions

The first three permissions are required to connect, while the remainder can be customized. Permissions labelled with "NHI security agent" power agent findings and do not install data via syncs.

| Permission | Covers | Impact if removed |
| :- | :- | :- |
| `Application.Read.All` | Service principals, applications, federated identity credentials, owners, and app role assignments | Required. The identity inventory, including federated identity credential accounts, and most credential findings disappear |
| `CrossTenantInformation.ReadBasic.All` | Resolves your tenant and marks each service principal as homed in your tenant or external to it | Required. The connection cannot validate |
| `Directory.Read.All` | The directory objects used to resolve principals, plus the `oauth2PermissionGrants` endpoint | Required. Principal resolution and over-broad consent-grant findings both fail |
| `Policy.Read.All` | Conditional access policies | Conditional-access gap findings. Already inert without Entra ID P1 or P2, since lower tiers have no conditional-access policies to read |
| `RoleManagement.Read.Directory` | Directory role definitions and role assignments | View of which non-human identities hold Global Administrator and similar roles for privileged-role findings |
| `Synchronization.Read.All` | Provisioning secrets held by individual service principals | Synchronization secrets stop appearing, and stale or expiring sync-credential findings go with them |
| `AuditLog.Read.All` | Sign-in and directory audit events | Inactivity, dormant-account and active-compromise findings |
| `CustomSecAttributeDefinition.Read.All` | Workload-identity classification definitions | NHI security agent —Findings are no longer enriched with your classifications. No effect if your org doesn't use custom security attributes |
| `CustomSecAttributeAssignment.Read.All` | Which workload identities carry which classification | NHI security agent — Same as above;  enrichment only |

***

## Security FAQ

\*\*Does Lumos access data inside my tenant (mailboxes, files, Teams messages)? \*\*

No. The permissions above are all directory- and policy-metadata reads against Microsoft Graph. None of them grant access to Mail, Files, Sites, Chat, Calendar, or any user-owned content. There is no `Mail.Read`, `Files.Read.All`, `Sites.Read.All`, `Chat.Read.All`, or `Calendars.Read` in the ask.

\*\*Does Lumos read client-secret values or certificate private keys? \*\*

No. `Application.Read.All` returns credential *metadata* — key ID, hint, display name, type, start/end dates. The secret value and private key material are never returned by Microsoft Graph to any caller after creation.

\*\*Does Lumos read raw audit logs and exfiltrate them? \*\*

Lumos reads sign-in and directory audit logs via `AuditLog.Read.All` to surface inactivity, anomalous sign-ins, and compromise indicators. Findings are derived in Lumos; raw log bodies are not retained beyond what's needed to generate the finding.

**Why does Lumos need **`Directory.Read.All`** instead of something narrower?** `Directory.Read.All` is the Microsoft-blessed least-privilege permission for inventorying the directory graph (users, groups, basic org info) as application-permission scope. The narrower `User.Read.All` + `Group.Read.All` combination is broader for delegated scenarios but does not cover all the directory-object types Lumos needs to resolve principals against role assignments and consent grants.

**How are credentials handled?**

 Lumos stores the customer-provided **Client Secret** encrypted at rest. At scan time, Lumos exchanges it for a short-lived Graph access token via the OAuth 2.0 client credentials grant (token lifetime \~1 hour). No long-lived tokens are stored. Rotate the secret in Entra and update it in Lumos as part of your normal credential-rotation schedule, or sooner if compromise is suspected.

\*\*Can I scope the permissions down further? \*\*

Yes, within limits. **Tailoring the permissions** above lists what each one covers and what stops working without it. Three are required to connect at all; the rest each map to a finding category you can choose to give up. Your Lumos account team can walk through the trade-offs.

\*\*Can I remove the integration later? \*\*

Yes. Either delete the client secret, delete the app registration, or revoke admin consent in **Enterprise applications → \<app name> → Permissions → Remove all permissions**. The next Lumos scan fails and Lumos surfaces a "connection lost" banner in the integration UI. No data exfiltration is possible once consent is revoked.
