Skip to main content
This page explains every GCP IAM permission that Qovery requires to create and manage your GKE clusters, and what each permission is used for in our infrastructure engine.
Qovery uses a custom IAM role with granular permissions rather than predefined GCP roles, following the principle of least privilege. The setup script also enables only the specific GCP APIs that Qovery needs.

Setup Overview

Qovery provides a setup script that:
  1. Enables required GCP APIs (Container, Compute, Artifact Registry, Storage, Resource Manager, Cloud Run)
  2. Creates a custom IAM role with the exact permissions listed below
  3. Creates a service account and binds it to the custom role
  4. Generates a JSON key for the service account to upload in Qovery
You can review the full setup script in the GCP installation guide.

Required GCP APIs

APIWhy
container.googleapis.comGKE cluster creation and management
compute.googleapis.comVPC networks, subnetworks, routers, NAT gateways, firewall rules
artifactregistry.googleapis.comDocker image repository management
storage.googleapis.comGCS buckets for Terraform state, logs, and metrics
cloudresourcemanager.googleapis.comProject-level IAM policy management
run.googleapis.comCloud Run Jobs for asynchronous cleanup tasks

IAM Permissions — Service Accounts

iam.serviceAccounts.*

PermissionWhy
create, delete, disable, enable, undeleteQovery creates dedicated GCP service accounts for each cluster component (GKE nodes, Loki logging, External Secrets Operator, KEDA autoscaler, Thanos metrics)
get, listReads existing service accounts to avoid duplicates during updates
updateUpdates service account display names or descriptions when cluster configuration changes
getIamPolicy, setIamPolicyConfigures Workload Identity bindings — maps Kubernetes service accounts to GCP service accounts so pods authenticate without JSON keys
actAsRequired for assigning service accounts to GKE nodes and Cloud Run Jobs
Workload Identity is the recommended way to authenticate workloads on GKE. Qovery creates dedicated service accounts for each component:
  • Cluster SA — Default node SA with logging, monitoring, and image pull permissions
  • Loki SA — GCS access for log storage
  • ESO SA — Secret Manager access for external secrets
  • KEDA SA — Workload Identity for autoscaling
  • Thanos SA — GCS access for metrics storage

IAM Permissions — Resource Manager

resourcemanager.projects.*

PermissionWhy
getReads project metadata to validate the project context before provisioning
getIamPolicyReads existing project-level IAM bindings to check current state before making changes
setIamPolicyBinds service accounts to IAM roles at the project level (e.g., granting the cluster SA roles/logging.logWriter)

Kubernetes Engine — container.*

Qovery creates GKE Autopilot clusters, which requires full control over Kubernetes resources. The permissions are grouped by function below.

Cluster Management

Permission groupWhy
container.clusters.create, delete, update, get, listCreates and manages GKE Autopilot clusters with VPC-native networking, private nodes, release channels, and maintenance windows
container.clusters.connect, getCredentialsRetrieves cluster credentials (kubeconfig) to deploy Helm charts and Kubernetes resources
container.clusters.createTagBinding, deleteTagBinding, listEffectiveTags, listTagBindingsTags clusters for lifecycle tracking and cost allocation
container.operations.get, listMonitors long-running cluster operations (create, upgrade, delete)

Core Kubernetes Resources

These permissions are required to deploy and manage Qovery system components (Nginx Ingress, cert-manager, Loki, Prometheus, KEDA, etc.) via Helm charts.
Permission groupWhy
container.pods.*Deploys application pods, reads logs, executes into pods for debugging, manages pod lifecycle
container.deployments.*Creates Deployments for Qovery agent, ingress controller, monitoring stack
container.services.*Creates Kubernetes Services (LoadBalancer, ClusterIP) to expose applications
container.configMaps.*Stores configuration for Helm releases and application settings
container.secrets.*Manages TLS certificates, registry credentials, and application secrets
container.namespaces.*Creates isolated namespaces for each Qovery environment
container.serviceAccounts.*Creates Kubernetes service accounts for Workload Identity bindings
container.persistentVolumeClaims.*, container.persistentVolumes.*Manages persistent storage for stateful workloads (databases, caches)

