# GKE Policy Automation: checking a GKE cluster against its own best practices

> GKE Policy Automation is a Go tool and a Rego policy library that validates Google Kubernetes Engine clusters against configuration best practices and against the quotas and limits that will bite you at scale. It can read live GKE and Cloud Monitoring data, or a local JSON export, and publish results to a file, Pub/Sub, Cloud Storage or Security Command Center.

**google/gke-policy-automation** — Tool and policy library for reviewing Google Kubernetes Engine clusters against best practices

- Repository: https://github.com/google/gke-policy-automation
- Stars: 526 · Forks: 28
- Language: Go
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/google-gke-policy-automation

## What the tool checks, and what it is careful to say about itself

The repository contains the tool and the policy library for validating GKE clusters against configuration best practices and against scalability limits. The description calls it a tool and policy library for reviewing Google Kubernetes Engine clusters against best practices, and the topics name gcp, gke, opa and rego, which tells you the rules are written in Rego and evaluated with the Open Policy Agent.

Two checks are offered and they are quite different in kind. The best practices check validates a cluster against the set of GKE configuration policies, which is a static comparison of the cluster's current configuration against a curated set of rules about how a cluster should be set up. The scalability check validates a cluster against the GKE quotas and limits, and reports violations when the current values will cross the certain thresholds, which is a projection rather than a snapshot.

That distinction is the most useful thing in the README, because the two checks need different inputs and answer different questions. One asks whether the cluster is configured the way it should be. The other asks whether the cluster will still work when it is twice the size, which is a question about the rate at which something is growing rather than about a setting being wrong today.

The disclaimer is short and should be quoted: note, this is not an officially supported Google product. The code is Apache-2.0 licensed and the project is under the google GitHub organisation, and the policy library is the part that carries the Google investment. The tool itself is something the community runs.

The primary language is Go, the default branch is main, the last push was on 2026-09-04, and the recent releases are v1.4.8 on 2026-09-04, v1.4.7 on 2026-07-21 and v1.4.6 on 2026-07-21.

## Four ways to install it, and which one fits your setup

The installation section offers a container image, a kubectl plugin, a binary and a source build, which is a sensible spread for a tool that has to run both on a workstation and inside a cluster.

The container image is hosted on ghcr.io, and the packages page lists all the tags and versions. Running it directly against a cluster is one command:

```sh
docker pull ghcr.io/google/gke-policy-automation:latest
docker run --rm ghcr.io/google/gke-policy-automation check \
-project my-project -location europe-west2 -name my-cluster
```

The container is built from gcr.io/distroless/static-debian12, with the binary copied to /gke-policy, a nonroot:nonroot user, and the entrypoint set to that binary. A distroless base means there is no shell and no package manager in the image, which is the right choice for something that reads cloud credentials.

The Krew route turns it into a kubectl plugin, which is the most convenient option if you already use kubectl plugins:

```sh
kubectl krew install gke-policy
kubectl gke-policy check --discovery -p my-project
```

Binaries for Linux, Windows and Mac are available as tarballs on the release page, which is the option with no container runtime and no cluster access to the plugin mechanism.

For source builds, Go v1.26 or newer is required, and the development guide has the details:

```sh
git clone https://github.com/google/gke-policy-automation.git
cd gke-policy-automation
make build
./gke-policy check \
--project my-project --location europe-west2 --name my-cluster
```

The build uses a GNUmakefile rather than a bare Makefile, and there is a .goreleaser.yaml at the root for producing the release artefacts, plus a .krew.yaml for the plugin manifest and a Dockerfile for the image. The presence of both a release configuration and a plugin manifest in the root is what makes the four install routes possible from one codebase.

## Running the two checks, and the metrics dependency for the second

The best practices check is the simple one, and it is what most people will run first:

```sh
./gke-policy check \
--project my-project --location europe-west2 --name my-cluster
```

The scalability check takes a subcommand, because it is a different kind of check with different inputs:

```sh
./gke-policy check scalability \
--project my-project --location europe-west2 --name my-cluster
```

