> ## 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.

# AWS IAM (NHI)

<Note>
  This integration is in Beta. Contact your Lumos team to have it enabled for your domain.
</Note>

## What You're Setting Up

You're creating a **read-only IAM role** in your AWS account that Lumos assumes via AWS STS using an External-ID-gated trust policy. Lumos uses this role to surface non-human-identity risk — over-privileged roles, weak OIDC trust, wildcard-principal trust policies, externally-shared resources, publicly-invokable Lambda Function URLs, unused access keys, abandoned IAM users, GuardDuty compromise signals, and more.

The policy is organised so that statements line up one-to-one with a setting in the integration UI: switch a workload off and you can delete its statement. The six statements prefixed `NHIAgent` have no setting — those are read by the NHI security agent and it produces findings without installing the data.

**What Lumos does NOT do:**

* **No writes** — every action is read-only.

* **No data-plane access** — Lumos never reads secret values, S3 objects, KMS encryption, DynamoDB rows, or log-stream contents.

* **No CloudTrail log-file access** — Lumos reads management-event history through the CloudTrail API, not from your CloudTrail S3 bucket, and only to establish when a workload last ran.

* **No role assumption beyond this scoped role.**

Every call Lumos makes lands in your CloudTrail so you can audit exactly what ran.

***

## Prerequisites

Before you start, make sure you have:

* **AWS IAM admin permissions** in the account you want to connect (or a role that can create IAM roles and policies).

* The **Service Role External ID** shown on your Lumos integration page (used in Step 2). Do not generate your own — Lumos issues a per-tenant value.

* For full finding coverage, enable these in every region you want scanned:
  * **IAM Access Analyzer** with **both analyzer types** configured: an **External Access** analyzer (Type `ACCOUNT` or `ORGANIZATION`) powers externally-shared-resource and public-resource findings; an **Unused Access** analyzer powers stale-access-key and abandoned-user findings.
  * **Amazon GuardDuty** for active-compromise and lateral-movement detection.
    Neither is required to connect or to sync. Leaving them off costs you the findings listed under the `NHIAgent` statements in the policy and nothing else.

* If you're connecting multiple AWS accounts: each needs its own role and connection. See the "Connecting many accounts at once" section for StackSet instructions. Include your Organization management or delegated-admin account so Lumos can tell org-sibling trust relationships apart from external ones. One connection covers every region in an account, so you don't need a separate connection per region.

***

## Step 1 — Create the IAM policy

In the AWS console: **IAM → Policies → Create policy → JSON**. Paste the policy below and name it `LumosNHIReadOnly-policy` (any name works).

The policy is split into one statement per integration setting so you can remove the services you do not want scanned. **If you remove a service, toggle its setting off in the integration UI as well.** Validate reports a toggled-on service with a missing permission as a setup error; a sync with the setting left on fails with AccessDenied. See the "Tailoring the policy" section below for what each statement covers and what you give up by dropping it.

