Open-source project
JamesWoolfenden/pike avatar
JamesWoolfenden/pike

Pike: deriving least privilege IAM policies from OpenTofu and Terraform code

Pike is a tool for determining the permissions or policy required for IAC code

934 stars48 forksHCLApache-2.0

At a glance

What is it?
Pike is a Go tool that reads OpenTofu or Terraform configuration and works out the IAM permissions needed to apply it, then emits a policy as JSON or as a deployable aws_iam_policy resource. It supports AWS, GCP and Azure, and its own documentation is blunt about the fact that the output is a starting point rather than a finished policy.
Who is it for?
Pike suits a platform team that has grown tired of copying administrator policies into CI roles and wants the permission list derived from the code instead, and it fits a reviewer who wants a readable diff when infrastructure changes.
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 1 day ago.
What is it written in?
Mainly HCL, 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

The problem is the wildcard policy that every CI role grows

Almost every Terraform pipeline ends up with an IAM role that can do far more than its code needs, because writing the exact permission list by hand is tedious and nobody revisits it. Pike attacks that specific problem. It is described as a tool to determine the minimum IAM permissions required to run OpenTofu or Terraform infrastructure code, and the recent additions listed in the README are all in that direction: JSON modules support, a GCP compare mode that checks what your IaC needs against a deployed role, and backend detection for S3 and GCP. The audience is infrastructure engineers and security engineers who own the CI identity, and secondarily the developers writing the Terraform who would rather not hand-maintain policy documents. The value proposition is narrow on purpose. Pike does not replace a policy review, it replaces the guesswork involved in writing one, which is why the tool also has a compare mode rather than only a generate mode.

Lookup maps per provider turn resource types into action lists

The mechanism sits in a mapping directory the README links to directly, at src/mapping, and the documentation invites contributions to add new resources there. Each provider keeps its own map of resource types to the IAM actions those resources require. A scan parses the configuration, finds every resource type in it, looks each one up in the map for the provider in play, and collects the union of the actions into a single policy statement. The AWS side has the most supported resources, and Azure is the most recent addition, with GCP in between. The mapping approach is what makes the tool extensible without touching the core, and the same mapping mechanism is also what a contributor edits when they add a resource. The go.mod file confirms the shape of the implementation: the AWS SDK v2 modules for iam and sts are direct dependencies, hashicorp hcl v2 and terraform-json handle configuration parsing, and the CLI itself is built on urfave/cli v2 with zerolog for logging.

A scan produces a JSON policy document, not a finished policy

Running a scan against a directory of OpenTofu or Terraform files prints the permissions as a JSON policy document. The README's own example shows the shape: a single statement with Effect Allow, a list of ec2 actions covering instance monitoring, describing, running, stopping and terminating instances, security group authoring and network interface description, and a Resource of *. Two features of that output deserve attention. First, the resource list is a single star, so the actions are not constrained to the resources the code creates. Second, and stated plainly in the README, there are no conditions, and partial resources are wild-carded for now. The documentation is careful about what this means. It calls the output a first step, notes that best practice would go further, and says you will need to modify the permissions to what your environment requires by adding restrictions yourself. It also points at a second path: deploying with short-lived credentials, generating them for your build and then invoking your build remotely, which the README describes with the words QUICKER for the static approach and INVOKE and REMOTE for the alternative.

Abridged, the document the scan prints looks like this:

json
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "ec2:MonitorInstances",
            "ec2:DescribeInstances"
        ],
        "Resource": "*"
    }
}

The full example in the README lists twenty ec2 actions against the same single star resource.

Installing and running a first scan in three commands

The quick start is three steps: install, scan, generate. On macOS the binary comes from a personal Homebrew tap, and on Windows from a Scoop bucket. Installing from source is a single go install of the module path. The scan command points at a directory with the -d flag and prints the JSON policy. Adding the -o terraform flag switches the output to a policy resource you can deploy, described in the README as creating an aws_iam_policy resource. From there the README names two next commands, pike make to deploy the policy directly and pike compare to validate against existing policies. The README also lists a longer command surface under Usage, with sections for scan, output, make, invoke, apply, remote, readme, pull, runtime, watch and parse, plus compare, help, building, inspect and extending, and a Docker image published under the jameswoolfenden/pike name.

On macOS:

shell
brew tap jameswoolfenden/homebrew-tap
brew install jameswoolfenden/tap/pike

On Windows, add the Scoop bucket first and then install:

shell
scoop bucket add iac https://github.com/JamesWoolfenden/scoop.git
scoop install pike

Or install straight from source:

shell
go install github.com/jameswoolfenden/pike@latest

With the binary on your path, point a scan at a directory of infrastructure code:

shell
pike scan -d ./path/to/your/terraform

That prints the JSON policy to standard output. Add the output flag when you would rather have a policy resource:

shell
pike scan -o terraform -d ./path/to/your/terraform

Running Pike in Docker against a mounted Terraform directory

