Self-hosted service
DataDog/KubeHound avatar
DataDog/KubeHound

KubeHound: a Kubernetes attack graph for defenders, not just red teams

Tool for building Kubernetes attack paths

1,012 stars67 forksGoApache-2.0

At a glance

What is it?
KubeHound ingests a cluster and calculates the attack paths that exist between its assets, storing them in a Gremlin graph you can query from a notebook or a script. It ships as a Go binary, needs Docker and Docker Compose, and is built for purple team work and security auditing rather than exploitation.
Who is it for?
KubeHound suits a cluster security team that wants to see which workloads can reach which other workloads, because a graph of concrete reachable edges answers questions that a list of CVEs cannot, and it gives the defender the same map an adversary would build.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the graph actually computes

The README describes KubeHound as a Kubernetes attack graph tool allowing automated calculation of attack paths between assets in a cluster. That phrasing matters, because the tool does not scan for vulnerabilities and it does not exploit anything. It reads the state of a cluster, works out which assets are connected by which permissions, and expresses those connections as attack paths.

The result is a graph. Nodes are cluster assets, edges are the attack primitives between them, and a path through the graph is a route from a starting point to something worth reaching. The README points to a sample path image and to docs/reference/attacks for the edge definitions, which is where the catalogue of modelled attack classes lives.

This is the BloodHound idea applied to Kubernetes. The README explicitly credits the BloodHound team for pioneering the use of graph theory in offensive security and inspiring the project, and BloodHound is the model: a graph of who can reach what, used to find the paths that matter.

The topics list frames the intent as adversary-emulation, purple-team, red-team and security-audit work. The tool is built for the people who want to think like the attacker, but it is a read-only analysis tool that produces a map rather than a breach.

Gremlin is the query language, and a notebook is the front end

Querying the stored graph data requires the Gremlin query language through an API call or a dedicated graph query UI. The README notes that a number of fully featured graph query UIs exist, commercial and open source, and that the project ships an accompanying Jupyter notebook based on the AWS Graph Notebook.

The access path is straightforward. You visit http://localhost:8888/notebooks/KubeHound.ipynb, log in with the default password admin, follow the initial setup instructions to connect to the graph and configure the rendering, and then start running queries.

Two details are worth flagging. The password can be changed in the notebook Dockerfile or by setting the NOTEBOOK_PASSWORD environment variable in the deployments .env file, so the default should be treated as a placeholder to change before anything else. And the project documents a KubeHound DSL, a specific language for the most basic query cases, layered over raw Gremlin.

The reason a graph query language is the right interface here is worth stating plainly. Asking which pods can reach which secrets, or which workload account can list secrets cluster-wide, is a traversal question, not a filter question. Writing that as nested JSONPath-style filters is where query tools usually get unreadable.

Two installation routes, and one that insists on a tag

The runtime requirements are Docker at version 19.03 or newer and Docker Compose V2. Both are needed because the tool orchestrates the graph store and the notebook alongside itself.

There are three ways to get the binary. Prebuilt binaries for Linux, Windows and Mac OS are on the releases page, and the README gives a one-liner that derives the OS and architecture from uname.

bash
wget https://github.com/DataDog/KubeHound/releases/latest/download/kubehound-$(uname -o | sed 's/GNU\///g')-$(uname -m) -O kubehound
chmod +x kubehound

Homebrew is the least effort route, since the tool is in homebrew-core.

bash
brew update && brew install kubehound

The source route has one instruction that saves you a broken build. The README says you need to checkout a tag before building, and the command it gives uses git describe --tags --abbrev=0 to pick the most recent tag, then make build, which outputs the binary to ./bin/build/kubehound. Building the default branch instead of a tag is the kind of thing that produces a binary that does not match any release.

On macOS there is one extra step if you downloaded through a browser rather than wget: xattr -d com.apple.quarantine kubehound, to stop the quarantine attribute from blocking execution.

Pointing it at a cluster and generating sample data

Selecting the target cluster is a two line decision. You either use kubectx to switch the active context, or you export the KUBECONFIG environment variable pointing at a specific kubeconfig file.

bash
export KUBECONFIG=/your/path/to/.kube/config

Then you run the binary, with the path depending on how you installed it. A brew install puts kubehound on your path, a release download means you run ./kubehound from where you downloaded it, and a source build means ./bin/build/kubehound inside the repository.

For a dry run without touching a real cluster, the Makefile provides a sample target.

bash
make sample-graph

The README describes this as generating data by running the app against the provided kind cluster, a deliberately very vulnerable cluster, so you can see what the graph looks like when there is a lot to find. That is a genuinely useful evaluation tool, because it shows the output shape and the attack path structure without requiring you to point a security tool at production.

Beyond the binary there are also subcommands, the README mentions dump and ingest, and a separate deployment mode called KHaaS, a hosted service version described on the project site.

Querying the graph from your own scripts

If you expose the graph endpoint, the README shows how to query the database from a Python script, using the gremlinpython driver and a snippet that counts containers.

python
#!/usr/bin/env python
import sys
from gremlin_python.driver.client import Client

