# gittuf: a forge independent security layer for Git

> gittuf is a platform agnostic Git security system that lets maintainers protect a repository from unauthorized changes using signed policy and rules, so that any developer can verify locally that the history followed the expected rules. It is a Go project in beta under the OpenSSF.

**gittuf/gittuf** — A security layer for Git repositories

- Repository: https://github.com/gittuf/gittuf
- Website: https://gittuf.dev
- Stars: 670 · Forks: 146
- Language: Go
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/gittuf-gittuf

## Taking the forge out of the trust chain

gittuf is described as a platform agnostic Git security system, and the maintainers of a Git repository can use it to protect the contents of the repository from unauthorized or malicious changes. The important sentence is the one that follows, about what is most significant: the policy controls and enforcement are not tied to your source control platform, or forge, which means any developer can independently verify that a repository's changes followed the expected security policies. In other words, the README says plainly that gittuf removes the forge as a single point of trust in the software supply chain. That framing is the whole design. A forge's protection rules live on the forge's servers, are enforced by the forge, and are only as good as that vendor's uptime and policy. gittuf instead stores the policy in the repository itself, so verification is something you run locally against the objects you already have. The project describes itself as an incubating project at the Open Source Security Foundation, as part of the Supply Chain Integrity Working Group.

## Beta status and the advice to layer it

The Current Status section is short and unusually candid. gittuf is currently in beta. Its metadata is versioned, and updates should not require reinitializing a repository's gittuf policy, which is the property that decides whether the tool is usable in practice, since a security layer that must be reapplied from scratch on every upgrade is one nobody will keep. The recommendation is to try gittuf in addition to existing repository security mechanisms you may already be using, with forge security policies given as the example, and the project says it is actively seeking feedback and asks users to open an issue with suggestions or bugs. Read that as an instruction rather than as a hedge. The project is asking to be run alongside what you have, compared against it, and not to be trusted with the whole job yet. The badges on the front page support that reading, with a dedicated gittuf verification workflow, a build and test workflow, coverage, and OpenSSF Best Practices, Baseline and Scorecard badges.

## What the Go dependency list reveals

The go.mod file is the clearest description of what the tool actually does, and it is a list of security and signing libraries rather than of Git plumbing. The Sigstore family is central, with cosign for v3, fulcio, gitsign, sigstore, sigstore-go and protobuf-specs, and the in-toto attestation package for v1.2.0, which is what carries the metadata about who built what. `github.com/ProtonMail/go-crypto` provides the cryptographic primitives, and `github.com/hiddeco/sshsig` handles SSH signature verification. The Git side is `github.com/go-git/go-git/v6`, still at a beta version, and `github.com/secure-systems-lab/go-securesystemslib` supplies the in-toto and securesystemslib style metadata structures. The user interface is built with cobra for the command line, and with the Charm library set, bubbletea, bubbles and lipgloss, which is the terminal interface framework. The module targets Go 1.27.0 and is named github.com/gittuf/gittuf.

## Building and testing it from the Makefile

The Makefile in the repository is small and shows the shape of the development workflow. The build target depends on test and on a just-build target, and the release build disables cgo and uses trimpath with linker flags that stamp the version derived from `git describe --tags --always --dirty` into the binary. The install target does the same through `go install`. The test target runs the race detector over the whole tree with a twenty minute timeout:

```bash
test :
	go test -race -timeout 20m -v ./...
```

There are separate end-to-end tests, which build the binary and then run a shell script against it with the binary path passed in through an environment variable:

```bash
e2e : just-build
	GITTUF_BIN="$(CURDIR)/dist/gittuf" bash ./tests/run_e2e_tests.sh
```

The remaining targets are `fmt`, which runs `go fmt`, and `generate`, which runs `go generate`. The distinction between the end-to-end script and the Go tests is the interesting part, because an end-to-end test that drives the built binary is the only way to check the behaviour a user actually experiences, which for a tool that verifies signed history is the behaviour that matters.

## The repository layout and where the work happens