Workload Scaling & Scheduling

Permission groupWhy
container.horizontalPodAutoscalers.*Configures HPA for auto-scaling application workloads based on CPU/memory
container.statefulSets.*Deploys stateful components (Prometheus, Loki) that need stable identities
container.daemonSets.*Deploys node-level agents (Promtail log forwarder) on every node
container.cronJobs.*Schedules recurring tasks (certificate renewal, cleanup jobs)
container.jobs.*Runs one-off tasks (database migrations, lifecycle hooks)
container.replicaSets.*Manages pod replicas created by Deployments
container.podDisruptionBudgets.*Ensures minimum pod availability during node maintenance
container.priorityClasses.*Defines scheduling priority for system components vs user workloads
container.limitRanges.*, container.resourceQuotas.*Enforces resource limits per namespace to prevent noisy-neighbor issues

Networking & Ingress

Permission groupWhy
container.ingresses.*Creates Ingress resources to route external traffic to applications
container.networkPolicies.*Enforces network isolation between namespaces/environments
container.endpointSlices.*, container.endpoints.*Service discovery — maps Services to pod IPs
container.backendConfigs.*, container.frontendConfigs.*Configures GCP-specific load balancer settings (health checks, SSL policies)
container.managedCertificates.*Manages Google-managed TLS certificates for HTTPS endpoints

RBAC & Security

Permission groupWhy
container.clusterRoles.*, container.clusterRoleBindings.*Defines cluster-wide permissions for Qovery system components
container.roles.*, container.roleBindings.*Defines namespace-scoped permissions for application workloads
container.podSecurityPolicies.*Configures pod security constraints (deprecated but required for older clusters)
container.mutatingWebhookConfigurations.*, container.validatingWebhookConfigurations.*Installs admission webhooks for cert-manager and policy enforcement
container.certificateSigningRequests.*Manages internal TLS certificate signing within the cluster
container.selfSubjectAccessReviews.create, container.selfSubjectRulesReviews.create, container.subjectAccessReviews.create, container.localSubjectAccessReviews.create, container.tokenReviews.createRBAC authorization checks — verifies what actions are permitted

Storage & CSI

Permission groupWhy
container.storageClasses.*Defines storage classes (SSD, standard) for persistent volumes
container.csiDrivers.*, container.csiNodes.*, container.csiNodeInfos.*Container Storage Interface plugins for dynamic volume provisioning
container.volumeAttachments.*Attaches/detaches persistent disks to nodes
container.volumeSnapshots.*, container.volumeSnapshotClasses.*, container.volumeSnapshotContents.*Creates volume snapshots for backup and restore
container.storageStates.*, container.storageVersionMigrations.*Internal storage state management and API version migrations

Cluster Internals

Permission groupWhy
container.nodes.*Reads node status, labels, and taints for scheduling decisions
container.events.*Reads Kubernetes events for debugging and monitoring
container.leases.*Leader election for HA components (controller-manager, scheduler)
container.controllerRevisions.*Tracks revision history for Deployments and StatefulSets
container.replicationControllers.*Legacy workload management (backward compatibility)
container.componentStatuses.*Health checks on cluster components
container.customResourceDefinitions.*Installs CRDs for cert-manager, Prometheus Operator, KEDA, and other operators
container.apiServices.*Registers custom API services (metrics server, custom metrics)
container.runtimeClasses.*Configures container runtimes (gVisor, containerd)
container.bindings.createBinds pods to nodes during scheduling
container.podTemplates.*Pod template management for workload controllers
container.thirdPartyObjects.*Legacy third-party resource support
container.updateInfos.*Cluster update state tracking
container.auditSinks.*Configures audit log forwarding
container.hostServiceAgent.useRequired for GKE host service agent integration

