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

# GCP workload scanning access and permissions

> Every role, permission, IAM condition, and identity GCP workload scanning creates, what each is for, and when it exists

With **[GCP workload scanning](/guides/integrations/gcp/workload-scanning/overview)**, Plerion's access is a small set of custom roles, some of them conditioned so they only reach resources Plerion itself created. The onboarding script and Terraform template create every grant listed here. Review them before you run either one, and audit them afterward in your IAM console.

***

## Summary

| Role or binding | Scope | Bound to | Condition | Exists when |
| - | - | - | - | - |
| `PlerionWorkloadScan` | Organization | Tenant service account | None | **Workload scanning** capability is on |
| `PlerionWorkloadScanSnapshots` | Organization | Tenant service account | Snapshot name starts with `plerion-scan-` | **Workload scanning** capability is on |
| `PlerionWorkloadScanImageRead` | Organization | Tenant service account | Project not tagged `PlerionAccess: Denied` | **Compute Engine custom images** type is on |
| `PlerionWorkloadScanArtifactPull` | Organization | Artifact-scanner service account | None | **Cloud Run** or **Cloud Functions (2nd gen)** type is on |
| `PlerionWorkloadScanFunctionSourceRead` | Organization | Source-scanner service account | None | **Cloud Functions (1st gen)** type is on |
| `PlerionWorkloadScanCompute` | Scanning project | Tenant service account | None | Workload scanning is on |
| `roles/iam.serviceAccountUser` | Each scanner service account | Tenant service account | None | With the matching service account |

Two of these grants are broad by nature. `PlerionWorkloadScanArtifactPull` lets the artifact-scanner identity pull any container image in your organization, and `PlerionWorkloadScanFunctionSourceRead` lets the source-scanner identity download the deployed source of any 1st gen function. Both exist only while their workload type is on.

Managed instance group scanning adds no role or permission. It uses `PlerionWorkloadScan` and `PlerionWorkloadScanCompute` as they are.

***

## Organization-level roles granted with the capability

Turning on the **Workload scanning** capability in the capabilities step grants these two bindings to the tenant service account. They exist whether or not the scanning project has been created yet, and they let Plerion read workload metadata and take snapshots.

### `PlerionWorkloadScan`

| Permissions | Purpose |
| - | - |
| `compute.instances.get`, `compute.instances.list` | Find Compute Engine instances and read their disks and state |
| `compute.instanceGroupManagers.get`, `compute.instanceGroupManagers.list` | Find managed instance groups and read their members |
| `compute.disks.get`, `compute.disks.list`, `compute.disks.createSnapshot` | Read disk metadata and snapshot a disk |
| `compute.snapshots.create`, `compute.snapshots.list` | Create the scan snapshot; let the sweeper find snapshots Plerion created |
| `run.services.get`, `run.services.list`, `run.revisions.get`, `run.locations.list` | Find Cloud Run services, resolve the image digest a serving revision runs, and list the regions Cloud Run is available in |
| `cloudfunctions.functions.get`, `cloudfunctions.functions.list` | Find Cloud Functions and read their generation, state, and backing revision |
| `artifactregistry.repositories.get`, `artifactregistry.repositories.list`, `artifactregistry.repositories.downloadArtifacts` | Read Artifact Registry repository metadata and pull images |
| `container.clusters.get`, `container.clusters.list` | Read GKE cluster metadata |

The role is unconditioned at organization scope. `compute.snapshots.list` returns snapshot names and labels for every snapshot in your organization, including your own backups. That is metadata only. Reading a snapshot's contents, deleting it, or relabeling it is governed by the conditioned role below.

### `PlerionWorkloadScanSnapshots`

| Permissions | Purpose |
| - | - |
| `compute.snapshots.useReadOnly` | Create the scan disk from the snapshot |
| `compute.snapshots.delete` | Delete the snapshot when the scan finishes |
| `compute.snapshots.setLabels` | Label the snapshot with its owning tenant, integration, and execution. GCP checks this permission when labels are supplied in the create request, not only on a later edit |

