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

# Google Cloud (NHI)

> Connect Lumos to Google Cloud through Workload Identity Federation, with no service account key, to inventory service accounts, their workloads, keys and federation trusts, IAM access and last activity.

## What you're setting up

You're giving Lumos read-only access to one Google Cloud organization, folder or project without creating a service account key. Lumos signs a short-lived token with a key pair it generates for you. A Workload Identity Federation provider in your organization trusts that key and exchanges the token. Lumos then impersonates a read-only service account you create, the reader, and reads your scope through Cloud Asset Inventory.

Lumos uses that access to inventory the non-human identities in your scope: service accounts, the workloads that run as them, Google service agents, external identities trusted through Workload Identity Federation, GKE workload identities and Agent Identities. It also reads the credentials that can act as them, the IAM roles they hold and where, and when service accounts and their keys last authenticated.

**What Lumos does NOT do:**

* **No writes.** Every permission Lumos uses is a read. Lumos cannot create, change or delete resources, service accounts, keys or IAM policies.
* **No service account keys.** Lumos never creates one. You upload only the public half of a key pair; the private key never leaves Lumos. That signing key is long-lived: your provider trusts it until you replace or remove the public key. Only the Google tokens it obtains are short-lived.
* **No secret contents.** Lumos reads Secret Manager secrets as metadata only and never reads a secret version. It reads service account keys, HMAC keys and API keys as metadata only and never retrieves key material.
* **No content reads.** Lumos does not read Cloud Storage objects, database rows, logs or messages.
* **No workload configuration synced.** Cloud Asset Inventory returns each workload's configuration, including environment variables and instance metadata, alongside its service account. The connector doesn't sync that configuration to Lumos and leaves it out of its request logs.