```plaintext theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AlwaysRequired",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "sts:GetCallerIdentity",
        "account:ListRegions"
      ]
    },
    {
      "Sid": "FetchIamUsers",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "iam:ListUsers",
        "iam:GetUser",
        "iam:ListUserPolicies",
        "iam:GetUserPolicy",
        "iam:ListAttachedUserPolicies",
        "iam:ListGroupsForUser",
        "iam:ListAccessKeys",
        "iam:GetAccessKeyLastUsed",
        "iam:GetLoginProfile",
        "iam:ListMFADevices",
        "iam:GetPolicy",
        "iam:GetPolicyVersion"
      ]
    },
    {
      "Sid": "FetchFederatedPrincipals",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "iam:ListOpenIDConnectProviders",
        "iam:GetOpenIDConnectProvider",
        "iam:ListSAMLProviders",
        "iam:GetSAMLProvider",
        "iam:ListRoles"
      ]
    },
    {
      "Sid": "FetchIamRoleEntitlements",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "iam:ListRoles",
        "iam:GetRole",
        "iam:ListRolePolicies",
        "iam:GetRolePolicy",
        "iam:ListAttachedRolePolicies",
        "iam:GetPolicy",
        "iam:GetPolicyVersion"
      ]
    },
    {
      "Sid": "FetchIamGroupEntitlements",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "iam:ListGroups",
        "iam:GetGroup",
        "iam:ListGroupPolicies",
        "iam:GetGroupPolicy",
        "iam:ListAttachedGroupPolicies",
        "iam:GetPolicy",
        "iam:GetPolicyVersion"
      ]
    },
    {
      "Sid": "FetchIamPolicyTerminalResources",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "iam:ListPolicies",
        "iam:GetPolicy",
        "iam:ListPolicyVersions",
        "iam:GetPolicyVersion"
      ]
    },
    {
      "Sid": "FetchLambdaFunctions",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "lambda:ListFunctions",
        "lambda:GetFunctionConfiguration",
        "lambda:ListFunctionUrlConfigs",
        "lambda:GetPolicy"
      ]
    },
    {
      "Sid": "FetchEcsTasksAndServices",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "ecs:List*",
        "ecs:Describe*"
      ]
    },
    {
      "Sid": "FetchEc2InstanceProfiles",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "ec2:DescribeInstances",
        "ec2:DescribeSecurityGroups",
        "autoscaling:Describe*",
        "iam:ListInstanceProfiles"
      ]
    },
    {
      "Sid": "FetchEksWorkloads",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "eks:List*",
        "eks:Describe*",
        "iam:ListRoles"
      ]
    },
    {
      "Sid": "FetchGlueJobs",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "glue:GetJobs",
        "glue:GetCrawlers",
        "glue:GetJobRuns"
      ]
    },
    {
      "Sid": "FetchStepFunctions",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "states:List*",
        "states:Describe*"
      ]
    },
    {
      "Sid": "FetchKinesisFirehoseStreams",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "firehose:List*",
        "firehose:Describe*"
      ]
    },
    {
      "Sid": "FetchCodePipelinePipelines",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "codepipeline:List*",
        "codepipeline:Get*"
      ]
    },
    {
      "Sid": "FetchSageMakerJobs",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "sagemaker:List*",
        "sagemaker:Describe*"
      ]
    },
    {
      "Sid": "FetchEventBridgeRulesAndPipes",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "events:ListRules",
        "events:ListTargetsByRule",
        "pipes:ListPipes",
        "pipes:DescribePipe"
      ]
    },
    {
      "Sid": "FetchMskConnectConnectors",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "kafkaconnect:ListConnectors"
      ]
    },
    {
      "Sid": "FetchCodeBuildProjects",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "codebuild:List*",
        "codebuild:BatchGet*"
      ]
    },
    {
      "Sid": "FetchBatchJobDefinitions",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "batch:Describe*",
        "batch:List*"
      ]
    },
    {
      "Sid": "FetchAppRunnerServices",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "apprunner:List*",
        "apprunner:Describe*"
      ]
    },
    {
      "Sid": "FetchBedrockAgents",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "bedrock:List*",
        "bedrock:Get*"
      ]
    },
    {
      "Sid": "FetchIotRoleAliases",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "iot:List*",
        "iot:Describe*"
      ]
    },
    {
      "Sid": "FetchIamRolesAnywhereProfiles",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "rolesanywhere:ListProfiles"
      ]
    },
    {
      "Sid": "FetchSecretsManagerSecrets",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "secretsmanager:ListSecrets"
      ]
    },
    {
      "Sid": "FetchSsmSecureStringParameters",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "ssm:DescribeParameters"
      ]
    },
    {
      "Sid": "FetchNhaLastActivity",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "cloudwatch:GetMetricData",
        "cloudwatch:ListMetrics"
      ]
    },
    {
      "Sid": "FetchLastActivityViaCloudTrail",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "cloudtrail:LookupEvents"
      ]
    },
    {
      "Sid": "NHIAgentIamAuthorizationGraph",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "iam:GetAccountAuthorizationDetails"
      ]
    },
    {
      "Sid": "NHIAgentAccessAnalyzerFindings",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "access-analyzer:ListAnalyzers",
        "access-analyzer:ListFindings",
        "access-analyzer:GetFinding"
      ]
    },
    {
      "Sid": "NHIAgentGuardDutyFindings",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "guardduty:ListDetectors",
        "guardduty:ListFindings",
        "guardduty:GetFindings"
      ]
    },
    {
      "Sid": "NHIAgentBucketExposure",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "s3:ListAllMyBuckets",
        "s3:GetBucketLocation",
        "s3:GetBucketPolicy",
        "s3:GetBucketPolicyStatus",
        "s3:GetBucketAcl",
        "s3:GetBucketPublicAccessBlock",
        "s3:GetAccountPublicAccessBlock"
      ]
    },
    {
      "Sid": "NHIAgentKeyPolicyExposure",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "kms:ListKeys",
        "kms:DescribeKey",
        "kms:GetKeyPolicy"
      ]
    },
    {
      "Sid": "NHIAgentIdentityCenter",
      "Effect": "Allow",
      "Resource": "*",
      "Action": [
        "sso:List*",
        "sso:Describe*",
        "sso:Get*",
        "identitystore:List*",
        "identitystore:Describe*",
        "organizations:ListAccounts",
        "organizations:DescribeOrganization"
      ]
    },
    {
      "Sid": "DenyDataPlaneReads",
      "Effect": "Deny",
      "Resource": "*",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:GetObjectAttributes",
        "s3:ListBucket",
        "s3:ListBucketVersions",
        "secretsmanager:GetSecretValue",
        "ssm:GetParameter",
        "ssm:GetParameters",
        "ssm:GetParametersByPath",
        "kms:Decrypt",
        "dynamodb:GetItem",
        "dynamodb:Query",
        "dynamodb:Scan",
        "logs:GetLogEvents",
        "logs:FilterLogEvents"
      ]
    }
  ]
}
```