For CI, where installing a Go binary on the runner is inconvenient, the project publishes a container image. The documented invocation pulls the image and mounts the Terraform directory at /tf inside the container, then runs a scan against that path. The Dockerfile itself explains the design decisions, and they are worth reading before you depend on the image. It is a multi-stage build: the builder stage compiles pike from the checked-out sources rather than fetching the latest release at build time, so the image is reproducible from a specific commit. The runtime stage is a minimal Alpine image with a non-root user created through adduser with a fixed uid of 10001, and it installs bash, ca-certificates and git with pinned versions, because entrypoint.sh needs bash and the Terraform or OpenTofu flows often want git and trusted certificates. The image is built with CGO disabled and trimmed with the -s -w linker flags, and the version string is a constant in src/version.go rather than something injected at link time.

GCP organisation level resources are marked as unvalidated placeholders

This is the limitation to read before trusting a result. The README carries a note on placeholder resources: some entries in the lookup maps, particularly the GCP organization, folder and billing-level resources, are marked as placeholder entries. Pike recognises those resources and will not error on them, but the permissions attached to them have not been validated through actual resource lifecycle testing, because those resources need organisation-level access or specialised account types that are hard to test in practice. In other words, the tool tells you nothing is wrong and everything is also unproven at the same time. AWS, which has the most supported resources, does not carry this caveat as prominently, and the new GCP compare mode is the feature to watch if your estate is GCP, since comparing what the code needs against a role that is actually deployed is a better test than reading a generated list. The README invites pull requests and issues for new resources, so gaps in the maps are a known and addressable state.

Static analysis against Checkov, and the boundary of what Pike infers

The project badge shows checkov verified, and the topics include bridgecrew and security, so the natural comparison is with static policy scanning of the same Terraform files. The approaches differ in what they look at. A scanner such as Checkov evaluates the configuration against a rule set and reports misconfigurations, including over-permissive roles that are already written in the code. Pike goes the other way: it starts from the resources in the code and derives the permissions, so it can produce a policy for a role that does not exist yet or replace an administrator wildcard. The cost of that direction is that Pike can only see what the configuration says. The README is explicit that the policies are determined statically and that unrecorded intentions can be impossible to infer, which is the same limitation that makes conditions absent: if a human decided that a bucket may only be written during a deploy window, the Terraform file does not carry that intent. Both tools can run on the same directory, and using one to answer what the code implies and the other to judge the result is a reasonable pairing.

Apache-2.0, fast releases, and a project that expects contributions

The licence field is Apache-2.0, which includes an explicit patent grant and is a permissive choice for a tool that will be run inside a build pipeline. The Dockerfile labels the published image with the same licence identifier. On maintenance, the pace is fast: v1.0.13 was published on 2026-10-19, v1.0.12 on 2026-08-21 and v1.0.11 on 2026-08-14, and the last push to the repository was on 2026-10-20, so the repository is not archived and is being worked on daily. That velocity is a double-edged fact for a tool you intend to pin in CI. The version numbers move often, the resource maps grow with every contribution, and a scan result can differ between two versions of Pike without the code changing. The repository layout suggests a mature process for that: a Makefile with build, release and test targets across many platforms, a goldens target that regenerates testdata/help.golden and testdata/api_surface.txt so CLI surface changes are reviewed in a diff, a CHANGELOG, CONTRIBUTING and SECURITY files, pre-commit hooks, golangci linting, codecov coverage reporting and goreleaser for the release builds. The upgrade cost is therefore low in effort but real in churn, and pinning a version in your pipeline is the sensible response.

Editorial conclusion

Pike suits a platform team that has grown tired of copying administrator policies into CI roles and wants the permission list derived from the code instead, and it fits a reviewer who wants a readable diff when infrastructure changes. It does not suit anyone who needs condition expressions, resource scoping or per-environment policy from the start, because the generated policies carry no conditions and wild-card resources, and it does not suit a GCP organisation or billing-level workflow, where the lookup entries are marked as placeholders without empirically validated permissions. Before adopting it, run a scan on a directory you already know, compare the output against the policy your pipeline actually uses today, and read the placeholder note in the README before trusting a GCP result.

Frequently asked questions

What does Pike do with my Terraform code?

It parses the OpenTofu or Terraform files in a directory, looks up each resource type in the provider mapping, and outputs the union of the IAM actions those resources need. The result is a JSON policy document with a Resource of star and no conditions.

Can Pike generate a deployable IAM policy resource?

Yes. Adding the -o terraform flag to the scan command outputs the policy as an aws_iam_policy resource you can deploy, and the pike make command is documented as a way to deploy the policy directly.

Which cloud providers does Pike support?

Pike supports AWS, GCP and Azure, with Azure the newest and AWS having the most supported resources. The lookup maps live under src/mapping in the repository, and contributions of new resources are invited.

How do I install Pike on Windows or macOS?

On macOS the Homebrew tap route is used, and on Windows Pike is distributed through a Scoop bucket that you add before installing. The Docker image is also published for CI use.

Official sources

  1. Issues
  2. JamesWoolfenden/pike on GitHub
  3. License: Apache-2.0
  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/jameswoolfenden-pike.svg)](https://hysenlabs.com/projects/jameswoolfenden-pike)

Was this useful?