**Recommended setup.** A custom role with only the permissions Lumos uses, granted on your organization, with **Fetch last activity** on. That's the least access that gives Lumos a complete inventory, and it's the setup the steps below walk through. If creating a custom role is a hurdle, six predefined roles are quicker to set up but grant broader read access (Step 6). To give Lumos less, see [Reducing access](#reducing-access) for what each reduction costs.

***

## Prerequisites

Before you start, make sure you have:

* A **host project** to hold the federation trust and the reader service account. It can be an existing project, and nothing Lumos reads has to live in it.
* In the host project, permission to enable APIs, create a service account, and create a workload identity pool and provider.
* On your organization, permission to grant IAM roles, and to create custom roles if you use the recommended custom role.
* The Lumos integration page open.

One connection covers one organization and everything beneath it. To connect several organizations, repeat the setup for each.

***

## Step 1: Generate the key in Lumos

1. In the Lumos app, go to **Integrations**, open the **Discover** tab, and search for **"Google Cloud (NHI)"**.
2. Under **Workload Identity Federation**, enter a **Key Identifier**, for example `lumos-gcp-nhi` (letters, numbers and hyphens). Note it; you'll use it in Steps 4 and 5.
3. Select **Get Key** and save the public key as a file named `lumos-jwks.json`. It looks like this:

   ```json theme={null}
   {"keys": [{"kty": "RSA", "kid": "lumos-gcp-nhi", "n": "…", "e": "AQAB", "alg": "RS256", "use": "sig"}]}
   ```

Keep this page open. You'll come back to it in Step 8.

***

## Step 2: Enable the APIs in the host project

Google checks that an API is enabled in the reader's own project, not in the projects it reads. Enable these in the host project only.

1. In the [Google Cloud console](https://console.cloud.google.com/), select the host project. On its **Dashboard**, note the **Project ID** and **Project number**.
2. Go to **APIs & Services → Library**.
3. Search for each API below, open it and select **Enable**:

| API | Used for |
| :- | :- |
| Security Token Service API (`sts.googleapis.com`) | Exchanging the Lumos token |
| IAM Service Account Credentials API (`iamcredentials.googleapis.com`) | Acting as the reader |
| Identity and Access Management (IAM) API (`iam.googleapis.com`) | Service accounts, roles, federation pools |
| Cloud Resource Manager API (`cloudresourcemanager.googleapis.com`) | The organization, folders and projects |
| Cloud Asset API (`cloudasset.googleapis.com`) | Workloads, keys and IAM policies |
| Cloud Storage API (`storage.googleapis.com`) | HMAC keys |
| Dataflow API (`dataflow.googleapis.com`) | Service accounts of Dataflow jobs |
| Vertex AI API (`aiplatform.googleapis.com`) | Service accounts of Vertex AI endpoints |
| Policy Analyzer API (`policyanalyzer.googleapis.com`) | Last activity. Only needed with **Fetch last activity** on, the default |

***

## Step 3: Create the reader service account

1. In the host project, go to **IAM & Admin → Service Accounts** and select **Create service account**.
2. Enter a name, for example `lumos-nhi-reader`.
3. Select **Create and close**. Don't grant it roles here and don't create a key for it.
4. Copy the account's email, `lumos-nhi-reader@<host project ID>.iam.gserviceaccount.com`. You'll enter it in Lumos in Step 8.

***

## Step 4: Create the workload identity pool and provider

1. In the host project, go to **IAM & Admin → Workload Identity Federation** and select **Create pool**.

2. Enter a name, for example `Lumos NHI Pool`, with the ID `lumos-nhi-pool`.

3. Under **Add a provider to pool**:
   * **Select a provider**: **OpenID Connect (OIDC)**
   * **Provider name**: `Lumos NHI`, **Provider ID**: `lumos-nhi`
   * **Issuer (URL)**: `https://lumos.com`, exactly, with no trailing slash
   * **JWK file (JSON)**: upload `lumos-jwks.json` from Step 1
   * **Audiences**: keep **Default audience**
   * Select **Continue**

4. Under **Configure provider attributes**, map `google.subject` to `assertion.sub`.

5. Recommended: under **Attribute conditions**, add the condition below so the provider accepts nothing else, using your key identifier from Step 1:

   ```plaintext theme={null}
   assertion.sub == 'lumos:gcp-nhi:<key identifier>'
   ```

6. Select **Save**.

7. Open the new provider and copy its **Default audience**. You'll enter it in Lumos in Step 8.

***

## Step 5: Let Lumos act as the reader

This lets exactly one outside identity, `lumos:gcp-nhi:<key identifier>`, act as the reader. It grants `roles/iam.workloadIdentityUser` on the reader service account and nothing else.

1. On the **Workload Identity Federation** page, open the pool from Step 4 and select **Grant access**.
2. Choose **Grant access using service account impersonation**.
3. **Service account**: select the reader from Step 3.
4. **Select principals**: **Only identities matching the filter**, with **Attribute name** `subject` and **Attribute value** `lumos:gcp-nhi:<key identifier>` (for example `lumos:gcp-nhi:lumos-gcp-nhi`).
5. Select **Save**. On the **Configure your application** dialog, select **Dismiss**. Lumos doesn't need the configuration file.

***

## Step 6: Choose the reader's role

You can give the reader its access in one of two ways:

* **Custom role (recommended).** Holds only the permissions Lumos uses. It takes one extra step, creating the role, and permission to create custom roles on the organization.
* **Predefined roles (quicker).** Six of Google's built-in roles that together cover the same permissions. There's no role to create, so you can go straight to Step 7. The trade-off is broader read access: together they also let the reader view other IAM, security, Dataflow and Vertex AI metadata that Lumos never reads, including the names of Cloud Storage buckets and objects (not their contents).

**Option A: Custom role**

1. In the project picker, select your **organization**, go to **IAM & Admin → Roles** and select **Create custom role**.
2. **Title**: `Lumos NHI Reader Role`, **ID**: `lumosNhiReaderRole`, **Role launch stage**: **General Availability**.
3. Select **Add permissions**. For each permission below, type it in the filter, tick it and select **Add**.
4. Select **Create**.

This is the full list for the recommended setup. [Reducing access](#reducing-access) covers the ones you can leave out.

| Permission | Used for |
| :- | :- |
| `resourcemanager.organizations.get` | Reading the organization |
| `resourcemanager.folders.get` | Reading its folders |
| `resourcemanager.projects.get` | Placing accounts in their project |
| `cloudasset.assets.listResource` | Listing service accounts |
| `cloudasset.assets.searchAllResources` | Workloads, keys, API keys and the hierarchy |
| `cloudasset.assets.searchAllIamPolicies` | IAM bindings |
| `iam.serviceAccounts.get` | Service accounts from outside the scope that hold a role in it |
| `iam.workloadIdentityPools.list` | Federated principals |
| `iam.workloadIdentityPoolProviders.list` | Federation trusts |
| `iam.roles.get` | The permissions each role grants |
| `storage.hmacKeys.list` | HMAC keys |
| `dataflow.jobs.get` | Service accounts of Dataflow jobs |
| `aiplatform.endpoints.get` | Service accounts of Vertex AI endpoints |
| `policyanalyzer.serviceAccountLastAuthenticationActivities.query` | When service accounts last authenticated |
| `policyanalyzer.serviceAccountKeyLastAuthenticationActivities.query` | When service account keys last authenticated |

Google allows the two `resourcemanager.organizations.get` and `resourcemanager.folders.get` permissions only in a custom role created on the organization, which is why Step 6 creates it there.

**Option B: Predefined roles**

Nothing to create here. In Step 7, grant these six roles instead of the custom role:

| Role | Covers |
| :- | :- |
| `roles/iam.securityReviewer` | Service accounts, role definitions, federation pools and providers, HMAC keys |
| `roles/cloudasset.viewer` | Cloud Asset Inventory searches: workloads, keys and IAM bindings |
| `roles/browser` | The organization, folders and projects |
| `roles/dataflow.viewer` | Service accounts of Dataflow jobs |
| `roles/aiplatform.viewer` | Service accounts of Vertex AI endpoints |
| `roles/policyanalyzer.activityAnalysisViewer` | Last activity |

***

## Step 7: Grant the role on your organization

Lumos reads the organization you grant the role on, and everything beneath it.

1. In the project picker, select your organization. Note its ID from the picker's **ID** column.
2. Go to **IAM & Admin → IAM** and select **Grant access**.
3. **New principals**: the reader's email from Step 3.
4. **Select a role**: **Custom → Lumos NHI Reader Role**. If you chose the predefined roles, add each of the six from Step 6, using **Add another role**.
5. Select **Save**.

The scope you'll enter in Lumos is `organizations/<organization ID>`, for example `organizations/123456789012`. To connect a folder or a project instead, see [Reducing access](#reducing-access).

***

## Step 8: Connect in Lumos

Back on the Lumos page from Step 1, fill in the settings:

* **Scope:** from Step 7
* **Workload Identity Federation provider:** the default audience from Step 4. Lumos accepts it with or without the `https://iam.googleapis.com/` prefix, as `projects/<project number>/locations/global/workloadIdentityPools/<pool ID>/providers/<provider ID>`
* **Reader service account:** the reader's email from Step 3
* **Fetch last activity:** leave it on, the default

Select **Validate**. When **Valid Credentials** appears, select **Complete**.

When you validate, Lumos signs a token, exchanges it with Google, acts as the reader, checks that the APIs are enabled in the host project, reads the scope and tests every permission it needs there. Google is asked which permissions the reader holds, so this works the same for a custom role and for predefined roles. If a check fails, the message names what to fix: an API to enable, a permission missing from the role, or a part of the trust that doesn't match.

The check covers the scope itself. It doesn't confirm that every project and resource beneath the scope is readable, so a successful connection doesn't guarantee a complete sync. If Google is throttling requests or unavailable at that moment, Lumos saves the connection without finishing the check. If the first sync then fails, recheck Steps 4 to 7.

After you connect, the connector's **"Integrations"** tab shows its sync status. **Synced** means the first run completed. See [NHI Connector Sync Status](https://docs.lumos.com/nhi-sync-status.md) for what each status means. Your service accounts and other non-human identities then appear in the [NHI Inventory](https://docs.lumos.com/nhi-inventory.md).

***

## Setting up with the gcloud CLI

Steps 2 to 7 can also be run from the `gcloud` CLI, for example as a script or as the basis of a Terraform module. Do Step 1 in Lumos first, save the key as `lumos-jwks.json`, then replace the values at the top and run:

```bash theme={null}
HOST_PROJECT_ID=my-host-project
ORG_ID=123456789012
KEY_ID=lumos-gcp-nhi   # the Key Identifier from Step 1
HOST_PROJECT_NUMBER=$(gcloud projects describe "$HOST_PROJECT_ID" --format='value(projectNumber)')
READER="lumos-nhi-reader@${HOST_PROJECT_ID}.iam.gserviceaccount.com"

# Step 2: enable the APIs in the host project
gcloud services enable sts.googleapis.com iamcredentials.googleapis.com iam.googleapis.com \
  cloudresourcemanager.googleapis.com cloudasset.googleapis.com storage.googleapis.com \
  dataflow.googleapis.com aiplatform.googleapis.com policyanalyzer.googleapis.com \
  --project="$HOST_PROJECT_ID"

# Step 3: create the reader service account
gcloud iam service-accounts create lumos-nhi-reader \
  --project="$HOST_PROJECT_ID" --display-name="Lumos NHI reader"

# Step 4: create the pool and the OIDC provider with the Lumos public key
gcloud iam workload-identity-pools create lumos-nhi-pool \
  --project="$HOST_PROJECT_ID" --location=global --display-name="Lumos NHI Pool"
gcloud iam workload-identity-pools providers create-oidc lumos-nhi \
  --project="$HOST_PROJECT_ID" --location=global --workload-identity-pool=lumos-nhi-pool \
  --issuer-uri="https://lumos.com" \
  --jwk-json-path=lumos-jwks.json \
  --attribute-mapping="google.subject=assertion.sub" \
  --attribute-condition="assertion.sub == 'lumos:gcp-nhi:${KEY_ID}'"

# Step 5: let only the Lumos subject act as the reader
gcloud iam service-accounts add-iam-policy-binding "$READER" \
  --project="$HOST_PROJECT_ID" \
  --role=roles/iam.workloadIdentityUser \
  --member="principal://iam.googleapis.com/projects/${HOST_PROJECT_NUMBER}/locations/global/workloadIdentityPools/lumos-nhi-pool/subject/lumos:gcp-nhi:${KEY_ID}"

# Step 6: create the custom role on the organization
gcloud iam roles create lumosNhiReaderRole --organization="$ORG_ID" \
  --title="Lumos NHI Reader Role" --stage=GA \
  --permissions=resourcemanager.organizations.get,resourcemanager.folders.get,resourcemanager.projects.get,cloudasset.assets.listResource,cloudasset.assets.searchAllResources,cloudasset.assets.searchAllIamPolicies,iam.serviceAccounts.get,iam.workloadIdentityPools.list,iam.workloadIdentityPoolProviders.list,iam.roles.get,storage.hmacKeys.list,dataflow.jobs.get,aiplatform.endpoints.get,policyanalyzer.serviceAccountLastAuthenticationActivities.query,policyanalyzer.serviceAccountKeyLastAuthenticationActivities.query

# Step 7: grant the role on the organization
gcloud organizations add-iam-policy-binding "$ORG_ID" \
  --member="serviceAccount:${READER}" \
  --role="organizations/${ORG_ID}/roles/lumosNhiReaderRole"

# Values for Step 8
echo "Scope: organizations/${ORG_ID}"
echo "Workload Identity Federation provider: projects/${HOST_PROJECT_NUMBER}/locations/global/workloadIdentityPools/lumos-nhi-pool/providers/lumos-nhi"
echo "Reader service account: ${READER}"
```

To use the predefined roles instead of the custom role, skip the Step 6 command and, in Step 7, run `gcloud organizations add-iam-policy-binding` once for each of the six roles listed in Step 6.

***

## What Lumos inventories

**Non-human accounts**

| Account type | What it is |
| :- | :- |
| Service account | A service account in your scope. Lumos marks whether it's user-managed, the default Compute Engine account or the default App Engine account. Service accounts from outside the scope that hold a role in it are included and marked as out of scope |
| Workload binding | One for each workload and the service account it runs as, so a service account used by three workloads appears three times, once per workload. Each copies its service account's access |
| Google service agent | A Google-managed service account that holds a role in your scope |
| Federated principal | An external identity trusted through Workload Identity Federation that holds a role: a single subject, a group, an attribute match or a whole pool |
| GKE workload | A GKE Workload Identity principal: a Kubernetes namespace or service account |
| Agent Identity | The identity of an Agent Engine |

Disabled service accounts show as suspended. A service account that has been deleted but is still named somewhere, such as by a workload, a binding or a key, shows as inactive.

**Workloads.** Lumos links each service account to the workloads that run as it: Compute Engine instances, Cloud Run services and jobs, Cloud Run functions, GKE node pools, Cloud Build triggers, Dataproc clusters, App Engine versions, Workbench instances, Agent Engines, Composer environments, Dataflow jobs and Vertex AI endpoints. For VMs, GKE node pools, Dataproc clusters and Workbench instances, Lumos also records the access scopes, which can narrow what the service account does from that workload.

**Credentials**

| Credential | What Lumos reads |
| :- | :- |
| Service account keys | User-managed keys: creation and expiry dates, origin (Google-generated or uploaded), algorithm, and whether and why the key was disabled, including leaks Google detected |
| HMAC keys | The service account each belongs to and its creation date |
| API keys | API keys bound to a service account, with their restrictions and whether they have none |
| Federation trusts | One per federation provider and principal: the provider type, the issuer or AWS account it trusts, allowed audiences, attribute mapping and attribute condition |

A key whose service account was deleted, or sits outside your scope, still appears, with the account's email but without a link to an account.

**Roles and scopes.** Lumos reads IAM allow-policy bindings on the organization, folders, projects and individual resources inside your scope, and breaks each role into its permissions. Bindings on folders or the organization above your scope are not read. A role held on a container also appears on the workloads and secrets beneath it, with only the permissions that act on that type of resource. Lumos also shows who can act as which service account, and marks privileged roles: basic roles that write (Owner, Editor), admin roles, and roles that can impersonate or change an IAM policy.

A binding with an IAM condition is kept separate from unconditional access to the same role, along with the condition's title and expression. Lumos doesn't evaluate the condition.

**Resources.** The organization, folder and project hierarchy, the workloads above, Secret Manager secrets (metadata only), and any other resource that carries its own IAM policy.

**Last activity.** With **Fetch last activity** on, Lumos reads when each service account and each user-managed key last authenticated, from Activity Analyzer. It's reported on the service account itself, not on each workload binding.

***

## 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:** for each token, Lumos signs a JWT that is valid for 10 minutes, exchanges it through your provider, and calls `generateAccessToken` on the reader to get a short-lived access token.
* **How Lumos reads:** nearly everything comes from Cloud Asset Inventory searches across the whole scope. Lumos reads from their own APIs only what Cloud Asset Inventory doesn't include: HMAC keys (one call per project), federation pools and providers, role definitions, and the service accounts of Dataflow jobs and Vertex AI endpoints (one call per job or endpoint).
* **Rate limits:** Lumos limits its own calls per API to stay under Google's quotas. Last-activity queries are the slowest at 10 per minute, two per project (one for service accounts, one for keys), so with **Fetch last activity** on, large scopes take longer.
* **Quota project:** API calls are counted against the host project, where the reader lives.
* **New folders:** Cloud Asset Inventory can take hours to index a newly created folder. If the scope is a folder it doesn't hold yet, the sync fails and retries instead of reading part of the hierarchy.

***

## Reducing access

The recommended setup is the least access that gives a complete inventory. You can give Lumos less in the ways below, at the cost listed for each. The remaining permissions in Step 6 can't be removed: the connection check fails if any of them is missing.

| Change | How | What you give up |
| :- | :- | :- |
| Connect a folder instead of the organization | Create the custom role on the organization as in Step 6. In Step 7, grant it on the folder instead, and enter the scope as `folders/<folder ID>` | Roles granted on the organization and the folders above it are not read, though they still apply inside the folder. Identities elsewhere in the organization are not inventoried unless they hold a role inside the folder |
| Connect a project instead of the organization | Create the custom role in the project, without `resourcemanager.organizations.get` and `resourcemanager.folders.get`, or use the predefined roles. Grant it on the project in Step 7, and enter the scope as `projects/<project ID>`, using the project ID, not the number | Same as for a folder: roles granted on the folders and organization above the project are not read, and identities outside it are not inventoried unless they hold a role in it |
| Turn off last activity | Leave out the two `policyanalyzer` permissions in Step 6 (or `roles/policyanalyzer.activityAnalysisViewer`, with the predefined roles) and the Policy Analyzer API in Step 2, and turn off **Fetch last activity** in Step 8 | No last-authentication time for service accounts and keys, so you can't tell which ones are unused |

For example, if you connect a project, an Editor grant on its parent folder doesn't appear in Lumos, even though it applies to every service account in the project. That's why we recommend the organization.

***

## Known limitations

* **Access granted above the scope is not shown.** If you connect a folder or project instead of the organization (see [Reducing access](#reducing-access)), roles granted on the folders and organization above it are not read, though they still apply to everything inside it.
* **Human principals are not read:** users, groups, domains and Workforce Identity Federation. Roles granted to a group don't appear on the service accounts in that group.
* **Access is potential, not effective.** Deny policies, Principal Access Boundary policies and organization policies are not read, and IAM conditions are recorded but not evaluated, so Lumos can overstate access.
* **Domain-wide delegation is not read.**
* **Not every credential is covered:** unbound API keys, Google-managed (system) service account keys and short-lived tokens are not listed.
* **Not every workload is covered:** 1st-gen Cloud Functions and Cloud Scheduler jobs, and builds run outside a Cloud Build trigger (such as `gcloud builds submit` or Cloud Run source deploys).
* **Last activity relies on Activity Analyzer,** which Google offers in Preview. If the reader can't query a project, that project's accounts and keys have no last activity, and the sync doesn't fail.

***

## Security FAQ

**Does Lumos access data inside my projects (objects, secrets, database rows)?**

No. With the recommended custom role, the reader holds only the permissions listed in Step 6, and none of them reads data. There is no `storage.objects.get`, no `secretmanager.versions.access` and no BigQuery or database read. Secrets and keys are read as metadata only. The predefined roles grant more than Lumos uses, so the limit there is what Lumos calls, not what the roles allow.

**Can the reader see my workload configuration?**

Yes. Cloud Asset Inventory returns each workload's configuration with the workload, including Cloud Run environment variables and Compute Engine instance metadata. Lumos needs the service account recorded alongside them. The connector doesn't sync the rest to Lumos. It leaves the configuration out of its request logs, and it leaves Dataflow job and Vertex AI endpoint responses out entirely. If you keep secrets in environment variables or instance metadata, any principal that can search Cloud Asset Inventory in that scope can read them, not just Lumos. Secret Manager avoids this.

**How is the key pair handled?**

Lumos generates the key pair and keeps the private key. You upload only the public key to your provider. No service account key exists for the reader. The long-lived credential is Lumos's signing key: anyone holding it could obtain reader tokens for as long as your provider trusts the matching public key. Each token it obtains is short-lived, but the key itself stays valid until you rotate or remove it.

Lumos stores the key pair encrypted at rest in its secrets manager, the same way it stores credentials for its other integrations. Each connection's keys are stored separately, apart from other integration credentials.

To rotate, generate a new key pair in Lumos and upload the new public key to the provider. Until you do, Google rejects Lumos's tokens. To revoke it, remove the public key from the provider, or disable the provider.

**Can I limit what Lumos reads?**

Yes. [Reducing access](#reducing-access) lists each option and what it costs. Lumos tests the reader's permissions at connect, not the role's name, so any role that holds the required permissions works.

**Can I see what Lumos read?**

Yes, once you turn on the right logs. Every call Lumos makes is a read, and Google records reads as Data Access audit logs, under the reader service account. None of Lumos's calls produce Admin Activity entries. Google turns Data Access audit logs off by default, so nothing is recorded until you enable them:

* **On the scope:** enable Data Access audit logs (**Admin Read**) for the Cloud Asset API, Cloud Resource Manager API, Identity and Access Management API, Cloud Storage and Vertex AI API. With **Fetch last activity** on, also enable them (**Data Read**) for the Policy Analyzer API.
* **On the host project:** enable Data Access audit logs for the Identity and Access Management API to record each time Lumos acts as the reader. Google doesn't let you enable the [IAM Service Account Credentials logs](https://docs.cloud.google.com/iam/docs/audit-logging/audit-logging-iamcreds) separately. The [Security Token Service records each token exchange](https://docs.cloud.google.com/iam/docs/audit-logging/audit-logging-sts) as **Admin Read**.

Dataflow doesn't write audit logs for job reads, so Lumos's Dataflow calls aren't recorded.

**Can I remove the integration later?**

Yes. Remove the reader's role on the scope, remove the `roles/iam.workloadIdentityUser` grant on the reader, disable or delete the provider or the pool, or disable or delete the reader service account. Once the change takes effect, Lumos's reads fail. An access token issued before then stays valid until it expires, at most one hour by default.