The top level of the repository has the shape of a Go project with a clear internal structure. There is `main.go` at the root, an `internal/` directory, a `pkg/` directory for the public API, a `tests/` directory, an `experimental/` directory, and a `debug/` directory. The `docs/` directory holds the documentation the README links to, including the get started guide, the contributing guide, and a roadmap file. The `pkg` and `internal` split is the standard Go convention and it tells you something about the project's intent, since a public package is a commitment to an API. Supporting files include the usual set, with a `Makefile`, `go.mod`, `go.sum`, a `CHANGELOG.md`, `CONTRIBUTING.md`, `SECURITY.md`, `SECURITY_INSIGHTS.yml`, `MAINTAINERS.txt` and a `CITATION.bib`. The `.goreleaser.yml` file points to GoReleaser for the release artefacts, and `.golangci.yml` for the linting configuration. The `experimental/` directory in particular is where you would expect anything that is not yet a supported part of the stable surface.

## What gittuf is not, and what it sits next to

The distinction that matters most is between a policy layer and a signing layer, because they solve different problems and are often confused. Code signing, in the form of signed tags and signed commits, proves that a particular person or key made a particular change. A policy layer decides which changes are allowed at all, and proves that the allowed set was applied. Sigstore's cosign and gitsign appear in the dependency list, so gittuf can consume and produce signatures, but the object of the exercise is the policy, and a signed change that violates the policy is still a violation. The second distinction is about who has to opt in. A forge's rules apply to everyone who interacts with that forge, silently. gittuf's rules are opt-in, which means a consumer that does not run gittuf sees ordinary Git history with some extra objects, and a consumer that does run it can check the rules for itself. That is the feature and also the cost, because until the ecosystem around a project adopts it, the enforcement is only as good as the willing participants.

## The adoption path the project describes

The README does not give installation commands, and it says so by pointing you at a get started guide, alongside the contributing guide, the roadmap and the issue tracker. The channels for involvement are the issue tracker for bugs and suggestions, the OpenSSF Slack workspace where the project has a channel, and the pull request process through the contributing guide. That is a project in the middle of its design phase, and the fact that the documentation lives in a separate `docs/` tree with a dedicated roadmap file is the honest signal of that. The version history shows how active it is: v0.15.0 in June 2026, v0.16.0 in September, and v0.17.0 on 2026-10-19, with the last push the same day. Frequent releases in a beta project mean frequent changes, which is fine while you are evaluating and is a reason to pin versions if you adopt it. The Apache-2.0 licence, with the SPDX identifier visible at the top of the Makefile, means you can read, modify and redistribute it without friction.

## Conclusion

gittuf fits a project that has outgrown a forge's own branch protection and wants its security rules to be verifiable by anyone who clones the repository, which is a different goal from code signing and a stronger one. It is the wrong tool if you need a single developer to adopt a change today, since adopting a policy means every consumer has to opt in, and it is the wrong tool if you are satisfied with signed tags, because gittuf does not replace that. Before you deploy it, read the get started guide and the roadmap, and try it alongside the protections you already have rather than instead of them. The last push was on 2026-10-19 with v0.17.0 released the same day, the project is Apache-2.0 licensed, and it is still in beta.

## FAQ

### What problem does gittuf solve?

It lets the maintainers of a Git repository protect its contents from unauthorized or malicious changes with policy controls that are not tied to the source control platform, so any developer can independently verify that the changes followed the expected security policies, removing the forge as a single point of trust in the supply chain.

### Is gittuf ready to use in production?

The README states that gittuf is currently in beta and recommends trying it in addition to existing repository security mechanisms such as forge security policies, rather than instead of them. The project is actively seeking feedback.

### Does upgrading gittuf require reinitialising a repository policy?

No. The README states that gittuf's metadata is versioned and that updates should not require reinitializing a repository's gittuf policy.

### How is gittuf built and tested?

The Makefile builds with cgo disabled and version information injected through linker flags, and the test target runs `go test -race -timeout 20m -v ./...`. There is a separate end-to-end target that builds the binary and runs `bash ./tests/run_e2e_tests.sh` against it, plus `fmt` and `generate` targets.

## Sources

- [gittuf/gittuf on GitHub](https://github.com/gittuf/gittuf)
- [License: Apache-2.0](https://github.com/gittuf/gittuf/blob/main/LICENSE)
- [Project website](https://gittuf.dev)
- [README](https://github.com/gittuf/gittuf/blob/main/README.md)
- [Releases](https://github.com/gittuf/gittuf/releases)

---

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