ℹ **A note on repeated actions:** a few IAM actions appear in more than one statement — `iam:ListRoles` in three, `iam:GetPolicy` and `iam:GetPolicyVersion` in four. That is deliberate. Those calls are shared by several settings: resolving EKS IRSA bindings and federated trust policies both walk the full role list, and attached managed policies are resolved for users, roles and groups alike. Repeating them means each statement is independently deletable. IAM combines the grants automatically, so there is no need to consolidate.

***

## Step 2: Create the IAM role

1. Go to **IAM → Roles → Create role**.
2. For **Trusted entity type**, choose **AWS account**.
3. Under **An AWS account**, select **Another AWS account** and enter the Lumos account ID: `349123981986`
4. Check Require external ID and enter the Service Role External ID shown in the Lumos connector setup form.
5. Click **Next**.
6. On the **Add permissions** screen, search for the policy you created in Step 1, select it, and click **Next**.
7. Give the role a name (e.g. `LumosNHIReadOnly`) and click **Create role**.

***

## Step 3 — Note the role ARN

After the role is created, copy its ARN (format: `arn:aws:iam::<your-account-id>:role/LumosNHIReadOnly`). You'll paste it into Lumos in the next step.

***

## Step 4 — Update the trust policy

1. Open the role you just created (click **View role** from the success banner, or find it under **IAM → Roles**).
2. Go to the **Trust relationships** tab and click **Edit trust policy**.
3. In the JSON document, set the `AWS` value inside the `Principal` block to the **Lumos Customer Integrator Role ARN** shown in the Lumos connector setup form.
4. Click **Save changes**.

***

## Step 5 — Connect in Lumos