All three are bound under one IAM condition:

```
resource.name.extract('/snapshots/{name}').startsWith('plerion-scan-')
```

Every snapshot Plerion creates is named with the `plerion-scan-` prefix, so these permissions only ever apply to snapshots Plerion created. Plerion cannot read the contents of, delete, or relabel any other snapshot in your organization, including your backups. GCP IAM enforces this, not Plerion's software.

***

## Organization-level roles gated by workload type

These roles exist only while the matching workload type is turned on. The access command Plerion generates reflects your current selection. It creates a role when its type is on and removes it when the type is off. See [Changing workload types](/guides/integrations/gcp/workload-scanning/managing-workload-scanning#changing-workload-types).

### `PlerionWorkloadScanImageRead`

Created when **Compute Engine custom images** is on. Bound to the tenant service account.

| Permissions | Purpose |
| - | - |
| `compute.images.list` | Enumerate a project's custom images, the same call Plerion's asset collector already uses |
| `compute.images.get` | Read an image's status, deprecation state, size, and encryption. Included so the role is self-contained |
| `compute.images.useReadOnly` | Create a scan disk from the image in the scanning project |

The binding carries a tag condition:

```
!resource.matchTag('<organization-id>/PlerionAccess', 'Denied')
```

A project tagged `PlerionAccess: Denied` is excluded, so Plerion can't read that project's custom images at all. A name-prefix condition like the snapshot role's isn't possible here, because Plerion has to read images you named. The role is organization-wide because custom images live in every project, and a per-project binding would need updating as images are built.

### `PlerionWorkloadScanArtifactPull`

Created when **Cloud Run** or **Cloud Functions (2nd gen)** is on. Bound to the **artifact-scanner service account**, `plerion-scanner-artifact@<scanning-project>.iam.gserviceaccount.com`, not the tenant service account.

| Permissions | Purpose |
| - | - |
| `artifactregistry.repositories.downloadArtifacts` | Pull image layers to scan |
| `artifactregistry.repositories.get` | Read repository metadata needed to resolve the pull |
| `artifactregistry.repositories.list` | Locate the repository holding an image |

The role is unconditioned and organization-wide because a service and the image it runs often live in different projects. It lets the artifact-scanner identity pull any image in your organization. For a 2nd gen function, the image lives in the `gcf-artifacts` repository Google creates in your project. It is an ordinary Artifact Registry repository, and Plerion pulls only the image the function is currently serving.

The tenant service account already holds `downloadArtifacts` through `PlerionWorkloadScan`. What turning on the type adds is the dedicated identity that runs the scan job, and its role. A Compute Engine-only integration has no artifact-scanner identity and no `PlerionWorkloadScanArtifactPull` role.

### `PlerionWorkloadScanFunctionSourceRead`

Created when **Cloud Functions (1st gen)** is on. Bound to the **source-scanner service account**, `plerion-scanner-source@<scanning-project>.iam.gserviceaccount.com`.

| Permissions | Purpose |
| - | - |
| `cloudfunctions.functions.sourceCodeGet` | Get a short-lived download link for the source Google Cloud currently has deployed for a 1st gen function |

This is the only permission the source-scanner identity holds. It doesn't include `cloudfunctions.functions.get` or `.list`, so the identity can only act on function names Plerion already found through `PlerionWorkloadScan`. It lets the source-scanner identity read the deployed source of any 1st gen function in your organization.

***

## Scanning project role: `PlerionWorkloadScanCompute`

Inside the scanning project, a project-scoped custom role is bound to the tenant service account. It covers running scanner VMs and Cloud Run scan jobs in that one project and nothing outside it.

| Permission group | Purpose |
| - | - |
| `compute.disks.create` / `get` / `list` / `use` / `useReadOnly` / `delete` / `setLabels` | Create the scan disk, attach it read-only, label it, and delete it |
| `compute.instances.create` / `get` / `list` / `delete` / `attachDisk` / `detachDisk` / `setLabels` / `setMetadata` / `setServiceAccount` | Boot, label, and delete the scanner VM, attach and detach the scan disk, and supply the VM's startup metadata and service account. GCP requires the last two permissions at instance creation |
| `compute.networks.get` / `updatePolicy` | Read the scanning project's network and satisfy the check GCP runs when creating a subnet |
| `compute.subnetworks.use` / `useExternalIp` / `create` / `get` / `list` | Use or create the per-region subnet the scanner VM runs in |
| `compute.zones.get` / `list`, `compute.machineTypes.get` / `list` | Pick a valid zone and machine type |
| `compute.regions.get` | Read the scanning project's regional quotas so a run stays within them |
| `compute.images.get` / `useReadOnly` | Boot the scanner VM's image (Plerion's pre-built image or the public Ubuntu image) |
| `run.jobs.create` / `get` / `list` / `update` / `run` / `runWithOverrides` | Create the standing scan jobs, keep their configuration current, and launch an execution with the image digest or function to scan as an override |
| `run.executions.get` / `list` / `delete`, `run.tasks.get` / `list` | Poll an execution and delete it when it completes |
| `serviceusage.services.get` | Confirm the Cloud Run API is enabled on the scanning project before launching a job |