Artifact Registry — artifactregistry.*

Permission groupWhy
repositories.create, delete, update, get, listCreates Docker repositories (prefixed qovery-) to store container images built from your source code
repositories.getIamPolicy, setIamPolicyGrants the cluster service account pull access to Qovery repositories
repositories.uploadArtifacts, downloadArtifacts, readViaVirtualRepository, deleteArtifactsPushes built images during CI/CD, pulls images during deployment, cleans up old images
repositories.createTagBinding, deleteTagBinding, listEffectiveTags, listTagBindingsTags repositories for lifecycle tracking
dockerimages.get, listLists and inspects images for version management and cleanup
tags.create, delete, get, list, updateManages image tags (e.g., latest, commit SHA, version numbers)
versions.delete, get, listManages image versions and removes unused versions to save storage costs
locations.get, listDiscovers available Artifact Registry regions

Compute Engine — Networking

VPC Networks — compute.networks.*

PermissionWhy
create, delete, get, listCreates a dedicated VPC for the GKE cluster or uses an existing one
access, use, useExternalIpAllows GKE nodes and pods to use the VPC for networking
getEffectiveFirewalls, getRegionEffectiveFirewallsReads firewall state for debugging and validation
setFirewallPolicy, updatePolicy, updatePeeringConfigures network policies and VPC peering for cross-VPC connectivity
mirrorNetwork traffic mirroring for security analysis (if enabled)
createTagBinding, deleteTagBinding, listEffectiveTags, listTagBindingsTags networks for lifecycle tracking

Subnetworks — compute.subnetworks.*

PermissionWhy
create, delete, update, get, listCreates subnetworks for GKE pods and services with secondary IP ranges
use, useExternalIpAllows GKE to schedule pods in the subnetwork
expandIpCidrRangeExpands subnet CIDR if more pod IPs are needed
getIamPolicy, setIamPolicyGrants GKE access to the subnetwork
setPrivateIpGoogleAccessEnables private Google access so nodes can reach GCP APIs without public IPs
mirrorSubnet-level traffic mirroring
createTagBinding, deleteTagBinding, listEffectiveTags, listTagBindingsTags subnetworks for lifecycle tracking

Routers & NAT — compute.routers.*

PermissionWhy
create, delete, update, get, listCreates Cloud Routers for NAT gateway configuration
useAssociates the router with the VPC network
getRoutePolicy, deleteRoutePolicy, listRoutePolicies, updateRoutePolicy, listBgpRoutesManages BGP routing policies for advanced networking

Routes — compute.routes.*

PermissionWhy
create, delete, get, listCreates custom routes for VPC traffic (e.g., routing to NAT gateway)
createTagBinding, deleteTagBinding, listEffectiveTags, listTagBindingsTags routes for lifecycle tracking

Instance Groups — compute.instanceGroupManagers.*, compute.instanceGroups.*

PermissionWhy
get, list, update, useReads and manages GKE node pool instance groups (managed by Autopilot)
listEffectiveTags, listTagBindingsTags instance groups for lifecycle tracking

Regions — compute.regions.*

PermissionWhy
get, listDiscovers available regions for cluster placement

Cloud Storage — storage.*

Qovery creates three GCS buckets per cluster, all prefixed with qovery-:
  • qovery-kubeconfigs-{id} — Stores kubeconfig files (versioned)
  • qovery-logs-{id} — Stores application and infrastructure logs (Loki)
  • qovery-prometheus-{id} — Stores metrics (Thanos long-term storage)

Bucket Operations — storage.buckets.*