And it has a hard prerequisite, stated in bold in the README: you need to run kube-state-metrics to export cluster metrics to use the cluster scalability limits check, with a separate installation and configuration guide for it in the docs directory.

The reason is that a scalability projection needs history, not a snapshot. To tell you that a node pool will cross a limit at some point, the tool needs to know how the current values are trending, and the trend comes from a time series of cluster metrics. kube-state-metrics is what produces that series.

The tool assumes the metrics are available in Cloud Monitoring, in other words the result of Google Cloud Managed Service for Prometheus based metrics collection. If you use self-managed Prometheus collection instead, there are two extra steps. First, configure Prometheus scraping for kube-state-metrics using PodMonitor or ServiceMonitor and the corresponding annotations, specifically prometheus.io/scrape. Second, configure the custom Prometheus API server address in the tool, which is done in the config file:

```yaml
     inputs:
       metricsAPI:
         enabled: true
         address: http://my-prometheus-svc:8080 # Prometheus server API endpoint
         username: user   # username for basic authentication (optional)
         password: secret # password for basic authentication (optional)
```

and then run the scalability check with that config, passing the file with the -c option.

The basic authentication fields are optional, which matters because a Prometheus API server inside a cluster is often reached over a service address that has no external authentication layer. The address field is a plain HTTP endpoint, so the tool is reaching the Prometheus API directly rather than going through Cloud Monitoring, which is what makes the self-managed path work at all.

## Checking many clusters, and the discovery mode

The common check options apply to all types of check command, and the first is about scale.

To check several named clusters, you list them in the config file and pass it with -c:

```sh
./gke-policy check -c config.yaml
```

The file lists clusters either by name, project and location, or by a full resource id:

```yaml
clusters:
  - name: prod-central
    project: my-project-one
    location: europe-central2
  - id: projects/my-project-two/locations/europe-west2/clusters/prod-west
```

Two forms, because a cluster in another project is often easier to name by its full id than by a triple, and the tool accepts both.

Discovery mode is the more interesting option, because it is the one that makes the tool usable across an organisation. You can discover clusters in selected GCP projects, folders or in the entire organization using Cloud Asset Inventory and a configuration file:

```yaml
clusterDiscovery:
  enabled: true
  organization: "123456789012"
```

And you can do it for a single project using command line flags only, with no config file at all:

```sh
./gke-policy check --discovery -p my-project-id
```

The two discovery forms differ in reach. The organization form with Cloud Asset Inventory is the only one that can enumerate clusters across folders and projects you do not have listed anywhere else, which is how you catch the cluster somebody created in the wrong project.

The same command shape appears in the Krew example, which is worth noting: kubectl gke-policy check --discovery -p my-project is the same check as the binary invocation, so a plugin installation does not cost you any functionality.

## Inputs and outputs, and where the results can go

The input and output sections are the parts that matter for anyone wiring this into a pipeline.

Data for cluster validation can be retrieved from multiple data sources, for example the GKE API, the Cloud Monitoring API, or a local JSON file exported from the GKE API. For best practices checks the GKE API is enabled by default, and for scalability checks the metrics API is enabled as well. A config file overrides that:

```yaml
inputs:
  gkeAPI:
    enabled: true
  gkeLocal:
    enabled: false
    file:
  metricsAPI:
    enabled: true
    project: sample-project
    metrics:
```

The gkeLocal entry is the one to look at if you want reproducible runs. A local JSON file exported from the GKE API means the check can be run against a fixed snapshot, which is what you want in a pipeline where the result has to be comparable to the last one.

On the output side, the cluster validation results can be published to multiple outputs, including a JSON file, a Pub/Sub topic, a Cloud Storage bucket or Security Command Center. The example given for a JSON file output is a command line invocation with an output file flag:

```sh
  ./gke-policy check \
  --project my-project --location europe-west2 --name my-cluster \
  --out-file output.j
```

The four outputs map onto four different uses. A JSON file is for you to read. Pub/Sub is for a pipeline that wants an event per finding. Cloud Storage is for keeping a history of runs. Security Command Center is for the findings to show up in the place your security team already looks, which is usually the one that gets acted on.

