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:
Enables required GCP APIs (Container, Compute, Artifact Registry, Storage, Resource Manager, Cloud Run)
Creates a custom IAM role with the exact permissions listed below
Creates a service account and binds it to the custom role
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
API Why 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.*
Permission Why 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.*
Permission Why 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 group Why 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 group Why 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 group Why 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 group Why 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 group Why 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 group Why 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 group Why 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 group Why 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.*
Permission Why 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.*
Permission Why 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.*
Permission Why 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.*
Permission Why 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.*
Permission Why get, list, update, useReads and manages GKE node pool instance groups (managed by Autopilot) listEffectiveTags, listTagBindingsTags instance groups for lifecycle tracking
Regions — compute.regions.*
Permission Why 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.*
Permission Why 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.*
Permission Why 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 group Why 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.*
Permission Why 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.*
Permission Why 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 group Why 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:
Resource Count Purpose GKE Autopilot cluster 1 Managed Kubernetes control plane VPC network 1 Network isolation for the cluster Subnetwork 1 Pod and service IP ranges Cloud Router 1 BGP router for NAT configuration Cloud NAT 1 Outbound internet access for nodes GCS buckets 3 Kubeconfigs, logs (Loki), metrics (Thanos) Artifact Registry repositories 1+ Docker image storage Service accounts 5+ Cluster nodes, Loki, ESO, KEDA, Thanos Firewall rules 5+ Intra-cluster, webhook, and logging rules
Security Best Practices
Can I restrict these permissions further?
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.
Why does Qovery need so many Kubernetes Engine permissions?
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.
What service accounts does Qovery create?
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.
How can I audit what Qovery does with these permissions?
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.