KH_QUERY = "kh.containers().count()"
c = Client("ws://127.0.0.1:8182/gremlin", "kh")
results = c.submit(KH_QUERY).all().result()

The dependency is installed with pip install gremlinpython. The query itself uses the KubeHound DSL rather than raw Gremlin, which is the point of having a project-specific language layered on top.

The README frames this as a way to gather KPIs and metadata for automation, and that is the route to a durable answer to the question the tool raises. A one-off graph is a screenshot, a query you can re-run on a schedule is a control.

One caution is worth stating because it is visible in the code rather than hidden in it: the connection string points at a websocket on port 8182, and the notebook is on 8888 with a default password. Both are local defaults meant for a developer machine. If you intend to expose the graph endpoint, the notebook password change and the network exposure are the first two things to sort out.

A Go project with an unusually explicit dependency list

The go.mod file is worth reading for what it reveals about the architecture. The module targets Go 1.26.0, and the direct dependencies line up with the described behaviour: the TinkerPop Gremlin client for graph access, controller-runtime and the Kubernetes client libraries for cluster interaction, cobra and viper for the command line and configuration, the Docker client and compose packages for driving the local stack, mongo-driver and gocloud.dev for storage abstractions, and zap for logging.

Two entries in that file are unusual. The in-toto dependency carries a comment explaining it must be bumped to v0.9.0 to fix a breaking change in the go-securesystemslib package that breaks Docker Compose, and golang.org/x/net is pinned with a comment referencing CVE-2025-22870. Those are the fingerprints of a supply chain aware team, which is expected from a Datadog project but is still good practice to see written down in the manifest.

The build is a multi-stage Dockerfile using the tonistiigi/xx cross-compilation helper with an osxcross toolchain for Darwin targets, a separate golangci-lint stage, and CGO_ENABLED=0 in the base stage. The Makefile injects build version, branch, architecture and OS into the binary through ldflags, so a binary can report what it is.

Licence, third-party notices and release cadence

The licence is Apache-2.0, and the repository carries a NOTICE file alongside LICENSE-3rdparty.csv, which is the file that records the licences of the vendored third-party components. For a security tool that ships binaries to be run against a production cluster, having that inventory in the repository rather than in a wiki page is a real convenience for a legal review.

There is also a SECURITY.md at the root and a CONTRIBUTING.md, and the README points to a contribution path specifically for adding a new attack type, following the contribution guidelines. That matters for a tool whose value is the breadth of its edge catalogue: a new Kubernetes misconfiguration is only useful if someone can encode it as an edge.

The documentation is a mkdocs site. The pyproject.toml in the repository root defines a project named kubehoundpc-wiki whose description is to generate and serve the mkdocs wiki on localhost, pulling in mkdocs, the material theme, the awesome-pages plugin and markdown-captions, with Python 3.11 as the floor.

On releases, the picture is mixed in a way worth naming. The last tagged versions are v1.6.7 from 2025-11-14, v1.6.6 from 2025-09-24 and v1.6.5 from 2025-09-19, while the last push to the repository was on 2026-10-19. Development has continued well past the most recent tag, so if you need a specific behaviour, read the tag rather than assuming the newest commit matches the newest release.

Editorial conclusion

KubeHound suits a cluster security team that wants to see which workloads can reach which other workloads, because a graph of concrete reachable edges answers questions that a list of CVEs cannot, and it gives the defender the same map an adversary would build. It is the wrong tool if you need to fix the findings, since it reports paths rather than enforcing policy, and it is the wrong tool for an air-gapped environment where the Docker and Compose dependency and the graph endpoint do not fit. Before you adopt it, run make sample-graph against the provided kind cluster to see the output shape, and check the edge definitions under docs/reference/attacks to confirm the attack classes it actually models match the misconfigurations present in your own cluster.

Frequently asked questions

What are the requirements to run KubeHound?

Docker at version 19.03 or newer and Docker Compose V2. Beyond that, you need a target Kubernetes cluster selected either with kubectx or by exporting the KUBECONFIG environment variable.

How do I build KubeHound from source?

Clone the repository, check out a tag with git checkout $(git describe --tags --abbrev=0), then run make build. The binary is output to ./bin/build/kubehound.

How do I query the KubeHound graph data?

The graph is queried with the Gremlin query language through an API call or a graph query UI. The project ships a Jupyter notebook based on the AWS Graph Notebook, reachable at http://localhost:8888/notebooks/KubeHound.ipynb, and a KubeHound DSL for basic queries.

Can I try KubeHound without pointing it at a real cluster?

Yes. Running make sample-graph generates data by running the app against the provided kind cluster, a deliberately very vulnerable cluster, so you can see the graph and the attack paths before using it anywhere real.

What licence is KubeHound released under?

Apache-2.0. The repository also carries a NOTICE file and a LICENSE-3rdparty.csv recording the licences of third-party components.

Official sources

  1. DataDog/KubeHound on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/datadog-kubehound.svg)](https://hysenlabs.com/projects/datadog-kubehound)

Was this useful?