1. In the Lumos app, go to **Integrations → Add Integration** and search for **"AWS IAM Identity Center (NHI)"**.

Fill in the connector settings in Lumos with the values you collected:

* **Regions -** one or more AWS region codes. Leave blank to scan every region in the account. While AWS reports `me-south-1` and `me-central-1` as unavailable, Lumos skips them when Regions is blank. If you list either region yourself, validation fails and asks you to remove it.
* **IAM Identity Center ARN -** *(Optional)* Instance ARN from IAM Identity Center Settings. Connecting does not require IAM Identity Center; if the ARN is missing or does not match, Lumos logs a warning and continues.
* **Service Role ARN -** ARN of the IAM role created in Step 3
* **Service toggles -** one toggle per `Fetch…` statement in the policy. Turn off any service whose statement you removed. The EC2 toggle is labeled **Fetch EC2 Instances** and corresponds to the `FetchEc2InstanceProfiles` statement.

When you select **Validate**, Lumos first confirms it can assume the role and discover at least one region, then makes one read-only call per AWS service you toggled on, in the first region in your list. If a permission is missing, the error names every missing permission together with the setting that needs it. Services you leave off are not checked, so you do not need KMS or Bedrock permissions just to connect.

> If you connected this integration before the **Regions** setting existed, your connection keeps scanning the one region it was created with. Set **Regions**, or leave it blank, to scan every enabled region. The old single-region field is ignored.

***

## Connecting many accounts at once

The steps above connect one AWS account. To onboard an entire AWS Organization, Lumos publishes a CloudFormation StackSet template and an onboarding script that deploy the role across every account you select and connect them in a single run.