The `run.*` permissions are granted with the rest of the role regardless of which workload types are on. A workload type controls the identity that can reach your images or source, which is the artifact-scanner or source-scanner service account.

The tenant service account also holds `roles/iam.serviceAccountUser` on each scanner service account in the scanning project, so it can start VMs and jobs that run as them.

<Warning>
  `run.jobs.runWithOverrides` on the scanning project lets its holder point the standing image scan job at any image the artifact-scanner identity can read. It also lets them point the source scan job at any 1st gen function the source-scanner identity can read. Two things limit the damage. The standing jobs are inert templates, so a plain `run.jobs.run` (the permission `roles/run.invoker` carries) does nothing. And each execution's upload token is bound to the digest or function it was launched for, so a redirected execution can't upload results anywhere. Treat `run.jobs.runWithOverrides` on the scanning project as organization-wide read access to images and function source, and grant it only to people who need it.
</Warning>

***

## Scanner service accounts

| Service account | Runs | Roles |
| - | - | - |
| `plerion-scanner@<scanning-project>.iam.gserviceaccount.com` | Scanner VMs | **None.** The VM receives a mounted disk and an upload token at boot and calls no GCP API |
| `plerion-scanner-artifact@<scanning-project>.iam.gserviceaccount.com` | Image scan job | `PlerionWorkloadScanArtifactPull` |
| `plerion-scanner-source@<scanning-project>.iam.gserviceaccount.com` | Source scan job | `PlerionWorkloadScanFunctionSourceRead` |

The scanner VM account is created with workload scanning. The other two are created with their workload type and removed when the type is turned off and the access command re-run. Because they are separate identities, compromising one grants none of the others' access.

<Info>
  Image pulls and source downloads by these identities appear in your Cloud Audit Logs only if Data Access audit logging is enabled for `artifactregistry.googleapis.com` and `cloudfunctions.googleapis.com`. Google Cloud doesn't enable Data Access logs by default. Turn them on if you want every pull and download, including Plerion's, in your own logs.
</Info>

***

## Reviewing and removing grants

The onboarding script prints each `gcloud` command before running it, including the `--permissions` list of each workload scanning role it creates or updates. To review the commands without running any, pass `--dry-run`. The Terraform template declares the same roles in plain text. Afterward, the roles appear in your IAM console under the organization's custom roles and, for `PlerionWorkloadScanCompute`, in the scanning project.

No Plerion identity can change your organization's IAM, so removing a grant is always something you do. Re-running the access command removes the type-gated roles for any type you have turned off, and `--remove-workload-scanning` deletes the scanning project and all three type-gated roles. See [Managing workload scanning](/guides/integrations/gcp/workload-scanning/managing-workload-scanning) for both, and the [GCP integration overview](/guides/integrations/gcp/overview#keyless-access) for revoking Plerion's access entirely.

***

## Next step

* [Coverage](/guides/integrations/gcp/workload-scanning/coverage)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.