PermissionWhy
create, delete, update, get, listFull lifecycle management of Qovery GCS buckets
getIamPolicy, setIamPolicyGrants Loki and Thanos service accounts access to their respective buckets
enableObjectRetention, restoreConfigures retention policies for compliance
getObjectInsightsStorage analytics for cost optimization
createTagBinding, deleteTagBinding, listEffectiveTags, listTagBindingsTags buckets for lifecycle tracking

Object Operations — storage.objects.*

PermissionWhy
create, delete, update, get, listReads and writes kubeconfigs, log chunks, and metrics blocks
getIamPolicy, setIamPolicyFine-grained object-level access control
overrideUnlockedRetention, setRetention, restoreManages object retention for compliance requirements

Other Storage — storage.bucketOperations.*, storage.managedFolders.*, storage.multipartUploads.*

Permission groupWhy
bucketOperations.cancel, get, listMonitors and manages long-running bucket operations
managedFolders.*Organizes objects within buckets with folder-level IAM
multipartUploads.*Large file uploads (log archives, metrics snapshots) using multipart upload

Cloud Run — run.*

Qovery uses Cloud Run Jobs for asynchronous cleanup tasks (e.g., deleting GCS buckets with many objects in the background).

Services — run.services.*

PermissionWhy
create, delete, update, get, listManages Cloud Run services if enabled for workload deployment
getIamPolicyReads IAM policies on Cloud Run services
listEffectiveTags, listTagBindingsTags services for lifecycle tracking

Jobs — run.jobs.*

PermissionWhy
create, delete, update, get, listCreates cleanup jobs that run gcloud storage rm to delete buckets asynchronously
run, runWithOverridesExecutes jobs with specific parameters (bucket name, cleanup commands)
getIamPolicyReads IAM policies on Cloud Run jobs
listEffectiveTags, listTagBindingsTags jobs for lifecycle tracking

Other Cloud Run — run.configurations.*, run.executions.*, run.revisions.*, run.routes.*, run.operations.*, run.locations.*

Permission groupWhy
configurations.get, listReads service configuration state
executions.cancel, delete, get, listMonitors and manages job execution lifecycle
revisions.delete, get, listManages Cloud Run revision history
routes.get, list, invokeRoutes traffic to Cloud Run services
operations.delete, get, listMonitors long-running Cloud Run operations
locations.listDiscovers available Cloud Run regions

What Qovery Creates in Your Account

Here’s a summary of all resources Qovery provisions per cluster:
ResourceCountPurpose
GKE Autopilot cluster1Managed Kubernetes control plane
VPC network1Network isolation for the cluster
Subnetwork1Pod and service IP ranges
Cloud Router1BGP router for NAT configuration
Cloud NAT1Outbound internet access for nodes
GCS buckets3Kubeconfigs, logs (Loki), metrics (Thanos)
Artifact Registry repositories1+Docker image storage
Service accounts5+Cluster nodes, Loki, ESO, KEDA, Thanos
Firewall rules5+Intra-cluster, webhook, and logging rules

Security Best Practices

The permissions listed are the minimum required for Qovery to fully manage your GKE infrastructure. If you don’t use certain features (e.g., Cloud Run workloads), contact Qovery support for a tailored minimal role.
GCP’s Kubernetes Engine permissions are extremely granular — each Kubernetes resource type (Pod, Service, Deployment, etc.) and action (create, get, list, update, delete) requires a separate permission. Qovery fully manages the cluster lifecycle, including deploying system components (ingress, monitoring, logging, autoscaling) via Helm charts, which requires CRUD access to nearly all Kubernetes resource types.
Qovery creates dedicated service accounts with Workload Identity bindings:
  • Cluster node SA — logging, monitoring, image pull
  • Loki SA — GCS access for log storage
  • ESO SA — Secret Manager access
  • KEDA SA — autoscaling metrics
  • Thanos SA — GCS access for metrics storage
Each SA has the minimum permissions for its specific function.
Enable GCP Audit Logs on your project to get a full record of every API call made by the Qovery service account. You can also review Qovery’s audit logs for a high-level view.