Follow `AWS_SETUP.md` in the Lumos [connector scripts](https://github.com/teamlumos/example-lumos-scripts/tree/main/connector_scripts/aws_sso_graph_nhi) repo.

The script applies the same **Regions** value and service toggles to every connection it creates and deploys the matching permissions.

***

## Scan behavior

* **Cadence:** Follow the NHI security agent configuration. By default, Lumos doesn't pull AWS IAM data on a regular basis unless the agent is configured to run on a schedule.
* **Session lifetime:** each scan opens a short-lived STS session (5-10 min). Lumos never holds long-lived credentials.
* **Regions:** scanning more regions takes longer, but not proportionally. Lumos queries regions in parallel, and the largest data sets — IAM users, roles, groups and policies — are global and fetched once regardless of how many regions you scan.
* **Unavailable regions:** AWS currently reports `me-south-1` and `me-central-1` as unavailable. Accounts that opted into these regions still report them as enabled, but their endpoints never connect. When Regions is blank, Lumos drops them from the discovered region list and scans every other enabled region. When Regions lists either one, Lumos rejects the configuration instead of narrowing it without telling you.
* **Federated trust credentials:** Lumos lists one OIDC or SAML credential per role trust policy that trusts the identity provider. For OIDC trusts with a `sub` condition, such as a GitHub repository, Lumos lists one credential per role and subject. Each credential is linked to the federated non-human account it grants access to. Identity providers that no role trusts, and EKS OIDC providers used for IRSA, are still listed once per provider with no linked account. If a role later trusts an unused provider, the next sync replaces the standalone credential with per-trust credentials. A trust policy that names a deleted provider gets no credential and does not fail the sync. OIDC and SAML credentials synced before per-trust credentials were introduced get new IDs on the next sync.
* **IAM user classification:** Lumos treats an IAM user as a non-human service identity when the user has no console password (login profile) and has never signed in to the console. Lumos shows these programmatic-only users, with their access keys and permissions, as non-human accounts. Every other IAM user appears as a user account.

***

## Troubleshooting

**Validation fails with "The Regions setting includes AWS regions that are currently unavailable"**

The Regions setting lists `me-south-1` or `me-central-1`, which AWS currently reports as unavailable. Remove the region from the Regions setting, or leave the setting blank to scan every available region enabled on the account.

***

## Tailoring the policy

Statement names match the settings in the integration UI. Every statement aside from `AlwaysRequired` can be deleted before you create the policy — Lumos skips that service and the rest of the scan is unaffected. **For any services removed from the policy, make sure that the corresponding setting in the Integration UI is toggled off.** Statements prefixed with `NHIAgent`  have no integration setting at all as they power agent findings rather than data syncs.

| Statement | Covers | Implications |
| :- | :- | :- |
| `AlwaysRequired` | The account ID Lumos runs as, and the regions enabled on the account | Required — every capability derives resource ARNs from the account ID |
| `FetchIamUsers` | IAM users, their policies, access keys, MFA devices and login profiles | Programmatic-only IAM users (no console password, never signed in to the console) as non-human service identities, with their access keys and permissions; all other IAM users as user accounts; unused access key and abandoned user findings |
| `FetchFederatedPrincipals` | OIDC and SAML identity providers, and the trust policies on your roles | Federated principals; OIDC and SAML trust credentials, one per role trust (and per OIDC subject), each linked to the non-human account it lets in; OIDC `sub`/`aud` and SAML certificate findings. Roles that an external AWS account, a specific external role or user, any AWS principal (`*`), or any account in a trusted AWS Organization can assume are inventoried as non-human accounts, with the required External ID when the trust sets one |
| `FetchIamRoleEntitlements` | IAM roles and their inline and attached policies | Role entitlements — the permissions each workload actually holds |
| `FetchIamGroupEntitlements` | IAM groups and their policies | Group entitlements and group membership in the access graph |
| `FetchIamPolicyTerminalResources` | Managed policies and their versions | Resources referenced by policy Allow statements |
| `FetchLambdaFunctions` | Lambda functions, URL configs and resource policies | Lambda execution role attribution; publicly-invokable Function URL findings |
| `FetchEcsTasksAndServices` | ECS clusters, services, tasks and task definitions | ECS task and execution role attribution |
| `FetchEc2InstanceProfiles` | EC2 instances, security groups, Auto Scaling groups and instance profiles | Standalone EC2 instances and Auto Scaling groups as the workloads that run as a role. Toggle labeled **Fetch EC2 Instances** |
| `FetchEksWorkloads` | EKS clusters, node groups, Fargate profiles, Pod Identity associations | Pod, node and Fargate role attribution |
| `FetchGlueJobs` | Glue jobs, crawlers and job runs | Glue job role attribution and last-run times |
| `FetchStepFunctions` | Step Functions state machines | State machine role attribution |
| `FetchKinesisFirehoseStreams` | Firehose delivery streams | Firehose delivery role attribution |
| `FetchCodePipelinePipelines` | CodePipeline pipelines and executions | Pipeline role attribution and last-run times |
| `FetchSageMakerJobs` | SageMaker notebook instances, endpoints and models | SageMaker execution role attribution |
| `FetchEventBridgeRulesAndPipes` | EventBridge rules, targets and Pipes | Rule and pipe role attribution |
| `FetchMskConnectConnectors` | MSK Connect connectors | Connector role attribution |
| `FetchCodeBuildProjects` | CodeBuild projects | Build project role attribution |
| `FetchBatchJobDefinitions` | Batch job definitions, compute environments, queues and jobs | Batch job role attribution and last-run times |
| `FetchAppRunnerServices` | App Runner services | App Runner instance role attribution |
| `FetchBedrockAgents` | Bedrock agents and their published aliases | Bedrock agent role attribution. The built-in test alias, which routes to the unpublished DRAFT version, is skipped |
| `FetchIotRoleAliases` | IoT role aliases | IoT role alias attribution |
| `FetchIamRolesAnywhereProfiles` | IAM Roles Anywhere profiles | Roles Anywhere profile attribution |
| `FetchSecretsManagerSecrets` | Secret names and metadata — never secret values | Secrets as resources in the access graph |
| `FetchSsmSecureStringParameters` | Parameter metadata — never parameter values | SSM parameters as resources in the access graph |
| `FetchNhaLastActivity` | CloudWatch metrics for workload activity | Last-used timestamps for every workload type |
| `FetchLastActivityViaCloudTrail` | CloudTrail management-event lookups | Last-run times for Batch jobs and standalone ECS tasks that have aged out of their own APIs |
| `DenyDataPlaneReads` | Explicit deny on object, secret, parameter, row and log-content reads | Nothing — it grants no access. Keep it if your security review wants the read-only guarantee written into the policy |
| `NHIAgentIamAuthorizationGraph` | The full IAM authorization graph in one paginated call | NHI security agent All IAM-based findings — this is the agent's primary extraction |
| `NHIAgentAccessAnalyzerFindings` | IAM Access Analyzer External Access and Unused Access findings | NHI security agent Externally-shared S3, KMS, Secrets Manager and Lambda resources; long-unused access keys; abandoned IAM users |
| `NHIAgentGuardDutyFindings` | GuardDuty findings scoped to non-human principals | NHI security agent Active-compromise and lateral-movement detection |
| `NHIAgentBucketExposure` | Bucket inventory, policies, ACLs and public-access-block settings | NHI security agent Public and externally-shared bucket findings |
| `NHIAgentKeyPolicyExposure` | KMS keys, their metadata and key policies | NHI security agent Key-policy trust findings |
| `NHIAgentIdentityCenter` | IAM Identity Center permission sets, assignments, applications, Organizations | NHI security agent Workforce access mapping; org-sibling vs external trust classification |

***

## Security FAQ

**Does Lumos access data inside my AWS account (S3 objects, secret values, log contents)?**

No. The S3 permissions grant bucket-level metadata only — inventory, bucket policies, ACLs and public-access-block settings — never object contents.  `DenyDataPlaneReads` then explicitly blocks  `s3:GetObject`, `s3:ListBucket`, `secretsmanager:GetSecretValue`, SSM parameter reads, `kms:Decrypt`, DynamoDB item reads and CloudWatch Logs event reads. An explicit `Deny` in IAM overrides every `Allow`, so those calls fail for this role regardless of what else the policy grants.

Every call Lumos makes lands in your CloudTrail so you can audit exactly what ran.

**Does Lumos read CloudTrail events?**

Yes, in a narrow way. Lumos calls `cloudtrail:LookupEvents` to find when a workload last ran where the service's own API can't say — for example AWS Batch, whose job list only retains finished jobs for about seven days, so older runs are recovered from `SubmitJob` events. Lumos reads this through the CloudTrail API rather than from your log bucket. It only runs when the CloudTrail activity settings are on.

**Why is **`iam:GetAccountAuthorizationDetails`** in the policy?**

It's AWS's dedicated read-only API for retrieving the IAM authorization graph — users, roles, groups, their inline + managed policy documents, trust policies, and `RoleLastUsed`. Using it in one call (rather than \~20 per-entity reads) keeps your CloudTrail cleaner and makes scans predictable. It's IAM-metadata-only; there is no data-plane exposure.

**How are credentials handled?**

The Lumos service account in AWS account `349123981986` assumes your role via `sts:AssumeRole` with the External ID condition.

**Can I scope the role down further?**

Yes. The policy is split by integration setting so you can delete whole statements before creating it — see the "Tailoring the policy" section for what each one covers and what dropping it costs you. Only `AlwaysRequired`  must stay. Your Lumos account team can walk through the trade-offs.

**Can I remove the role later?**

Yes. Delete the role in IAM. The next Lumos scan fails with `AccessDenied` and Lumos surfaces a "connection lost" banner in the integration UI. No data exfiltration — Lumos cannot assume the role once it's deleted.