The go.mod confirms those output paths are real rather than aspirational, since it requires the Pub/Sub, Storage and Security Center client libraries alongside the container and asset clients and the Open Policy Agent itself. It also requires the Prometheus client, which is consistent with the metrics path in the scalability check, and urfave/cli for the command line surface with a subcommand for check, which matches the check and check scalability forms.

## The policy library and the repository layout

The repository root shows the project split into a tool and its rules, with the rules in two directories. There is gke-policies-v2/ and there is gke-policies/, and the README links the policy library as ./gke-policies-v2.

Two policy directories means a versioned policy set, and the v2 in the linked path is the current one. For a tool whose output is a set of findings, the policy version is part of the contract: findings change when rules change, and a tool that reports violations without saying which rule set it applied is not much use in a compliance context. The two directories and the changelog are how that version is tracked.

The rest of the root is a well-organised Go project. There is main.go, an internal/ directory for the implementation, a docs/ directory holding the user guide, the inputs guide, the outputs guide and the kube-state-metrics guide, a scripts/ directory, a terraform/ directory, and a GNUmakefile. There are also a CHANGELOG.md, a CONTRIBUTING.md, a DEVELOPMENT.md and a LICENSE, and a .regal/ directory, which is the configuration directory for Regal, the linter for Rego, so the policies themselves are linted in CI alongside the Go code.

The workflows tell the same story. There is a build badge and a policy tests badge, so the Rego policies have their own test suite separate from the Go build, which is the right split since a broken policy is a silent failure and a broken build is not.

The remaining root files are the housekeeping you would expect in a Google project: a .markdownlint.yml, a .mlc_config.json for link checking, a .terminalizer.yml, a .gitignore, and a Dockerfile already covered above.

So the shape of the project is a small Go CLI wrapping the Open Policy Agent, a versioned Rego policy library that carries the actual rules, and a set of Google Cloud integrations so the tool can both read cluster state and publish findings back into the platform you already run.

## Conclusion

Adopt GKE Policy Automation if you run several GKE clusters and want the configuration review and the scalability projection to be a repeatable check rather than an occasional audit, especially since the discovery mode can cover a whole organisation through Cloud Asset Inventory. Do not adopt it expecting a managed Google product, because the README states plainly that this is not an officially supported Google product. Before running the scalability check, set up kube-state-metrics with metrics available in Cloud Monitoring, and if you self-manage Prometheus, point the tool at your own API server address and configure the scraping annotations.

## FAQ

### What does GKE Policy Automation do?

It validates GKE clusters against a set of GKE configuration best practices and against the GKE quotas and limits, reporting violations when current values will cross certain thresholds. The rules are written in Rego and evaluated with the Open Policy Agent.

### What does the scalability check need that the best practices check does not?

It needs cluster metrics, so you must run kube-state-metrics to export them, and the tool assumes the metrics are available in Cloud Monitoring through Google Cloud Managed Service for Prometheus. With self-managed Prometheus you configure scraping annotations and point the tool at your own API server address in the config file.

### How do I check every GKE cluster in my organization?

Use cluster discovery, enabled in the config file with an organization id under clusterDiscovery, which uses Cloud Asset Inventory to enumerate clusters across projects and folders. For a single project you can use the command line flag --discovery -p my-project-id instead of a config file.

### Where can GKE Policy Automation publish its findings?

Multiple outputs are supported, including a JSON file, a Pub/Sub topic, a Cloud Storage bucket or Security Command Center. The JSON file example uses the --out-file flag on the check command.

### Is GKE Policy Automation an officially supported Google product?

No. The README states plainly that this is not an officially supported Google product, even though the repository lives under the google organisation and is licensed under Apache 2.0 with the policy library maintained alongside the tool.

## Sources

- [google/gke-policy-automation on GitHub](https://github.com/google/gke-policy-automation)
- [Issues](https://github.com/google/gke-policy-automation/issues)
- [License: Apache-2.0](https://github.com/google/gke-policy-automation/blob/main/LICENSE)
- [README](https://github.com/google/gke-policy-automation/blob/main/README.md)
- [Releases](https://github.com/google/gke-policy-automation/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/google-gke-policy-automation
