pax_global_header 0000666 0000000 0000000 00000000064 14751501410 0014510 g ustar 00root root 0000000 0000000 52 comment=f38f261f5df1d393a97aec3a5463017da6c22934
gittuf-0.9.0/ 0000775 0000000 0000000 00000000000 14751501410 0013020 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/.gitattributes 0000664 0000000 0000000 00000000046 14751501410 0015713 0 ustar 00root root 0000000 0000000 docs/cli/*.md linguist-generated=true
gittuf-0.9.0/.github/ 0000775 0000000 0000000 00000000000 14751501410 0014360 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 14751501410 0016543 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/.github/ISSUE_TEMPLATE/bug.yml 0000664 0000000 0000000 00000002015 14751501410 0020041 0 ustar 00root root 0000000 0000000 name: Bug Report
description: File a bug report
labels: ["bug"]
assignees:
- adityasaky
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: what-happened
attributes:
label: What happened?
description: Also tell us, what did you expect to happen? Please include the version or revision of gittuf.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: Please copy and paste the stack trace if it's available. This will be automatically formatted into code, so no need for backticks.
render: Shell
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/gittuf/community/blob/main/CODE-OF-CONDUCT.md)
options:
- label: I agree to follow this project's Code of Conduct
required: true
gittuf-0.9.0/.github/ISSUE_TEMPLATE/issue.yml 0000664 0000000 0000000 00000002210 14751501410 0020411 0 ustar 00root root 0000000 0000000 name: Discussion / Feature Request
description: Open a discussion for gittuf workflows or a feature request
labels: ["discussion"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to file this issue!
- type: textarea
id: Description
attributes:
label: Add a description
description: Please provide some details about what you'd like to discuss. If relevant, please include the version or revision of gittuf.
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output if the discussion pertains to existing gittuf functionality
description: Please copy and paste the stack trace if it's available. This will be automatically formatted into code, so no need for backticks.
render: Shell
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/gittuf/community/blob/main/CODE-OF-CONDUCT.md)
options:
- label: I agree to follow this project's Code of Conduct
required: true
gittuf-0.9.0/.github/dependabot.yml 0000664 0000000 0000000 00000001354 14751501410 0017213 0 ustar 00root root 0000000 0000000 version: 2
updates:
# Monitor Go dependencies
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
time: "14:00"
# Bundle updates into one PR
groups:
all:
applies-to: version-updates
patterns:
- "*"
commit-message:
prefix: "chore"
include: "scope"
open-pull-requests-limit: 10
# Monitor GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
time: "14:00"
# Bundle updates into one PR
groups:
all:
applies-to: version-updates
patterns:
- "*"
commit-message:
prefix: "chore"
include: "scope"
open-pull-requests-limit: 10
gittuf-0.9.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14751501410 0016415 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/.github/workflows/check-docs.sh 0000775 0000000 0000000 00000000212 14751501410 0020752 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -euo pipefail
make generate
if [[ $(git --no-pager diff) ]] ; then
echo "Please re-generate CLI docs"
exit 1
fi
gittuf-0.9.0/.github/workflows/ci.yml 0000664 0000000 0000000 00000001246 14751501410 0017536 0 ustar 00root root 0000000 0000000 name: tests
on:
push:
branches: ['main']
paths-ignore:
- "docs/*"
- "**.md"
pull_request:
paths-ignore:
- "docs/*"
- "**.md"
permissions: read-all
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: ['1.23']
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: ${{ matrix.go-version }}
cache: true
- name: Test
run: go test -timeout 20m ./...
gittuf-0.9.0/.github/workflows/codeql.yml 0000664 0000000 0000000 00000006717 14751501410 0020422 0 ustar 00root root 0000000 0000000 # For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "main" ]
paths-ignore:
- "docs/**"
- "**.md"
pull_request:
branches: [ "main" ]
paths-ignore:
- "docs/**"
- "**.md"
schedule:
- cron: '28 17 * * 6'
permissions: read-all
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ 'ubuntu-latest' }}
timeout-minutes: ${{ 360 }}
permissions:
# required for all workflows
security-events: write
strategy:
fail-fast: false
matrix:
include:
- language: go
build-mode: autobuild
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0
with:
category: "/language:${{matrix.language}}"
gittuf-0.9.0/.github/workflows/coverage.yml 0000664 0000000 0000000 00000001415 14751501410 0020734 0 ustar 00root root 0000000 0000000 name: coverage
on:
push:
branches: ['main']
paths-ignore:
- "docs/**"
- "**.md"
pull_request:
paths-ignore:
- "docs/**"
- "**.md"
permissions: read-all
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: 1.23
cache: true
- name: Check Coverage
run: go test -covermode=atomic -coverprofile='coverage.cov' `go list ./... | grep -v -f .test_ignore.txt`
- name: Coveralls Parallel
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b
with:
file: 'coverage.cov'
gittuf-0.9.0/.github/workflows/docs.yml 0000664 0000000 0000000 00000000610 14751501410 0020065 0 ustar 00root root 0000000 0000000 name: docs
on:
push:
branches: ['main']
pull_request:
permissions: read-all
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: '1.23'
cache: true
- run: ./.github/workflows/check-docs.sh
gittuf-0.9.0/.github/workflows/get-started-tests-policy-v02.yml 0000664 0000000 0000000 00000002145 14751501410 0024427 0 ustar 00root root 0000000 0000000 name: get-started-tests with policy v02
on:
push:
branches: ['main']
paths-ignore:
- "docs/**"
- "!docs/testing/**"
- "!docs/get-started.md"
- "*.md"
pull_request:
paths-ignore:
- "docs/**"
- "!docs/testing/**"
- "!docs/get-started.md"
- "*.md"
permissions: read-all
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: ['1.23']
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: ${{ matrix.go-version }}
cache: true
- name: Install Python
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38
with:
python-version: '3.10'
- name: Build gittuf
run: make just-install
- name: Test Getting Started
run: python3 docs/testing/test-get-started-md.py
env:
GITTUF_DEV: '1'
GITTUF_ALLOW_V02_POLICY: '1'
gittuf-0.9.0/.github/workflows/get-started-tests.yml 0000664 0000000 0000000 00000002015 14751501410 0022521 0 ustar 00root root 0000000 0000000 name: get-started-tests
on:
push:
branches: ['main']
paths-ignore:
- "docs/**"
- "!docs/testing/**"
- "!docs/get-started.md"
- "*.md"
pull_request:
paths-ignore:
- "docs/**"
- "!docs/testing/**"
- "!docs/get-started.md"
- "*.md"
permissions: read-all
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: ['1.23']
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: ${{ matrix.go-version }}
cache: true
- name: Install Python
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38
with:
python-version: '3.10'
- name: Build gittuf
run: make just-install
- name: Test Getting Started
run: python3 docs/testing/test-get-started-md.py
gittuf-0.9.0/.github/workflows/gittuf-rsl-main.yml 0000664 0000000 0000000 00000002442 14751501410 0022164 0 ustar 00root root 0000000 0000000 name: Record change to main branch
on:
push:
branches:
- 'main'
permissions: read-all
jobs:
create-rsl-entry:
if: github.repository == 'gittuf/gittuf'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Install gittuf
uses: gittuf/gittuf-installer@f31e69c7c18c7473cbce18ed69a559b945d3a738
- name: Install gitsign
uses: chainguard-dev/actions/setup-gitsign@main
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- name: Update RSL
env:
KEY: ${{ secrets.KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "$KEY" > /tmp/key
chmod 600 /tmp/key # ssh-keygen signer requires this
git fetch origin refs/gittuf/reference-state-log:refs/gittuf/reference-state-log refs/gittuf/attestations:refs/gittuf/attestations
GITTUF_DEV=1 gittuf dev attest-github --signing-key /tmp/key --repository ${{ github.repository }} --commit ${{ github.sha }} --base-branch "main"
gittuf rsl record main
git push origin refs/gittuf/reference-state-log:refs/gittuf/reference-state-log refs/gittuf/attestations:refs/gittuf/attestations
gittuf-0.9.0/.github/workflows/gittuf-rsl-non-main.yml 0000664 0000000 0000000 00000001565 14751501410 0022761 0 ustar 00root root 0000000 0000000 name: Record change to non-main branch
on:
push:
branches-ignore:
- 'main'
permissions: read-all
jobs:
create-rsl-entry:
if: github.repository == 'gittuf/gittuf'
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: Install gittuf
uses: gittuf/gittuf-installer@f31e69c7c18c7473cbce18ed69a559b945d3a738
- name: Install gitsign
uses: chainguard-dev/actions/setup-gitsign@main
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- name: Update RSL
run: |
git fetch origin refs/gittuf/reference-state-log:refs/gittuf/reference-state-log
gittuf rsl record ${{ github.ref }}
git push origin refs/gittuf/reference-state-log:refs/gittuf/reference-state-log
gittuf-0.9.0/.github/workflows/gittuf-verify.yml 0000664 0000000 0000000 00000001072 14751501410 0021744 0 ustar 00root root 0000000 0000000 name: gittuf Verification
on:
workflow_run:
workflows: ["Record change to main branch"]
branches: [main]
types:
- completed
permissions: read-all
jobs:
gittuf-verify:
if: github.repository == 'gittuf/gittuf'
runs-on: ubuntu-latest
steps:
- name: Install gittuf
uses: gittuf/gittuf-installer@f31e69c7c18c7473cbce18ed69a559b945d3a738
- name: Checkout and verify repository
run: |
gittuf clone https://github.com/${{ github.repository }}
cd gittuf
gittuf verify-ref main --verbose
gittuf-0.9.0/.github/workflows/lint.yml 0000664 0000000 0000000 00000001166 14751501410 0020112 0 ustar 00root root 0000000 0000000 name: golangci-lint
on:
push:
branches: ['main']
paths-ignore:
- "docs/**"
- "**.md"
pull_request:
paths-ignore:
- "docs/**"
- "**.md"
permissions: read-all
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: '1.23'
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@e60da84bfae8c7920a47be973d75e15710aa8bd7
with:
version: latest
gittuf-0.9.0/.github/workflows/release.yml 0000664 0000000 0000000 00000001423 14751501410 0020560 0 ustar 00root root 0000000 0000000 name: release
on:
push:
tags:
- 'v*'
permissions: read-all
jobs:
release:
permissions:
contents: write
id-token: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0 # fetch full history for previous tag information
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: '1.23'
cache: true
- uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e
- uses: goreleaser/goreleaser-action@9ed2f89a662bf1735a48bc8557fd212fa902bebf
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
gittuf-0.9.0/.github/workflows/run-demo.yml 0000664 0000000 0000000 00000001266 14751501410 0020673 0 ustar 00root root 0000000 0000000 name: Run demo
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions: read-all
jobs:
demo:
name: Run demo
runs-on: ubuntu-latest
steps:
- name: Checkout demo repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: gittuf/demo
- name: Install Python
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38
with:
python-version: '3.12'
- name: Install gittuf-installer
uses: gittuf/gittuf-installer@f31e69c7c18c7473cbce18ed69a559b945d3a738
- name: Run demo script
run: python run-demo.py --no-prompt
gittuf-0.9.0/.github/workflows/scorecard.yml 0000664 0000000 0000000 00000006132 14751501410 0021107 0 ustar 00root root 0000000 0000000 # This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: OpenSSF Scorecard
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '15 10 * * 3'
push:
branches: [ "main" ]
paths-ignore:
- "docs/**"
- "**.md"
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: read
steps:
- name: "Checkout code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@9e8d0789d4a0fa9ceb6b1738f7e269594bdd67f0 # v3.28.9
with:
sarif_file: results.sarif
gittuf-0.9.0/.github/workflows/ubuntu-2204.yml 0000664 0000000 0000000 00000001445 14751501410 0021053 0 ustar 00root root 0000000 0000000 name: git 2.34.1 on ubuntu-22.04
on:
push:
branches: ["main"]
paths-ignore:
- "docs/**"
- "**.md"
pull_request:
paths-ignore:
- "docs/**"
- "**.md"
permissions: read-all
jobs:
test:
strategy:
matrix:
go-version: ['1.23']
runs-on: ubuntu-22.04
steps:
- name: Downgrade Git
run: sudo apt-get update && sudo apt-get install -y --allow-downgrades git=1:2.34.1-1ubuntu1.12 git-man=1:2.34.1-1ubuntu1.12
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: ${{ matrix.go-version }}
cache: true
- name: Test
run: go test ./...
gittuf-0.9.0/.gitignore 0000664 0000000 0000000 00000000026 14751501410 0015006 0 ustar 00root root 0000000 0000000 dist/*
*.prof
vendor*
gittuf-0.9.0/.golangci.yml 0000664 0000000 0000000 00000000542 14751501410 0015405 0 ustar 00root root 0000000 0000000 linters:
enable:
- asciicheck
- errcheck
- errorlint
- gofmt
- goimports
- gosec
- gocritic
- importas
- prealloc
- revive
- misspell
- stylecheck
- tparallel
- unconvert
- unparam
- unused
- whitespace
output:
uniq-by-line: false
run:
issues-exit-code: 1
timeout: 10m
exclude-dirs:
- internal/third_party
gittuf-0.9.0/.goreleaser.yml 0000664 0000000 0000000 00000002420 14751501410 0015747 0 ustar 00root root 0000000 0000000 version: 2
project_name: gittuf
builds:
- id: gittuf
mod_timestamp: '{{ .CommitTimestamp }}'
env:
- CGO_ENABLED=0
flags:
- -trimpath
goos:
- linux
- darwin
- freebsd
- windows
goarch:
- amd64
- arm64
ldflags:
- "-s -w"
- "-extldflags=-zrelro"
- "-extldflags=-znow"
- "-buildid= -X github.com/gittuf/gittuf/internal/version.gitVersion={{ .Version }}"
- id: git-remote-gittuf
mod_timestamp: '{{ .CommitTimestamp }}'
main: ./internal/git-remote-gittuf
binary: git-remote-gittuf
env:
- CGO_ENABLED=0
flags:
- -trimpath
goos:
- linux
- darwin
- freebsd
- windows
goarch:
- amd64
- arm64
ldflags:
- "-s -w"
- "-extldflags=-zrelro"
- "-extldflags=-znow"
- "-buildid= -X github.com/gittuf/gittuf/internal/version.gitVersion={{ .Version }}"
archives:
- id: binary
format: binary
allow_different_binary_count: true
gomod:
proxy: true
changelog:
disable: true
signs:
- cmd: cosign
env:
- COSIGN_YES=true
certificate: '${artifact}.pem'
signature: '${artifact}.sig'
args:
- sign-blob
- '--output-certificate=${certificate}'
- '--output-signature=${signature}'
- '${artifact}'
artifacts: binary
output: true
release:
prerelease: allow
github:
owner: gittuf
name: gittuf
draft: true
gittuf-0.9.0/.test_ignore.txt 0000664 0000000 0000000 00000000537 14751501410 0016166 0 ustar 00root root 0000000 0000000 github.com/gittuf/gittuf/docs/cli
github.com/gittuf/gittuf/experimental/gittuf/options
github.com/gittuf/gittuf/internal/cmd
github.com/gittuf/gittuf/internal/dev
github.com/gittuf/gittuf/internal/git-remote-gittuf
github.com/gittuf/gittuf/internal/testartifacts
github.com/gittuf/gittuf/internal/third_party
github.com/gittuf/gittuf/internal/version
gittuf-0.9.0/CHANGELOG.md 0000664 0000000 0000000 00000020676 14751501410 0014644 0 ustar 00root root 0000000 0000000 # Changelog
This file tracks the changes introduced by gittuf versions.
## v0.9.0
### Added
- Added a terminal UI (TUI) to enable managing gittuf policy interactively
- Added global rules to set thresholds and prohibit force pushes to help set
security baselines in repositories with gittuf
- Added workflows to support synchronizing/propagating policy and RSL changes
across multiple repositories
- Added local persistent cache functionality to reduce the time taken for
verification of a repository after successful initial verification
- Added functionality to set a repository's canonical location in gittuf
metadata
- Added a control for RSL recording to skip checking for duplicates
- Added the gittuf Augmentation Process (GAP) for formalizing changes to gittuf
- Added color output for various gittuf logging flows
- Added functionality to discard currently staged changes to policy
- Added functionality to remove principals and keys no longer used by rules in
the metadata
### Updated
- Updated RSL printing to now use buffered output, improving performance
- Improved testing coverage of `gitinterface`
- Updated the design document for clarity and to reflect recent changes to
gittuf
- Updated various dependencies and CI workflows
## v0.8.1
- Fixed loading of legacy ECDSA key format
- Replaced `show` with `rev-parse` in some gitinterface APIs
- Added gittuf/demo run to CI
- Updated various dependencies and CI workflows
## v0.8.0
- Added an experimental gittuf Go API
- Added an experimental version (`v0.2`) of policy metadata, which adds support
for "principals" in gittuf
- Added an experimental flow to determine a feature ref's mergeability
- Optimized some preprocessing flows in the `policy` package
- Improved gittuf's design documentation
- Improved testing coverage of `gittuf` and `rsl`
- Fixed an internal issue with git-remote-gittuf and Go's builtin max
- Fixed issue with `git-remote-gittuf` with server responses on push
- Fixed issue with `git-remote-gittuf` when pushing to a remote repository
without gittuf enabled
- Fixed issue with `git-remote-gittuf` freezing upon failure to authenticate
with the remote repository when using HTTP
- Updated various dependencies and CI workflows
## v0.7.0
- Added support for metadata signing using Sigstore (currently `GITTUF_DEV`
only)
- Removed use of legacy custom securesystemslib key formats in gittuf's tests
- Removed vendored signerverifier library
- Unified SSH signature verification for Git commits and tags
- Refactored `policy` and `tuf` packages to support versioning policy metadata
- Updated various dependencies and CI workflows
## v0.6.2
- Added `git-remote-gittuf` to the release workflow's pre-built artifacts
- Updated CI workflow dependency
## v0.6.1
- Added a counter to RSL entries to support persistent caching
- Added experimental support for signature extensions to vendored DSSE library
- Refactored `GetLatestReferenceEntry` RSL API
- Fixed Makefile build on Windows
- Moved `update-root-threshold` and `update-policy-threshold` out of developer
mode
- Fixed issue with git-remote-gittuf using the wrong transport when fetching the
RSL
- Fixed issue with git-remote-gittuf when explicitly pushing the RSL
- Fixed issue with git-remote-gittuf and `curl` fetches and pushes on Windows
- Increased testing coverage of `policy` and `gitinterface`
- Improved documentation for getting started with gittuf, especially on Windows
platforms
- Added copyright notices to code files
- Updated various dependencies and CI workflows
## v0.6.0
- Added command to reorder policy rules
- Added support for older Git versions
- Added support for GitHub pull request approval attestations
- Added support for using enterprise GitHub instances
- Added caching for the RSL APIs `GetEntry` and `GetParentForEntry`
- Added parallelization for some unit tests
- Removed some deprecated flows such as `FindPublicKeysForPath` and refactored
verification APIs
- Added CodeQL scanning for the repository
- Updated various dependencies and CI workflows
## v0.5.2
- Fixed issue with git-remote-gittuf when force pushing
- Fixed issue with git-remote-gittuf not fetching RSL before adding new entries
- Updated various dependencies
## v0.5.1
- Updated release workflow to support GoReleaser v2
## v0.5.0
- Added support for `ssh-keygen` based signer and verifier
- Added support for overriding reference name when local and remote reference
names differ
- Added initial (alpha) implementation of git-remote-gittuf
- Added command to display RSL
- Added support for automatically skipping RSL entries that point to rebased
commits
- Updated policy verification pattern matching to use `fnmatch`
- Updated to use Git binary for various operations on underlying repository
- Updated various dependencies and CI workflows
- Updated docs to make command snippets easier to copy
- Removed extraneous fields from gittuf policy metadata
- Removed `verify-commit` and `verify-tag` workflows in favor of `verify-ref`
(BREAKING CHANGE)
- Governance: added Patrick Zielinski and Neil Naveen as gittuf maintainers
## v0.4.0
- Added support for `policy-staging` for sequential signing of metadata to meet
a threshold
- Added support for minimum required signatures for rules
- Added support for profiling with pprof
- Added `--from-entry` to `verify-ref`
- Added debug statements for `--verbose` flag
- Added caching of verifiers for each verified namespace (reference or file
path) to avoid repeated searches of the same policy state
- Added separated `add-rule` and `update-rule` workflows for policy
- Added dogfooding plan
- Added CI workflows for phase 1 of dogfooding
- Added OpenSSF Scorecard for the repository
- Updated policy to require each rule name to be unique across all rule files
- Updated file rules verification to use same policy as branch protection rules
verification
- Update reference authorization attestations to use merge tree for the change
being authorized
- Updated design document with definitions and a diagram
- Updated tag verification to check the tag's RSL entry points to either the tag
object or the tag's target object
- Updated roadmap to indicate status for each item
- Updated minimum Go version to 1.22
- Updated pointer to gittuf community details
- Updated various dependencies and CI workflows
## v0.3.0
- Added check to prevent duplicate RSL entries for the same ref and target
- Added a formal developer mode for new early-stage gittuf features
- Added early support for attestations with one type for approving reference
changes (developer mode only)
- Added support for gittuf-specific Git hooks with a pre-push hook to fetch /
create / push RSL entries
- Updated `verify-ref` to perform full verification by default (BREAKING CHANGE)
- Updated identification of trusted keys in policy to support varying threshold
values between delegations
- Added verification tests for delegated policies
- Added root key management commands to the CLI
- Added command to list rules in gittuf policy
- Added support for standard encoding of private and public keys
- Added support for verifying SSH Git commit and tag signatures
- Added check for cycles when walking policy graph during verification
- Added autogenerated CLI docs
- Removed file rule verification when no file rules exist in the policy for
efficiency
- Added command to sign existing policy file with no other changes
- Added get started guide and gittuf logo to docs
- Removed CLI usage message for gittuf errors
- Updated various dependencies
## v0.2.0
- Added support to RSL to find unskipped entries
- Added `Get*` functions to gitinterface to compartmentalize choice of Git
library
- Added support in RSL and policy functions for RSL annotation entries
- Added recovery mode for policy verification workflow
- Added `go fmt` as Makefile target
- Updated length of refspecs slice to account for doubled entries
- Added support for merge commits in gitinterface
- Updated CLI to check if Git signing is viable to abort early
- Fixed bug in CLI that required an unnecessary signing key argument
- Fixed `clone`'s ability to handle trailing slashes
- Improved testing for in policy verification for delegations
- Added plumbing for better logging
- Updated various dependencies
- Updated installation instructions to include Sigstore verification of binaries
## v0.1.0
- Implemented reference state log (RSL)
- Added support for Git reference policies using RSL entry signatures
- Added support for file policies using commit signatures
- Added support for basic gittuf sync operations
gittuf-0.9.0/CONTRIBUTING.md 0000664 0000000 0000000 00000003611 14751501410 0015252 0 ustar 00root root 0000000 0000000 # Contributing Guide
Contributions to gittuf can be of several types:
* changes to the [design document](/docs/design-document.md) or
[gittuf Augmentation Proposals (GAPs)](/docs/gaps/README.md) stored in the
`docs/` folder
* code changes for bug fixes, new features, documentation, and other
enhancements to the implementation
* new issues or feature requests
[Join our community](https://github.com/gittuf/community/?tab=readme-ov-file#join-us)
to get started!
## Contributor Workflow
When submitting changes to the gittuf docs or implementation, contributors must
open a GitHub pull request to the repository. If a proposed change is a
significant deviation from gittuf's [design document](/docs/design-document.md),
a [GAP](/docs/gaps/README.md) may be necessary. When in doubt, contributors are
advised to file an issue in the repository for the
[maintainers](MAINTAINERS.txt) to determine the best way forward.
gittuf uses the NYU Secure Systems Lab [development
workflow](https://github.com/secure-systems-lab/lab-guidelines/blob/master/dev-workflow.md).
Pull requests must include tests for the changes in behavior they introduce.
They are reviewed by one or more [maintainers](MAINTAINERS.txt) and undergo
automated testing such as (but not limited to):
* Unit and build testing
* Static analysis using linters
* Developer Certificate of Origin (DCO) check
In future, as gittuf matures, this repository will also be secured using gittuf.
At that point, the contributor workflow may evolve to record gittuf specific
information.
## Other Guidelines
Contributors to gittuf must abide by the project's
[code of conduct](https://github.com/gittuf/community/blob/main/CODE-OF-CONDUCT.md).
Any questions regarding the gittuf community's governance and code of conduct
may be directed to the project's
[Technical Steering Committee](https://github.com/gittuf/community/blob/main/TECHNICAL-STEERING-COMMITTEE.md).
gittuf-0.9.0/LICENSE 0000664 0000000 0000000 00000026140 14751501410 0014030 0 ustar 00root root 0000000 0000000 Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright gittuf a Series of LF Projects, LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
gittuf-0.9.0/MAINTAINERS.txt 0000664 0000000 0000000 00000001330 14751501410 0015330 0 ustar 00root root 0000000 0000000 gittuf is built and maintained by developers from New York University (NYU),
Chainguard, and New Jersey Institute of Technology (NJIT).
Aditya Sirish A Yelgundhalli
Email: aditya.sirish@nyu.edu
GitHub username: @adityasaky
Affiliation: NYU
Justin Cappos
Email: jcappos@nyu.edu
GitHub username: @JustinCappos
Affiliation: NYU
Billy Lynch
Email: billy@chainguard.dev
GitHub username: @wlynch
Affiliation: Chainguard
Reza Curtmola
Email: reza.curtmola@njit.edu
GitHub username: @reza-curtmola
Affiliation: NJIT
Patrick Zielinski
Email: patrick.z@nyu.edu
GitHub username: @patzielinski
Affiliation: NYU
Neil Naveen
Email: naveen.neil@icloud.com
GitHub username: @neilnaveen
Affiliation: NYU gittuf-0.9.0/Makefile 0000664 0000000 0000000 00000002322 14751501410 0014457 0 ustar 00root root 0000000 0000000 # SPDX-License-Identifier: Apache-2.0
GIT_VERSION ?= $(shell git describe --tags --always --dirty)
LDFLAGS=-buildid= -X github.com/gittuf/gittuf/internal/version.gitVersion=$(GIT_VERSION)
.PHONY : build test install fmt
default : install
build : test
ifeq ($(OS),Windows_NT)
set CGO_ENABLED=0
go build -trimpath -ldflags "$(LDFLAGS)" -o dist/gittuf .
go build -trimpath -ldflags "$(LDFLAGS)" -o dist/git-remote-gittuf ./internal/git-remote-gittuf
set CGO_ENABLED=
else
CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o dist/gittuf .
CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o dist/git-remote-gittuf ./internal/git-remote-gittuf
endif
install : test just-install
just-install :
ifeq ($(OS),Windows_NT)
set CGO_ENABLED=0
go install -trimpath -ldflags "$(LDFLAGS)" github.com/gittuf/gittuf
go install -trimpath -ldflags "$(LDFLAGS)" github.com/gittuf/gittuf/internal/git-remote-gittuf
set CGO_ENABLED=
else
CGO_ENABLED=0 go install -trimpath -ldflags "$(LDFLAGS)" github.com/gittuf/gittuf
CGO_ENABLED=0 go install -trimpath -ldflags "$(LDFLAGS)" github.com/gittuf/gittuf/internal/git-remote-gittuf
endif
test :
go test -timeout 20m -v ./...
fmt :
go fmt ./...
generate :
go generate ./...
gittuf-0.9.0/README.md 0000664 0000000 0000000 00000004275 14751501410 0014307 0 ustar 00root root 0000000 0000000
[](https://www.bestpractices.dev/projects/7789)

[](https://coveralls.io/github/gittuf/gittuf)
gittuf is a security layer for Git repositories. With gittuf, any developer who
can pull from a Git repository can independently verify that the repository's
security policies were followed. gittuf's policy, inspired by [The Update
Framework (TUF)], handles key management for all trusted developers in a
repository, allows for setting permissions for repository branches, tags, files,
etc., protects against [other attacks] Git is vulnerable to, and more — all
while being backwards compatible with forges such as GitHub and GitLab.
gittuf is a sandbox project at the [Open Source Security Foundation (OpenSSF)]
as part of the [Supply Chain Integrity Working Group].
## Current Status
gittuf is currently in alpha. gittuf's metadata may have breaking changes,
meaning a repository's gittuf policy may have to be reinitialized from time to
time. As such, gittuf is currently not intended to be the primary mechanism for
enforcing a repository's security.
That said, we're actively seeking feedback from users. Take a look at the [get
started guide] to learn how to install and try gittuf out! Additionally,
contributions are welcome, please refer to the [contributing guide], our
[roadmap], and the issue tracker for ways to get involved.
## Installation & Get Started
See the [get started guide].
[The Update Framework (TUF)]: https://theupdateframework.io/
[other attacks]: https://ssl.engineering.nyu.edu/papers/torres_toto_usenixsec-2016.pdf
[contributing guide]: /CONTRIBUTING.md
[roadmap]: /docs/roadmap.md
[Open Source Security Foundation (OpenSSF)]: https://openssf.org/
[Supply Chain Integrity Working Group]: https://github.com/ossf/wg-supply-chain-integrity
[get started guide]: /docs/get-started.md
gittuf-0.9.0/SECURITY.md 0000664 0000000 0000000 00000001622 14751501410 0014612 0 ustar 00root root 0000000 0000000 # Reporting Security Issues
Please report security issues **confidentially** using
[GitHub's form](https://github.com/gittuf/gittuf/security/advisories/new).
Alternatively, you can send an encrypted email to `jcappos@nyu.edu` using the
following PGP key:
> E9C0 59EC 0D32 64FA B35F 94AD 465B F9F6 F8EB 475A
**Note:** Please do not report such issues publicly on the issue tracker. The
*issue tracker is intended for bug reports and feature requests.
## Responding to Reports
A gittuf maintainer will respond to the report as soon as possible. After the
report is triaged and the vulnerability is confirmed, a fix will be prepared
under embargo. Once the fix is accepted, a new release will be prepared along
with a report detailing the vulnerability. This report will identify the
reporter unless they request to be kept anonymous. Finally, a CVE may be
requested if appropriate for the vulnerability report.
gittuf-0.9.0/debug/ 0000775 0000000 0000000 00000000000 14751501410 0014106 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/debug/Dockerfile.Git_2_34_1 0000664 0000000 0000000 00000001333 14751501410 0017571 0 ustar 00root root 0000000 0000000 # This Dockerfile can be used to build a container image with Git 2.34.1 but the
# latest Go and delve release. This is useful when debugging gittuf errors with
# Git 2.34.1, a version of Git we support due to it being the latest on Ubuntu
# 22.04 LTS. After building the container image, run it with the local
# repository as a mounted volume. That way, changes can be made outside the
# container but iteratively debugged within the container.
FROM ubuntu:22.04
RUN apt-get update && apt-get install git software-properties-common -y
RUN add-apt-repository ppa:longsleep/golang-backports -y
RUN apt-get update && apt-get install golang -y
RUN go install github.com/go-delve/delve/cmd/dlv@latest
ENV PATH=/root/go/bin:$PATH
gittuf-0.9.0/debug/README.md 0000664 0000000 0000000 00000000752 14751501410 0015371 0 ustar 00root root 0000000 0000000 # Debug Helpers
This directory contains tools or artifacts used by the gittuf developers during
debugging.
## Debugging gittuf with Git 2.34.1
Build and run the container from the root of the gittuf repository.
```bash
docker build -t debug-gittuf-2-34-1 -f debug/Dockerfile.Git_2_34_1 .
docker run -it --rm -v $PWD:/gittuf -w /gittuf debug-gittuf-2-34-1
```
As the gittuf repository is mounted as a volume, you can make changes on the
host and iteratively debug within the container.
gittuf-0.9.0/docs/ 0000775 0000000 0000000 00000000000 14751501410 0013750 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/cli/ 0000775 0000000 0000000 00000000000 14751501410 0014517 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/cli/gittuf.md 0000664 0000000 0000000 00000002447 14751501410 0016352 0 ustar 00root root 0000000 0000000 ## gittuf
A security layer for Git repositories, powered by TUF
### Options
```
-h, --help help for gittuf
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf add-hooks](gittuf_add-hooks.md) - Add git hooks that automatically create and sync RSL
* [gittuf attest](gittuf_attest.md) - Tools for attesting to code contributions
* [gittuf clone](gittuf_clone.md) - Clone repository and its gittuf references
* [gittuf dev](gittuf_dev.md) - Developer mode commands
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
* [gittuf rsl](gittuf_rsl.md) - Tools to manage the repository's reference state log
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
* [gittuf verify-mergeable](gittuf_verify-mergeable.md) - Tools for verifying mergeability using gittuf policies
* [gittuf verify-ref](gittuf_verify-ref.md) - Tools for verifying gittuf policies
* [gittuf version](gittuf_version.md) - Version of gittuf
gittuf-0.9.0/docs/cli/gittuf_add-hooks.md 0000664 0000000 0000000 00000001334 14751501410 0020275 0 ustar 00root root 0000000 0000000 ## gittuf add-hooks
Add git hooks that automatically create and sync RSL
```
gittuf add-hooks [flags]
```
### Options
```
-f, --force overwrite hooks, if they already exist
-h, --help help for add-hooks
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
gittuf-0.9.0/docs/cli/gittuf_attest.md 0000664 0000000 0000000 00000001322 14751501410 0017725 0 ustar 00root root 0000000 0000000 ## gittuf attest
Tools for attesting to code contributions
### Options
```
-h, --help help for attest
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
* [gittuf attest authorize](gittuf_attest_authorize.md) - Add or revoke reference authorization
gittuf-0.9.0/docs/cli/gittuf_attest_authorize.md 0000664 0000000 0000000 00000001613 14751501410 0022022 0 ustar 00root root 0000000 0000000 ## gittuf attest authorize
Add or revoke reference authorization
```
gittuf attest authorize [flags]
```
### Options
```
-f, --from-ref string ref to authorize merging changes from
-h, --help help for authorize
-r, --revoke revoke existing authorization
-k, --signing-key string signing key to use for creating or revoking an authorization
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf attest](gittuf_attest.md) - Tools for attesting to code contributions
gittuf-0.9.0/docs/cli/gittuf_clone.md 0000664 0000000 0000000 00000001677 14751501410 0017536 0 ustar 00root root 0000000 0000000 ## gittuf clone
Clone repository and its gittuf references
```
gittuf clone [flags]
```
### Options
```
--bare make a bare Git repository
-b, --branch string specify branch to check out
-h, --help help for clone
--root-key public-keys set of initial root of trust keys for the repository (supported values: paths to SSH keys, GPG key fingerprints, Sigstore/Fulcio identities)
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
gittuf-0.9.0/docs/cli/gittuf_dev.md 0000664 0000000 0000000 00000003125 14751501410 0017202 0 ustar 00root root 0000000 0000000 ## gittuf dev
Developer mode commands
### Synopsis
These commands are meant to be used to aid gittuf development, and are not expected to be used during standard workflows. If used, they can undermine repository security. To proceed, set GITTUF_DEV=1.
### Options
```
-h, --help help for dev
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
* [gittuf dev add-github-approval](gittuf_dev_add-github-approval.md) - Record GitHub pull request approval as an attestation (developer mode only, set GITTUF_DEV=1)
* [gittuf dev attest-github](gittuf_dev_attest-github.md) - Record GitHub pull request information as an attestation (developer mode only, set GITTUF_DEV=1)
* [gittuf dev dismiss-github-approval](gittuf_dev_dismiss-github-approval.md) - Dismiss GitHub pull request approval as an attestation (developer mode only, set GITTUF_DEV=1)
* [gittuf dev populate-cache](gittuf_dev_populate-cache.md) - Populate persistent cache (developer mode only, set GITTUF_DEV=1)
* [gittuf dev rsl-record](gittuf_dev_rsl-record.md) - Record explicit state of a Git reference in the RSL, signed with specified key (developer mode only, set GITTUF_DEV=1)
gittuf-0.9.0/docs/cli/gittuf_dev_add-github-approval.md 0000664 0000000 0000000 00000002362 14751501410 0023116 0 ustar 00root root 0000000 0000000 ## gittuf dev add-github-approval
Record GitHub pull request approval as an attestation (developer mode only, set GITTUF_DEV=1)
```
gittuf dev add-github-approval [flags]
```
### Options
```
--approver string identity of the reviewer who approved the change
--base-URL string location of GitHub instance (default "https://github.com")
-h, --help help for add-github-approval
--pull-request-number int pull request number (default -1)
--repository string path to base GitHub repository the pull request is opened against, of form {owner}/{repo}
--review-ID int pull request review ID (default -1)
-k, --signing-key string signing key to use for signing attestation
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf dev](gittuf_dev.md) - Developer mode commands
gittuf-0.9.0/docs/cli/gittuf_dev_attest-github.md 0000664 0000000 0000000 00000002406 14751501410 0022047 0 ustar 00root root 0000000 0000000 ## gittuf dev attest-github
Record GitHub pull request information as an attestation (developer mode only, set GITTUF_DEV=1)
```
gittuf dev attest-github [flags]
```
### Options
```
--base-URL string location of GitHub instance (default "https://github.com")
--base-branch string base branch for pull request, used with --commit
--commit string commit to record pull request attestation for
-h, --help help for attest-github
--pull-request-number int pull request number to record in attestation (default -1)
--repository string path to base GitHub repository the pull request is opened against, of form {owner}/{repo}
-k, --signing-key string signing key to use for signing attestation
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf dev](gittuf_dev.md) - Developer mode commands
gittuf-0.9.0/docs/cli/gittuf_dev_dismiss-github-approval.md 0000664 0000000 0000000 00000002103 14751501410 0024032 0 ustar 00root root 0000000 0000000 ## gittuf dev dismiss-github-approval
Dismiss GitHub pull request approval as an attestation (developer mode only, set GITTUF_DEV=1)
```
gittuf dev dismiss-github-approval [flags]
```
### Options
```
--base-URL string location of GitHub instance (default "https://github.com")
--dismiss-approver string identity of the reviewer whose review was dismissed
-h, --help help for dismiss-github-approval
--review-ID int pull request review ID (default -1)
-k, --signing-key string signing key to use for signing attestation
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf dev](gittuf_dev.md) - Developer mode commands
gittuf-0.9.0/docs/cli/gittuf_dev_populate-cache.md 0000664 0000000 0000000 00000001262 14751501410 0022154 0 ustar 00root root 0000000 0000000 ## gittuf dev populate-cache
Populate persistent cache (developer mode only, set GITTUF_DEV=1)
```
gittuf dev populate-cache [flags]
```
### Options
```
-h, --help help for populate-cache
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf dev](gittuf_dev.md) - Developer mode commands
gittuf-0.9.0/docs/cli/gittuf_dev_rsl-record.md 0000664 0000000 0000000 00000001670 14751501410 0021341 0 ustar 00root root 0000000 0000000 ## gittuf dev rsl-record
Record explicit state of a Git reference in the RSL, signed with specified key (developer mode only, set GITTUF_DEV=1)
```
gittuf dev rsl-record [flags]
```
### Options
```
--dst-ref string name of destination reference, if it differs from source reference
-h, --help help for rsl-record
-k, --signing-key string path to PEM encoded SSH or GPG signing key
-t, --target string target ID
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf dev](gittuf_dev.md) - Developer mode commands
gittuf-0.9.0/docs/cli/gittuf_policy.md 0000664 0000000 0000000 00000004626 14751501410 0017732 0 ustar 00root root 0000000 0000000 ## gittuf policy
Tools to manage gittuf policies
### Options
```
-h, --help help for policy
-k, --signing-key string signing key to use to sign policy file
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
* [gittuf policy add-key](gittuf_policy_add-key.md) - Add a trusted key to a policy file
* [gittuf policy add-person](gittuf_policy_add-person.md) - Add a trusted person to a policy file (requires developer mode and v0.2 policy metadata to be enabled, set GITTUF_DEV=1 and GITTUF_ALLOW_V02_POLICY=1)
* [gittuf policy add-rule](gittuf_policy_add-rule.md) - Add a new rule to a policy file
* [gittuf policy apply](gittuf_policy_apply.md) - Validate and apply changes from policy-staging to policy
* [gittuf policy discard](gittuf_policy_discard.md) - Discard the currently staged changes to policy
* [gittuf policy init](gittuf_policy_init.md) - Initialize policy file
* [gittuf policy list-principals](gittuf_policy_list-principals.md) - List principals for the current policy in the specified rule file
* [gittuf policy list-rules](gittuf_policy_list-rules.md) - List rules for the current state
* [gittuf policy remote](gittuf_policy_remote.md) - Tools for managing remote policies
* [gittuf policy remove-key](gittuf_policy_remove-key.md) - Remove a key from a policy file
* [gittuf policy remove-person](gittuf_policy_remove-person.md) - Remove a person from a policy file (requires developer mode and v0.2 policy metadata to be enabled, set GITTUF_DEV=1 and GITTUF_ALLOW_V02_POLICY=1)
* [gittuf policy remove-rule](gittuf_policy_remove-rule.md) - Remove rule from a policy file
* [gittuf policy reorder-rules](gittuf_policy_reorder-rules.md) - Reorder rules in the specified policy file
* [gittuf policy sign](gittuf_policy_sign.md) - Sign policy file
* [gittuf policy tui](gittuf_policy_tui.md) - Start the TUI for managing policies
* [gittuf policy update-rule](gittuf_policy_update-rule.md) - Update an existing rule in a policy file
gittuf-0.9.0/docs/cli/gittuf_policy_add-key.md 0000664 0000000 0000000 00000002255 14751501410 0021324 0 ustar 00root root 0000000 0000000 ## gittuf policy add-key
Add a trusted key to a policy file
### Synopsis
This command allows users to add trusted keys to the specified policy file. By default, the main policy file is selected. Note that the keys can be specified from disk, from the GPG keyring using the "gpg:" format, or as a Sigstore identity as "fulcio:::".
```
gittuf policy add-key [flags]
```
### Options
```
-h, --help help for add-key
--policy-name string name of policy file to add key to (default "targets")
--public-key stringArray authorized public key
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_add-person.md 0000664 0000000 0000000 00000003206 14751501410 0022037 0 ustar 00root root 0000000 0000000 ## gittuf policy add-person
Add a trusted person to a policy file (requires developer mode and v0.2 policy metadata to be enabled, set GITTUF_DEV=1 and GITTUF_ALLOW_V02_POLICY=1)
### Synopsis
This command allows users to add a trusted person to the specified policy file. By default, the main policy file is selected. Note that the person's keys can be specified from disk, from the GPG keyring using the "gpg:" format, or as a Sigstore identity as "fulcio:::".
```
gittuf policy add-person [flags]
```
### Options
```
--associated-identity stringArray identities on code review platforms in the form 'providerID::identity' (e.g., 'https://github.com::')
--custom stringArray additional custom metadata in the form KEY=VALUE
-h, --help help for add-person
--person-ID string person ID
--policy-name string name of policy file to add key to (default "targets")
--public-key stringArray authorized public key for person
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_add-rule.md 0000664 0000000 0000000 00000002652 14751501410 0021504 0 ustar 00root root 0000000 0000000 ## gittuf policy add-rule
Add a new rule to a policy file
### Synopsis
This command allows users to add a new rule to the specified policy file. By default, the main policy file is selected. Note that authorized keys can be specified from disk, from the GPG keyring using the "gpg:" format, or as a Sigstore identity as "fulcio:::".
```
gittuf policy add-rule [flags]
```
### Options
```
--authorize stringArray authorize the principal IDs for the rule
-h, --help help for add-rule
--policy-name string name of policy file to add rule to (default "targets")
--rule-name string name of rule
--rule-pattern stringArray patterns used to identify namespaces rule applies to
--threshold int threshold of required valid signatures (default 1)
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_apply.md 0000664 0000000 0000000 00000001356 14751501410 0021134 0 ustar 00root root 0000000 0000000 ## gittuf policy apply
Validate and apply changes from policy-staging to policy
```
gittuf policy apply [flags]
```
### Options
```
-h, --help help for apply
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_discard.md 0000664 0000000 0000000 00000001352 14751501410 0021414 0 ustar 00root root 0000000 0000000 ## gittuf policy discard
Discard the currently staged changes to policy
```
gittuf policy discard [flags]
```
### Options
```
-h, --help help for discard
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_init.md 0000664 0000000 0000000 00000001446 14751501410 0020752 0 ustar 00root root 0000000 0000000 ## gittuf policy init
Initialize policy file
```
gittuf policy init [flags]
```
### Options
```
-h, --help help for init
--policy-name string name of policy file to create (default "targets")
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_list-principals.md 0000664 0000000 0000000 00000001732 14751501410 0023122 0 ustar 00root root 0000000 0000000 ## gittuf policy list-principals
List principals for the current policy in the specified rule file
```
gittuf policy list-principals [flags]
```
### Options
```
-h, --help help for list-principals
--policy-name string specify rule file to list principals for (default "targets")
--policy-ref string specify which policy ref should be inspected (default "policy")
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_list-rules.md 0000664 0000000 0000000 00000001516 14751501410 0022110 0 ustar 00root root 0000000 0000000 ## gittuf policy list-rules
List rules for the current state
```
gittuf policy list-rules [flags]
```
### Options
```
-h, --help help for list-rules
--target-ref string specify which policy ref should be inspected (default "policy")
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_remote.md 0000664 0000000 0000000 00000001575 14751501410 0021305 0 ustar 00root root 0000000 0000000 ## gittuf policy remote
Tools for managing remote policies
### Options
```
-h, --help help for remote
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
* [gittuf policy remote pull](gittuf_policy_remote_pull.md) - Pull policy from the specified remote
* [gittuf policy remote push](gittuf_policy_remote_push.md) - Push policy to the specified remote
gittuf-0.9.0/docs/cli/gittuf_policy_remote_pull.md 0000664 0000000 0000000 00000001400 14751501410 0022324 0 ustar 00root root 0000000 0000000 ## gittuf policy remote pull
Pull policy from the specified remote
```
gittuf policy remote pull [flags]
```
### Options
```
-h, --help help for pull
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy remote](gittuf_policy_remote.md) - Tools for managing remote policies
gittuf-0.9.0/docs/cli/gittuf_policy_remote_push.md 0000664 0000000 0000000 00000001376 14751501410 0022343 0 ustar 00root root 0000000 0000000 ## gittuf policy remote push
Push policy to the specified remote
```
gittuf policy remote push [flags]
```
### Options
```
-h, --help help for push
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy remote](gittuf_policy_remote.md) - Tools for managing remote policies
gittuf-0.9.0/docs/cli/gittuf_policy_remove-key.md 0000664 0000000 0000000 00000002064 14751501410 0022067 0 ustar 00root root 0000000 0000000 ## gittuf policy remove-key
Remove a key from a policy file
### Synopsis
This command allows users to remove keys from the specified policy file. The public key ID is required. By default, the main policy file is selected.
```
gittuf policy remove-key [flags]
```
### Options
```
-h, --help help for remove-key
--policy-name string name of policy file to remove key from (default "targets")
--public-key string public key ID to remove from the policy
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_remove-person.md 0000664 0000000 0000000 00000002230 14751501410 0022600 0 ustar 00root root 0000000 0000000 ## gittuf policy remove-person
Remove a person from a policy file (requires developer mode and v0.2 policy metadata to be enabled, set GITTUF_DEV=1 and GITTUF_ALLOW_V02_POLICY=1)
### Synopsis
This command allows users to remove a person from the specified policy file. The person's ID is required. By default, the main policy file is selected.
```
gittuf policy remove-person [flags]
```
### Options
```
-h, --help help for remove-person
--person-ID string person ID
--policy-name string name of policy file to remove person from (default "targets")
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_remove-rule.md 0000664 0000000 0000000 00000001567 14751501410 0022255 0 ustar 00root root 0000000 0000000 ## gittuf policy remove-rule
Remove rule from a policy file
```
gittuf policy remove-rule [flags]
```
### Options
```
-h, --help help for remove-rule
--policy-name string name of policy file to remove rule from (default "targets")
--rule-name string name of rule
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_reorder-rules.md 0000664 0000000 0000000 00000002266 14751501410 0022602 0 ustar 00root root 0000000 0000000 ## gittuf policy reorder-rules
Reorder rules in the specified policy file
### Synopsis
This command allows users to reorder rules in the specified policy file. By default, the main policy file is selected. The rule names need to be passed as arguments, in the new order they must appear in, starting from the first to the last rule. Rule names may contain spaces, so they should be enclosed in quotes if necessary.
```
gittuf policy reorder-rules [flags]
```
### Options
```
-h, --help help for reorder-rules
--policy-name string name of policy file to reorder rules in (default "targets")
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_sign.md 0000664 0000000 0000000 00000001574 14751501410 0020751 0 ustar 00root root 0000000 0000000 ## gittuf policy sign
Sign policy file
### Synopsis
This command allows users to add their signature to the specified policy file.
```
gittuf policy sign [flags]
```
### Options
```
-h, --help help for sign
--policy-name string name of policy file to sign (default "targets")
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_tui.md 0000664 0000000 0000000 00000002354 14751501410 0020607 0 ustar 00root root 0000000 0000000 ## gittuf policy tui
Start the TUI for managing policies
### Synopsis
This command allows users to start a terminal-based interface to manage policies. The signing key specified will be used to sign all operations while in the TUI. Changes to the policy files in the TUI are staged immediately without further confirmation and users are required to run `gittuf policy apply` to commit the changes
```
gittuf policy tui [flags]
```
### Options
```
-h, --help help for tui
--policy-name string name of policy file to make changes to (default "targets")
--target-ref string specify which policy ref should be inspected (default "policy")
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_policy_update-rule.md 0000664 0000000 0000000 00000002705 14751501410 0022235 0 ustar 00root root 0000000 0000000 ## gittuf policy update-rule
Update an existing rule in a policy file
### Synopsis
This command allows users to update an existing rule to the specified policy file. By default, the main policy file is selected. Note that authorized keys can be specified from disk, from the GPG keyring using the "gpg:" format, or as a Sigstore identity as "fulcio:::".
```
gittuf policy update-rule [flags]
```
### Options
```
--authorize stringArray authorize the principal IDs for the rule
-h, --help help for update-rule
--policy-name string name of policy file to add rule to (default "targets")
--rule-name string name of rule
--rule-pattern stringArray patterns used to identify namespaces rule applies to
--threshold int threshold of required valid signatures (default 1)
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign policy file
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf policy](gittuf_policy.md) - Tools to manage gittuf policies
gittuf-0.9.0/docs/cli/gittuf_rsl.md 0000664 0000000 0000000 00000002432 14751501410 0017224 0 ustar 00root root 0000000 0000000 ## gittuf rsl
Tools to manage the repository's reference state log
### Options
```
-h, --help help for rsl
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
* [gittuf rsl annotate](gittuf_rsl_annotate.md) - Annotate prior RSL entries
* [gittuf rsl log](gittuf_rsl_log.md) - Display the repository's Reference State Log
* [gittuf rsl propagate](gittuf_rsl_propagate.md) - Propagate contents of remote repositories into local repository (developer mode only, set GITTUF_DEV=1)
* [gittuf rsl record](gittuf_rsl_record.md) - Record latest state of a Git reference in the RSL
* [gittuf rsl remote](gittuf_rsl_remote.md) - Tools for managing remote RSLs
* [gittuf rsl skip-rewritten](gittuf_rsl_skip-rewritten.md) - Creates an RSL annotation to skip RSL reference entries that point to commits that do not exist in the specified ref
gittuf-0.9.0/docs/cli/gittuf_rsl_annotate.md 0000664 0000000 0000000 00000001415 14751501410 0021115 0 ustar 00root root 0000000 0000000 ## gittuf rsl annotate
Annotate prior RSL entries
```
gittuf rsl annotate [flags]
```
### Options
```
-h, --help help for annotate
-m, --message string annotation message
-s, --skip mark annotated entries as to be skipped
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl](gittuf_rsl.md) - Tools to manage the repository's reference state log
gittuf-0.9.0/docs/cli/gittuf_rsl_log.md 0000664 0000000 0000000 00000001231 14751501410 0020061 0 ustar 00root root 0000000 0000000 ## gittuf rsl log
Display the repository's Reference State Log
```
gittuf rsl log [flags]
```
### Options
```
-h, --help help for log
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl](gittuf_rsl.md) - Tools to manage the repository's reference state log
gittuf-0.9.0/docs/cli/gittuf_rsl_propagate.md 0000664 0000000 0000000 00000001346 14751501410 0021271 0 ustar 00root root 0000000 0000000 ## gittuf rsl propagate
Propagate contents of remote repositories into local repository (developer mode only, set GITTUF_DEV=1)
```
gittuf rsl propagate [flags]
```
### Options
```
-h, --help help for propagate
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl](gittuf_rsl.md) - Tools to manage the repository's reference state log
gittuf-0.9.0/docs/cli/gittuf_rsl_record.md 0000664 0000000 0000000 00000001661 14751501410 0020565 0 ustar 00root root 0000000 0000000 ## gittuf rsl record
Record latest state of a Git reference in the RSL
```
gittuf rsl record [flags]
```
### Options
```
--dst-ref string name of destination reference, if it differs from source reference
-h, --help help for record
--skip-duplicate-check skip check to see if latest entry for reference has same target
--skip-propagation skip propagation workflow
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl](gittuf_rsl.md) - Tools to manage the repository's reference state log
gittuf-0.9.0/docs/cli/gittuf_rsl_remote.md 0000664 0000000 0000000 00000001616 14751501410 0020602 0 ustar 00root root 0000000 0000000 ## gittuf rsl remote
Tools for managing remote RSLs
### Options
```
-h, --help help for remote
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl](gittuf_rsl.md) - Tools to manage the repository's reference state log
* [gittuf rsl remote pull](gittuf_rsl_remote_pull.md) - Pull RSL from the specified remote
* [gittuf rsl remote push](gittuf_rsl_remote_push.md) - Push RSL to the specified remote
* [gittuf rsl remote reconcile](gittuf_rsl_remote_reconcile.md) - Reconcile local RSL with remote RSL
gittuf-0.9.0/docs/cli/gittuf_rsl_remote_pull.md 0000664 0000000 0000000 00000001241 14751501410 0021630 0 ustar 00root root 0000000 0000000 ## gittuf rsl remote pull
Pull RSL from the specified remote
```
gittuf rsl remote pull [flags]
```
### Options
```
-h, --help help for pull
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl remote](gittuf_rsl_remote.md) - Tools for managing remote RSLs
gittuf-0.9.0/docs/cli/gittuf_rsl_remote_push.md 0000664 0000000 0000000 00000001237 14751501410 0021640 0 ustar 00root root 0000000 0000000 ## gittuf rsl remote push
Push RSL to the specified remote
```
gittuf rsl remote push [flags]
```
### Options
```
-h, --help help for push
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl remote](gittuf_rsl_remote.md) - Tools for managing remote RSLs
gittuf-0.9.0/docs/cli/gittuf_rsl_remote_reconcile.md 0000664 0000000 0000000 00000002305 14751501410 0022621 0 ustar 00root root 0000000 0000000 ## gittuf rsl remote reconcile
Reconcile local RSL with remote RSL
### Synopsis
This command checks the local RSL against the specified remote and reconciles the local RSL if needed. If the local RSL doesn't exist or is strictly behind the remote RSL, then the local RSL is updated to match the remote RSL. If the local RSL is ahead of the remote RSL, nothing is updated. Finally, if the local and remote RSLs have diverged, then the local only RSL entries are reapplied over the latest entries in the remote if the local only RSL entries and remote only entries are for different Git references.
```
gittuf rsl remote reconcile [flags]
```
### Options
```
-h, --help help for reconcile
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl remote](gittuf_rsl_remote.md) - Tools for managing remote RSLs
gittuf-0.9.0/docs/cli/gittuf_rsl_skip-rewritten.md 0000664 0000000 0000000 00000001402 14751501410 0022267 0 ustar 00root root 0000000 0000000 ## gittuf rsl skip-rewritten
Creates an RSL annotation to skip RSL reference entries that point to commits that do not exist in the specified ref
```
gittuf rsl skip-rewritten [flags]
```
### Options
```
-h, --help help for skip-rewritten
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf rsl](gittuf_rsl.md) - Tools to manage the repository's reference state log
gittuf-0.9.0/docs/cli/gittuf_trust.md 0000664 0000000 0000000 00000005744 14751501410 0017616 0 ustar 00root root 0000000 0000000 ## gittuf trust
Tools for gittuf's root of trust
### Options
```
-h, --help help for trust
-k, --signing-key string signing key to use to sign root of trust
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
* [gittuf trust add-github-app](gittuf_trust_add-github-app.md) - Add GitHub app to gittuf root of trust
* [gittuf trust add-global-rule](gittuf_trust_add-global-rule.md) - Add a new global rule to root of trust (developer mode only, set GITTUF_DEV=1)
* [gittuf trust add-policy-key](gittuf_trust_add-policy-key.md) - Add Policy key to gittuf root of trust
* [gittuf trust add-propagation-directive](gittuf_trust_add-propagation-directive.md) - Add propagation directive into gittuf root of trust (developer mode only, set GITTUF_DEV=1)
* [gittuf trust add-root-key](gittuf_trust_add-root-key.md) - Add Root key to gittuf root of trust
* [gittuf trust apply](gittuf_trust_apply.md) - Validate and apply changes from policy-staging to policy
* [gittuf trust disable-github-app-approvals](gittuf_trust_disable-github-app-approvals.md) - Mark GitHub app approvals as untrusted henceforth
* [gittuf trust enable-github-app-approvals](gittuf_trust_enable-github-app-approvals.md) - Mark GitHub app approvals as trusted henceforth
* [gittuf trust init](gittuf_trust_init.md) - Initialize gittuf root of trust for repository
* [gittuf trust remote](gittuf_trust_remote.md) - Tools for managing remote policies
* [gittuf trust remove-github-app](gittuf_trust_remove-github-app.md) - Remove GitHub app from gittuf root of trust
* [gittuf trust remove-global-rule](gittuf_trust_remove-global-rule.md) - Remove a global rule from root of trust (developer mode only, set GITTUF_DEV=1)
* [gittuf trust remove-policy-key](gittuf_trust_remove-policy-key.md) - Remove Policy key from gittuf root of trust
* [gittuf trust remove-propagation-directive](gittuf_trust_remove-propagation-directive.md) - Remove propagation directive from gittuf root of trust (developer mode only, set GITTUF_DEV=1)
* [gittuf trust remove-root-key](gittuf_trust_remove-root-key.md) - Remove Root key from gittuf root of trust
* [gittuf trust set-repository-location](gittuf_trust_set-repository-location.md) - Set repository location
* [gittuf trust sign](gittuf_trust_sign.md) - Sign root of trust
* [gittuf trust update-policy-threshold](gittuf_trust_update-policy-threshold.md) - Update Policy threshold in the gittuf root of trust
* [gittuf trust update-root-threshold](gittuf_trust_update-root-threshold.md) - Update Root threshold in the gittuf root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_add-github-app.md 0000664 0000000 0000000 00000002231 14751501410 0022450 0 ustar 00root root 0000000 0000000 ## gittuf trust add-github-app
Add GitHub app to gittuf root of trust
### Synopsis
This command allows users to add a trusted key for the special GitHub app role. This key is used to verify signatures on GitHub pull request approval attestations. Note that authorized keys can be specified from disk, from the GPG keyring using the "gpg:" format, or as a Sigstore identity as "fulcio:::".
```
gittuf trust add-github-app [flags]
```
### Options
```
--app-key string app key to add to root of trust
-h, --help help for add-github-app
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_add-global-rule.md 0000664 0000000 0000000 00000002142 14751501410 0022616 0 ustar 00root root 0000000 0000000 ## gittuf trust add-global-rule
Add a new global rule to root of trust (developer mode only, set GITTUF_DEV=1)
```
gittuf trust add-global-rule [flags]
```
### Options
```
-h, --help help for add-global-rule
--rule-name string name of rule
--rule-pattern stringArray patterns used to identify namespaces rule applies to
--threshold int threshold of required valid signatures (default 1)
--type string type of rule (threshold|block-force-pushes)
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_add-policy-key.md 0000664 0000000 0000000 00000002113 14751501410 0022474 0 ustar 00root root 0000000 0000000 ## gittuf trust add-policy-key
Add Policy key to gittuf root of trust
### Synopsis
This command allows users to add a new trusted key for the main policy file. Note that authorized keys can be specified from disk, from the GPG keyring using the "gpg:" format, or as a Sigstore identity as "fulcio:::".
```
gittuf trust add-policy-key [flags]
```
### Options
```
-h, --help help for add-policy-key
--policy-key string policy key to add to root of trust
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_add-propagation-directive.md 0000664 0000000 0000000 00000002352 14751501410 0024713 0 ustar 00root root 0000000 0000000 ## gittuf trust add-propagation-directive
Add propagation directive into gittuf root of trust (developer mode only, set GITTUF_DEV=1)
```
gittuf trust add-propagation-directive [flags]
```
### Options
```
--from-reference string reference to propagate from in upstream repository
--from-repository string location of upstream repository
-h, --help help for add-propagation-directive
--into-path string path to propagate upstream contents into in downstream reference
--into-reference string reference to propagate into in downstream repository
--name string name of propagation directive
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_add-root-key.md 0000664 0000000 0000000 00000001464 14751501410 0022170 0 ustar 00root root 0000000 0000000 ## gittuf trust add-root-key
Add Root key to gittuf root of trust
```
gittuf trust add-root-key [flags]
```
### Options
```
-h, --help help for add-root-key
--root-key string root key to add to root of trust
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_apply.md 0000664 0000000 0000000 00000001355 14751501410 0021015 0 ustar 00root root 0000000 0000000 ## gittuf trust apply
Validate and apply changes from policy-staging to policy
```
gittuf trust apply [flags]
```
### Options
```
-h, --help help for apply
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_disable-github-app-approvals.md 0000664 0000000 0000000 00000001453 14751501410 0025335 0 ustar 00root root 0000000 0000000 ## gittuf trust disable-github-app-approvals
Mark GitHub app approvals as untrusted henceforth
```
gittuf trust disable-github-app-approvals [flags]
```
### Options
```
-h, --help help for disable-github-app-approvals
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_enable-github-app-approvals.md 0000664 0000000 0000000 00000001446 14751501410 0025162 0 ustar 00root root 0000000 0000000 ## gittuf trust enable-github-app-approvals
Mark GitHub app approvals as trusted henceforth
```
gittuf trust enable-github-app-approvals [flags]
```
### Options
```
-h, --help help for enable-github-app-approvals
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_init.md 0000664 0000000 0000000 00000001434 14751501410 0020631 0 ustar 00root root 0000000 0000000 ## gittuf trust init
Initialize gittuf root of trust for repository
```
gittuf trust init [flags]
```
### Options
```
-h, --help help for init
--location string location of repository
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_remote.md 0000664 0000000 0000000 00000001571 14751501410 0021163 0 ustar 00root root 0000000 0000000 ## gittuf trust remote
Tools for managing remote policies
### Options
```
-h, --help help for remote
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
* [gittuf trust remote pull](gittuf_trust_remote_pull.md) - Pull policy from the specified remote
* [gittuf trust remote push](gittuf_trust_remote_push.md) - Push policy to the specified remote
gittuf-0.9.0/docs/cli/gittuf_trust_remote_pull.md 0000664 0000000 0000000 00000001376 14751501410 0022222 0 ustar 00root root 0000000 0000000 ## gittuf trust remote pull
Pull policy from the specified remote
```
gittuf trust remote pull [flags]
```
### Options
```
-h, --help help for pull
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust remote](gittuf_trust_remote.md) - Tools for managing remote policies
gittuf-0.9.0/docs/cli/gittuf_trust_remote_push.md 0000664 0000000 0000000 00000001374 14751501410 0022223 0 ustar 00root root 0000000 0000000 ## gittuf trust remote push
Push policy to the specified remote
```
gittuf trust remote push [flags]
```
### Options
```
-h, --help help for push
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust remote](gittuf_trust_remote.md) - Tools for managing remote policies
gittuf-0.9.0/docs/cli/gittuf_trust_remove-github-app.md 0000664 0000000 0000000 00000001404 14751501410 0023216 0 ustar 00root root 0000000 0000000 ## gittuf trust remove-github-app
Remove GitHub app from gittuf root of trust
```
gittuf trust remove-github-app [flags]
```
### Options
```
-h, --help help for remove-github-app
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_remove-global-rule.md 0000664 0000000 0000000 00000001537 14751501410 0023372 0 ustar 00root root 0000000 0000000 ## gittuf trust remove-global-rule
Remove a global rule from root of trust (developer mode only, set GITTUF_DEV=1)
```
gittuf trust remove-global-rule [flags]
```
### Options
```
-h, --help help for remove-global-rule
--rule-name string name of rule
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_remove-policy-key.md 0000664 0000000 0000000 00000001545 14751501410 0023251 0 ustar 00root root 0000000 0000000 ## gittuf trust remove-policy-key
Remove Policy key from gittuf root of trust
```
gittuf trust remove-policy-key [flags]
```
### Options
```
-h, --help help for remove-policy-key
--policy-key-ID string ID of Policy key to be removed from root of trust
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_remove-propagation-directive.md 0000664 0000000 0000000 00000001623 14751501410 0025460 0 ustar 00root root 0000000 0000000 ## gittuf trust remove-propagation-directive
Remove propagation directive from gittuf root of trust (developer mode only, set GITTUF_DEV=1)
```
gittuf trust remove-propagation-directive [flags]
```
### Options
```
-h, --help help for remove-propagation-directive
--name string name of propagation directive
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_remove-root-key.md 0000664 0000000 0000000 00000001527 14751501410 0022735 0 ustar 00root root 0000000 0000000 ## gittuf trust remove-root-key
Remove Root key from gittuf root of trust
```
gittuf trust remove-root-key [flags]
```
### Options
```
-h, --help help for remove-root-key
--root-key-ID string ID of Root key to be removed from root of trust
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_set-repository-location.md 0000664 0000000 0000000 00000001476 14751501410 0024512 0 ustar 00root root 0000000 0000000 ## gittuf trust set-repository-location
Set repository location
```
gittuf trust set-repository-location [flags]
```
### Options
```
-h, --help help for set-repository-location
--location string location of repository
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_sign.md 0000664 0000000 0000000 00000001437 14751501410 0020631 0 ustar 00root root 0000000 0000000 ## gittuf trust sign
Sign root of trust
### Synopsis
This command allows users to add their signature to the root of trust file.
```
gittuf trust sign [flags]
```
### Options
```
-h, --help help for sign
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_update-policy-threshold.md 0000664 0000000 0000000 00000001761 14751501410 0024442 0 ustar 00root root 0000000 0000000 ## gittuf trust update-policy-threshold
Update Policy threshold in the gittuf root of trust
### Synopsis
This command allows users to update the threshold of valid signatures required for the policy.
```
gittuf trust update-policy-threshold [flags]
```
### Options
```
-h, --help help for update-policy-threshold
--threshold int threshold of valid signatures required for main policy (default -1)
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_trust_update-root-threshold.md 0000664 0000000 0000000 00000001751 14751501410 0024125 0 ustar 00root root 0000000 0000000 ## gittuf trust update-root-threshold
Update Root threshold in the gittuf root of trust
### Synopsis
This command allows users to update the threshold of valid signatures required for the root of trust.
```
gittuf trust update-root-threshold [flags]
```
### Options
```
-h, --help help for update-root-threshold
--threshold int threshold of valid signatures required for root (default -1)
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
-k, --signing-key string signing key to use to sign root of trust
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf trust](gittuf_trust.md) - Tools for gittuf's root of trust
gittuf-0.9.0/docs/cli/gittuf_verify-mergeable.md 0000664 0000000 0000000 00000001646 14751501410 0021657 0 ustar 00root root 0000000 0000000 ## gittuf verify-mergeable
Tools for verifying mergeability using gittuf policies
```
gittuf verify-mergeable [flags]
```
### Options
```
--base-branch string base branch for proposed merge
--bypass-RSL bypass RSL when identifying current state of feature ref
--feature-branch string feature branch for proposed merge
-h, --help help for verify-mergeable
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
gittuf-0.9.0/docs/cli/gittuf_verify-ref.md 0000664 0000000 0000000 00000001722 14751501410 0020503 0 ustar 00root root 0000000 0000000 ## gittuf verify-ref
Tools for verifying gittuf policies
```
gittuf verify-ref [flags]
```
### Options
```
--from-entry string perform verification from specified RSL entry (developer mode only, set GITTUF_DEV=1)
-h, --help help for verify-ref
--latest-only perform verification against latest entry in the RSL
--remote-ref-name string name of remote reference, if it differs from the local name
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
gittuf-0.9.0/docs/cli/gittuf_version.md 0000664 0000000 0000000 00000001173 14751501410 0020112 0 ustar 00root root 0000000 0000000 ## gittuf version
Version of gittuf
```
gittuf version [flags]
```
### Options
```
-h, --help help for version
```
### Options inherited from parent commands
```
--no-color turn off colored output
--profile enable CPU and memory profiling
--profile-CPU-file string file to store CPU profile (default "cpu.prof")
--profile-memory-file string file to store memory profile (default "memory.prof")
--verbose enable verbose logging
```
### SEE ALSO
* [gittuf](gittuf.md) - A security layer for Git repositories, powered by TUF
gittuf-0.9.0/docs/cli/main.go 0000664 0000000 0000000 00000001162 14751501410 0015772 0 ustar 00root root 0000000 0000000 //go:generate go run .
// SPDX-License-Identifier: Apache-2.0
package main
import (
"fmt"
"os"
"github.com/gittuf/gittuf/internal/cmd/root"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
)
var (
dir string
cmd = &cobra.Command{
Use: "gendoc",
Short: "Generate help docs",
Args: cobra.NoArgs,
RunE: func(*cobra.Command, []string) error {
return doc.GenMarkdownTree(root.New(), dir)
},
}
)
func init() {
cmd.Flags().StringVarP(&dir, "dir", "d", ".", "Path to directory in which to generate docs")
}
func main() {
if err := cmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
gittuf-0.9.0/docs/design-document.md 0000664 0000000 0000000 00000122077 14751501410 0017370 0 ustar 00root root 0000000 0000000 # gittuf Design Document
Last Modified: January 20, 2025
## Introduction
This document describes gittuf, a security layer for Git repositories.
With gittuf, any developer who can pull from a Git repository can independently
verify that the repository's security policies were followed. gittuf's policy,
inspired by [The Update Framework (TUF)](https://theupdateframework.io/),
handles key management for all trusted developers in a repository, allows for
setting permissions for repository namespaces such as branches, tags, and files,
and provides protections against
[attacks targeting Git metadata](https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/torres-arias).
At the same time, gittuf is backwards compatible with existing source control
platforms ("forges") such as GitHub, GitLab, and Bitbucket. gittuf is currently
a sandbox project at the
[Open Source Security Foundation (OpenSSF)](https://openssf.org/) as part of the
[Supply Chain Integrity Working Group](https://github.com/ossf/wg-supply-chain-integrity).
The core concepts of gittuf described in this document have been
[peer reviewed](https://ssl.engineering.nyu.edu/papers/yelgundhalli_gittuf_ndss_2025.pdf).
This document is scoped to describing how gittuf's write access control policies
are applied to Git repositories. Other additions to gittuf's featureset are
described in standalone [gittuf Augmentation Proposals (GAPs)](/docs/gaps/).
## Definitions
This document uses several terms or phrases in specific ways. These are defined
here.
### Git References (Refs) and Objects
A Git reference is a "simple name" that typically points to a particular Git
commit. Generally, development in Git repositories are centered in one or more
refs, and they're updated as commits are added to the ref under development. By
default, Git defines two of refs: branches ("heads") and tags. Git allows for
the creation of other arbitrary refs that users can store other information as
long as they are formatted using Git's object types.
Git employs a content addressed object store, with support for four types of
objects. An essential Git object is the "commit", which is a self-contained
representation of the whole repository. Each commit points to a "tree" object
that represents the state of the files in the root of the repository at that
commit. A tree object contains one or more entries that are either other tree
objects (representing subdirectories) or "blob" objects (representing files).
The final type of Git object is the "tag" object, used as a static pointer to
another Git object. While a tag object can point to any other Git object, it is
frequently used to point to a commit.
```
Repository
|
|-- refs
| |
| |-- heads
| | |-- main (refers to commit C)
| | |-- feature-x (refers to commit E)
| |
| |-- tags
| | |-- v1.0 (refers to tag v1.0)
| |
| |-- arbitrary
| |-- custom-ref (formatted as Git object type)
|
|-- objects
|-- A [Initial commit]
|-- B [Version 1.0 release]
|-- C [More changes on main]
|-- D [Initial commit on feature-x]
|-- E [More changes on feature-x]
|-- v1.0 [Tag object referring to commit B]
```
### Actors and Authentication
In a Git repository, an "actor" is any party, human or bot, who makes changes to
the repository. These changes can involve any part of the repository, such as
modifying files, branches or tags. In gittuf, each actor is identified by a
unique signing key that they use to cryptographically sign their contributions.
gittuf uses cryptographic signatures to authenticate actors as these signatures
can be verified by anyone who has the corresponding public key, fundamental to
gittuf's mission to enable independent verification of repository actions. Note
that gittuf does not rely on Git commit metadata (e.g., author email, committer
email) to identify the actor who created it, as that may be trivially spoofed.
In practice, a gittuf policy allows an actor to make certain changes by granting
trust to the actor's signing key to make those changes. To maintain security,
all actions made in the repository, such as adding or modifying files, are
checked for authenticity. This is done by verifying the digital signature
attached to the action, which must match the trusted public key associated with
the actor who is supposed to have made the change.
### State
The term "state" refers to the latest values or conditions of the tracked
references (like branches and tags) in a Git repository. These are determined
by the most recent entries in the
[reference state log](#reference-state-log-rsl). Note that when verifying
changes in the repository, a workflow may only verify specific references rather
than all state updates in the reference state log.
## Threat Model
The following threat model is taken from the
[peer reviewed publication](https://ssl.engineering.nyu.edu/papers/yelgundhalli_gittuf_ndss_2025.pdf)
describing gittuf.
We consider the standard scenario where a forge is used to manage a Git
repository on a centralized synchronization point. This forge can be a publicly
hosted solution (e.g., the github.com service), or self-hosted on premises by an
enterprise. Either option exposes the forge instance to both external attackers
and insider threats. External attackers may circumvent security measures and
compromise the version control system, manifesting themselves as advanced
persistent threats (APT) and making unnoticed changes to the system. Similarly,
insider threats may be posed by rogue employees with escalated privileges who
abuse their authority to make unnoticed changes.
To protect the integrity of the repository’s contents, the maintainers of the
repository define security controls such as which contributors can write to
different parts of the repository. gittuf is meant to protect against scenarios
where any party, individual developers, bots that make changes, or the forge
itself, may be compromised and act in an arbitrarily malicious way as seen in
prior incidents. This includes scenarios such as:
* T1: Modifying configured repository security policies, such as to weaken them
* T2: Tampering with the contents of the repository’s activity log, such as by
reordering, dropping, or otherwise manipulating log entries
* T3: Subverting the enforcement of security policies, such as by accepting
invalid changes instead of rejecting them
Note that we consider out of scope a freeze attack, where the forge serves stale
data, as development workflows involve a substantial amount of out-of-band
communication which prevents such attacks from going unnoticed. We similarly
consider weaknesses in cryptographic algorithms as out of scope.
## gittuf Design
gittuf records additional metadata describing the repository's policy and
activity in the repository itself. Effectively, gittuf treats security policies,
activity information, and policy decisions as a content tracking problem. To
avoid collisions with regular repository contents, gittuf stores its metadata in
custom references under `refs/gittuf/`.
### gittuf Policy
Note: This section assumes some prior knowledge of the
[TUF specification](https://theupdateframework.github.io/specification/).
The repository's policy metadata handles the distribution of the repository's
trusted keys (representing actors) as well as write access control rules. There
are two types of metadata used by gittuf, which are stored in a custom reference
`refs/gittuf/policy`.
#### Root of Trust
gittuf's policy metadata includes root of trust metadata, which
establishes why the policy must be trusted. The root of trust metadata (similar
to TUF's root metadata) declares the keys belonging to the repository owners as
well as a numerical threshold that indicates the minimum number of signatures
for the metadata to be considered valid. The root of trust metadata is signed by
a threshold of root keys, and the initial set of root keys for a repository must
be distributed using out-of-band mechanisms or rely on trust-on-first-use
(TOFU). Subsequent changes to the set of root keys are handled in-band, with a
new version of the root of trust metadata created. This new version must be
signed by a threshold of root keys trusted in the previous version.
#### Rule Files
The rules protecting the repository's namespaces are declared in one or more
rule files. A rule file is similar to TUF's targets metadata. It declares the
public keys for the trusted actors, as well as namespaced "delegations" which
specify protected namespaces within the repository and which actors are trusted
to write to them.
A threshold of trusted actors for any delegation (or rule) can extend this trust
to other actors by signing a new rule file with the same name as the delegation.
In this rule file, they can add the actors who must be trusted for the same (or
a subset) of namespaces.
All repositories must contain a primary rule file (typically called
"targets.json" to match TUF's behavior). This rule file may contain no rules,
signifying that no repository namespaces are protected. The primary rule file
derives its trust directly from the root of trust metadata; it must be signed by
a threshold of actors trusted to manage the repository's primary rule file. All
other rule files derive their trust directly or indirectly from the primary rule
file through delegations.

_In this example, the repository administrator grants write permissions to Carol
for the main branch, to Alice for the alice-dev branch, and to Bob for the
/tests folder (under any of the existing branches)._
A significant difference between typical TUF metadata and those used by gittuf
is in the expectations of the policies. Typical TUF deployments are explicit
about the artifacts they are distributing. Any artifact not listed in TUF
metadata is rejected. In gittuf, policies are written only to express
_restrictions_. As such, when verifying changes to unprotected namespaces,
gittuf must allow any key to sign for these changes. This means that after all
explicit policies (expressed as delegations) are processed, and none apply to
the namespace being verified, an implicit `allow-rule` is applied, allowing
verification to succeed.
#### Example gittuf Policy
The following example is taken from the
[peer reviewed publication](https://ssl.engineering.nyu.edu/papers/yelgundhalli_gittuf_ndss_2025.pdf)
of gittuf's design. It shows a gittuf policy state with its root of trust and
three distinct rule files connected using delegations. The root of trust
declares the trusted signers for the next version of the root of trust as well
as the primary rule file. Signatures are omitted.
```
rootOfTrust:
keys: {R1, R2, R3, P1, P2, P3}
signers:
rootOfTrust: (2, {R1, R2, R3})
primary: (2, {P1, P2, P3})
ruleFile: primary
keys: {Alice, Bob, Carol, Helen, Ilda}
rules:
protect-main-prod: {git:refs/heads/main,
git:refs/heads/prod}
-> (2, {Alice, Bob, Carol})
protect-ios-app: {file:ios/*}
-> (1, {Alice})
protect-android-app: {file:android/*}
-> (1, {Bob})
protect-core-libraries: {file:src/*}
-> (2, {Carol, Helen, Ilda})
ruleFile: protect-ios-app
keys: {Dana, George}
rules:
authorize-ios-team: {file:ios/*}
-> (1, {Dana, George})
ruleFile: protect-android-app
keys: {Eric, Frank}
rules:
authorize-android-team: {file:android/*}
-> (1, {Eric, Frank})
```
### Tracking Repository Activity
gittuf leverages a "Reference State Log (RSL)" to track changes to the
repository's references. In addition, gittuf uses the
[in-toto Attestation Framework](https://github.com/in-toto/attestation) to
record other repository activity such as code review approvals.
#### Reference State Log (RSL)
Note: This document presents a summary of the RSL. For a full understanding of
the attacks mitigated by the RSL, please refer to the
[academic](https://www.usenix.org/system/files/conference/usenixsecurity16/sec16_paper_torres-arias.pdf)
[papers](https://ssl.engineering.nyu.edu/papers/yelgundhalli_gittuf_ndss_2025.pdf)
underpinning gittuf's design.
The Reference State Log contains a series of entries that each describe some
change to a Git ref. Such entries are known as RSL reference entries. Each entry
contains the ref being updated, the new location it points to, and a hash of the
parent RSL entry. The entry is signed by the actor making the change to the ref.
Additionally, the RSL supports annotation entries that refer to prior reference
entries. An annotation entry can be used to attach additional user-readable
messages to prior RSL entries or to mark those entries as revoked.
Given that each entry points to its parent entry using its hash, an RSL is a
hash chain. gittuf's implementation of the RSL uses Git's underlying Merkle
graph. Generally, gittuf is designed to ensure the RSL is linear but a
privileged attacker may be able to cause the RSL to branch, resulting in a fork*
attack where different actors are presented different versions of the RSL. The
feasibility and implications of such an attack are discussed later in this
document.
The RSL is tracked at `refs/gittuf/reference-state-log`, and is implemented as a
distinct commit graph. Each commit corresponds to one entry in the RSL, and
standard Git signing mechanisms are employed for the actor's signature on the
RSL entry. The latest entry is identified using the tip of the RSL Git ref.
Note that the RSL and liveness of the repository in Git remove the need for some
traditional TUF roles. As the RSL records changes to other Git refs in the
repository, it incorporates TUF's
[snapshot role](https://theupdateframework.github.io/specification/latest/#snapshot)
properties. At present, gittuf does not include an equivalent to TUF's
[timestamp role](https://theupdateframework.github.io/specification/latest/#timestamp)
to guarantee the freshness of the RSL. This is because the timestamp role in the
context of gittuf at most provides a non-repudiation guarantee for each claim of
the RSL's tip. The use of an online timestamp does not guarantee that actors
will receive the correct RSL tip. This may evolve in future versions of the
gittuf design.
##### RSL Reference Entries
These entries are the standard variety described above. They contain the name of
the reference they apply to and a target ID. As such, they have the following
structure.
```
RSL Entry
ref: [
targetID:
number:
```
The `targetID` is typically the ID of a commit for references that are branches.
However, for entries that record the state of a Git tag, `targetID` is the ID of
the annotated tag object.
##### RSL Annotation Entries
Apart from regular entries, the RSL can include annotations that apply to prior
RSL entries. Annotations can be used to add more information as a message about
a prior entry, or to _explicitly_ mark one or more entries as ones to be
skipped. This semantic is necessary when accidental or possibly malicious RSL
entries are recorded. Since the RSL history cannot be overwritten, an annotation
entry must be used to communicate to gittuf clients to skip the corresponding
entries. Annotations have the following schema.
```
RSL Annotation
entryID:
entryID:
...
skip:
number:
-----BEGIN MESSAGE-----
------END MESSAGE------
```
##### Example Entries
Here's a sample RSL, with the output taken from `gittuf rsl log`:
```
entry a5ea2c6ee7e8b577f6be6fcee5b06e6cac7166fa (skipped)
Ref: refs/heads/main
Target: 6cb8e5c546eab3d0e1d245014de8003febb8e9b3
Number: 5
Annotation ID: cccfb6f27b2a71c33e9a55bc82f084e2445aa398
Skip: yes
Number: 6
Message:
Skipping RSL entry
entry 40c82851f78c7018f4c360030a83923b0925c28d
Ref: refs/gittuf/policy
Target: b7cf91ec9b5b6b17334ab1378dc85375236524f5
Number: 4
entry 94c153bff6d684a956ed27f0abd70624e875657c
Ref: refs/gittuf/policy-staging
Target: b7cf91ec9b5b6b17334ab1378dc85375236524f5
Number: 3
entry fed977a5ca07e566af3a37808284dc7c5a67d6dc
Ref: refs/gittuf/policy-staging
Target: dcbb536bd86a69e555692aec7b65c20de8257ee2
Number: 2
entry e026a62f1c63c6db58bb357f9a85cafe05c64fb6
Ref: refs/gittuf/policy-staging
Target: 603fc733218a0a1e54ccde47d1d9864f67e0bb75
Number: 1
```
Specifically, the latest reference entry
`a5ea2c6ee7e8b577f6be6fcee5b06e6cac7166fa` has been skipped by an annotation
entry `cccfb6f27b2a71c33e9a55bc82f084e2445aa398`.
The commit object for the reference entry is as follows:
```bash
~/tmp/repo $ git cat-file -p a5ea2c6ee7e8b577f6be6fcee5b06e6cac7166fa
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent 40c82851f78c7018f4c360030a83923b0925c28d
author Aditya Sirish A Yelgundhalli 1729514863 -0400
committer Aditya Sirish A Yelgundhalli 1729514863 -0400
gpgsig -----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg8g2CmHSb7guzi6MUNgwHUQnxPN
X1x8urScZyJrUB6MMAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
AAAAQGQMSviwqF+cE/wgEo0U73vu86YHi4f5crzzFIctjyMGOOy2isYfHgGvSzs5bv6V2Q
EtMumBSVbCxvnRqJpiFAs=
-----END SSH SIGNATURE-----
RSL Reference Entry
ref: refs/heads/main
targetID: 6cb8e5c546eab3d0e1d245014de8003febb8e9b3
number: 5
```
Similarly, the commit object for the annotation entry is as follows:
```bash
~/tmp/repo $ git cat-file -p cccfb6f27b2a71c33e9a55bc82f084e2445aa398
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent a5ea2c6ee7e8b577f6be6fcee5b06e6cac7166fa
author Aditya Sirish A Yelgundhalli 1729514924 -0400
committer Aditya Sirish A Yelgundhalli 1729514924 -0400
gpgsig -----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg8g2CmHSb7guzi6MUNgwHUQnxPN
X1x8urScZyJrUB6MMAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5
AAAAQNf32yJvhGfLIIeeStHgkSB7iuRGJl6LhbRTpX/q49lUu4TrEiCeGa3H8LMJ/5D1EE
in3QAhlzdowYnmCKglTAw=
-----END SSH SIGNATURE-----
RSL Annotation Entry
entryID: a5ea2c6ee7e8b577f6be6fcee5b06e6cac7166fa
skip: true
number: 6
-----BEGIN MESSAGE-----
U2tpcHBpbmcgUlNMIGVudHJ5
-----END MESSAGE-----
```
#### Attestations for Authorization Records
gittuf makes use of the signing capability provided by Git for commits and tags
significantly. However, it is sometimes necessary to attach more than a single
signature to a Git object or repository action. For example, a policy may
require more than one developer to sign off and approve a change such as merging
something to the `main` branch. To support these workflows (while also remaining
compatible with standard Git clients), gittuf uses the concept of "detached
authorizations", implemented using signed [in-toto
attestations](https://github.com/in-toto/attestation). Attestations are tracked
in the custom Git reference `refs/gittuf/attestations`. The gittuf design
currently supports the "reference authorization" type to represent code review
approvals. Other types may be added to this document or via [GAPs](/docs/gaps/)
in future.
A reference authorization is an attestation that accompanies an RSL reference
entry, allowing additional developers to issue signatures authorizing the change
to the Git reference in question. Its structure is similar to that of a
reference entry:
```
TargetRef string
FromTargetID string
ToTargetID string
```
The `TargetRef` is the Git reference the authorization is for, while
`FromTargetID` and `ToTargetID` record the change in the state of the reference
authorized by the attestation (as Git hashes). The information pertaining to the
prior state of the Git reference is explicitly recorded in the attestation
unlike a standard RSL reference entry. This is because, for a reference entry,
this information can be implicitly identified using the RSL by examining the
previous entry for the reference in question. If the authorization is for a
brand new reference (say a new branch or any tag), `FromTargetID` must be set to
zero. For a change to a branch, `ToTargetID` pre-computes the Git merge tree
resulting from the change being approved. Thus, when verifying the change to the
branch, it must be followed by an RSL reference entry that points to a commit
which has the same Git tree ID. For a tag, `ToTargetID` records the Git object
the tag object is expected to point to.
Reference authorizations are stored in a directory called
`reference-authorizations` in the attestations namespace. Each authorization
must have the in-toto predicate type:
`https://gittuf.dev/reference-authorization/v`.
## gittuf Workflows
gittuf introduces some new workflows that are gittuf-specific, such as the
creation of policies and their verification. In addition, gittuf interposes in
some Git workflows so as to capture repository activity information.
### Policy Initialization and Changes
When the policy is initialized or updated (this can be a change to the root of
trust metadata or one or more rule files), a new policy state is created that
contains the full set of gittuf policy metadata. This is recorded as a commit in
the custom ref used to track the policy metadata (typically
`refs/gittuf/policy`). In turn, the commit to the custom ref is recorded in the
RSL, indicating the policy state to use for subsequent changes in the
repository.
### Syncing gittuf References
As the RSL must be linear with no branches, gittuf employs a variation of the
`Secure_Fetch` and `Secure_Push` workflows described in the
[RSL academic paper](https://www.usenix.org/system/files/conference/usenixsecurity16/sec16_paper_torres-arias.pdf).

_Note that gittuf can be used even if the synchronization point is not
gittuf-enabled. The repository can host the gittuf namespaces which other gittuf
clients can pull from for verification. In this example, a gittuf client with a
changeset to commit to the dev branch (step 1), creates in its local repository
a new commit object and the associated RSL entry (step 2). These changes are
pushed next to a remote Git repository (step 3), from where other gittuf or
legacy Git clients pull the changes (step 4)._
#### `RSLFetch`: Receiving Remote RSL Changes
Before local RSL changes can be made or pushed, it is necessary to verify that
they are compatible with the remote RSL state. If the remote RSL has entries
that are unavailable locally, entries made locally will be rejected by the
remote. For example, let the local RSL tip be entry A and the new entry be entry
C. If the remote has entry B after A with B being the tip, attempting to push C
which also comes right after A will fail. Instead, the local RSL must first
fetch entry B and then create entry C. This is because entries in the RSL must
be made serially. As each entry includes the ID of the previous entry, a local
entry that does not incorporate the latest RSL entry on the remote is invalid.
The workflow is as follows:
1. Fetch remote RSL to the local remote tracker
`refs/remotes/origin/gittuf/reference-state-log`.
1. If the last entry in the remote RSL is the same as the local RSL, terminate
successfully.
1. Perform the verification workflow for the new entries in the remote RSL,
incorporating remote changes to the local policy namespace. The verification
workflow is performed for each Git reference in the new entries, relative to
the local state of each reference. If verification fails, abort and warn
user. Note that the verification workflow must fetch each Git reference to
its corresponding remote tracker, `refs/remotes/origin/][`.
1. For each modified Git reference, update the local state. As all the refs have
been successfully verified, each ref's remote state can be applied to the
local repository, so `refs/heads/][` matches `refs/remotes/origin/][`.
1. Set local RSL to the remote RSL's tip.
NOTE: Some aspects of this workflow are under discussion and are subject to
change. The gittuf implementation does not implement precisely this workflow.
Specifically, the implementation does not verify new entries in the remote
automatically. Additionally, the RSL may contain entries for references a client
does not have, making verification of those entries unfeasible. See
https://github.com/gittuf/gittuf/issues/708.
#### `RSLPush`: Submitting Local RSL Changes
1. Execute `RSLFetch` repeatedly until there are no new RSL entries in the
remote RSL. Every time there is a remote update, the user must be prompted to
fetch and re-apply their changes to the RSL. This process could be automated
but user intervention may be needed to resolve conflicts in the refs they
modified. Changes to the gittuf policy must be fetched and applied locally.
1. Verify the validity of the RSL entries being submitted using locally
available gittuf policies to ensure the user is authorized for the changes.
If verification fails, abort and warn user.
1. Perform an atomic Git push to the remote of the RSL as well as the modified
Git references. If the push fails, it is likely because another actor pushed
their changes first. Restart the `RSLPush` workflow.
NOTE: Some aspects of this workflow are under discussion and are subject to
change. The gittuf implementation does not implement precisely this workflow.
This workflow is closely related to other push operations performed in the
repository, and therefore, this section may be incorporated with other
workflows. See https://github.com/gittuf/gittuf/issues/708.
### Regular Pushes
When an actor pushes a change to a remote repository, this update to the
corresponding ref (or refs) must be recorded in the RSL. For each ref being
pushed, the gittuf client creates a new RSL entry. Then, `RSLPush` is used to
submit these changes to the remote repository.
### Force Pushes
Due to the linear nature of the RSL, it is not possible to remove a reference
entry. A force push makes one or more prior reference entries for the pushed ref
invalid as the targets recorded in those entries may not be reachable any
longer. Thus, these entries must be marked as "skipped" in the RSL using an
annotation entry. After an annotation for these reference entries is created, a
reference entry is created recording the current state of the ref. Then,
`RSLPush` is used to submit these changes to the remote repository.
### Verification Workflow
There are several aspects to verification. First, the right policy state must be
identified by walking back RSL entries to find the last change to that
namespace. Next, authorized keys must be identified to verify that commit or RSL
entry signatures are valid.
#### Identifying Authorized Signers for Protected Namespaces
When verifying a commit or RSL entry, the first step is identifying the set of
keys authorized to sign a commit or RSL entry in their respective namespaces.
This is achieved by performing pre-ordered depth first search over the
delegations graph in a gittuf policy state. Assume the relevant policy state
entry is `P` and the namespace being checked is `N`. Then:
1. Validate `P`'s root metadata using the TUF workflow starting from the initial
root of trust metadata, ignore expiration date checks (see
https://github.com/gittuf/gittuf/issues/280).
1. Create empty set `K` to record authorized verifiers for `N`.
1. Create empty set `queue` to track the rules (or delegations) that must be
checked.
1. Begin traversing the delegations graph rooted at the primary rule file
metadata.
1. Verify the signatures of the primary rule file using the trusted keys in the
root of trust. If a threshold of signatures cannot be verified, abort.
1. Populate `queue` with the rules in the primary rule file.
1. While `queue` is not empty:
1. Set `rule` to the first item in `queue`, removing it from `queue`.
1. If `rule` is the `allow-rule`:
1. Proceed to the next iteration.
1. If the patterns of `rule` match `N` (i.e., the rule applies to the
namespace being verified):
1. Create a verifier with the trusted keys in `rule` and the specified
threshold.
1. Add this verifier to `K`.
1. If `P` contains a rule file with the same name as `rule` (i.e., a
delegated rule file exists):
1. Verify that the delegated rule file is signed by a threshold of
valid signatures using the keys declared in delegating rule file.
Abort if verification fails.
1. Add the rules in `current` to the front of `queue` (ensuring the
delegated rules are prioritized to match pre-order depth first
search behavior).
1. Return `K`.
#### Verifying Changes Made
In gittuf, verifying the validity of changes is _relative_. Verification of a
new state depends on comparing it against some prior, verified state. For some
ref `X` that is currently at verified entry `S` in the RSL and its latest
available state entry is `D`:
1. Fetch all changes made to `X` between the commit recorded in `S` and that
recorded in `D`, including the latest commit into a temporary branch.
1. Walk back from `S` until an RSL entry `P` is found that updated the gittuf
policy namespace. This identifies the policy that was active for changes made
immediately after `S`. If a policy entry is not found, abort.
1. Walk back from `S` until an RSL entry `A` is found that updated the gittuf
attestations ref. This identifies the set of attestations applicable for the
changes made immediately after `S`.
1. Validate `P`'s metadata using the TUF workflow, ignore expiration date
checks (see https://github.com/gittuf/gittuf/issues/280).
1. Walk back from `D` until `S` and create an ordered list of all RSL updates
that targeted either `X` or gittuf namespaces. Entries pertaining to other
refs MAY be ignored. Annotation entries MUST be recorded.
1. The verification workflow has an ordered list of states
`[I1, I2, ..., In, D]` that are to be verified.
1. Set trusted set for `X` to `S`.
1. For each set of consecutive states starting with `(S, I1)` to `(In, D)`:
1. Check if an annotation exists for the second state. If it does, verify if
the annotation indicates the state is to be skipped. It true, proceed to
the next set of consecutive states.
1. If second state changes gittuf policy:
1. Validate new policy metadata using the TUF workflow and `P`'s contents
to established authorized signers for new policy. Ignore expiration
date checks (see https://github.com/gittuf/gittuf/issues/280). If
verification passes, update `P` to new policy state.
1. If second state is for attestations:
1. Set `A` to the new attestations state.
1. Verify the second state entry was signed by an authorized key as defined
in `P` for the ref `X`. If the gittuf policy requires more than one
signature, search for a reference authorization attestation for the same
change. Verify the signatures on the attestation are issued by authorized
keys to meet the threshold, ignoring any signatures from the same key as
the one used to sign the entry.
1. If `P` contains rules protecting files in the repository:
1. Enumerate all commits between that recorded in trusted state and the
second state with the signing key used for each commit.
1. Identify the net or combined set of files modified between the commits
in the first and second states as `F`.
1. If all commits are signed by the same key, individual commits need not
be validated. Instead, `F` can be used directly. For each path:
1. Find the set of keys authorized to make changes to the path in
`P`.
1. Verify key used is in authorized set. If not, terminate
verification workflow with an error.
1. If not, iterate over each commit. For each commit:
1. Identify the file paths modified by the commit. For each path:
1. Find the set of keys authorized to make changes to the path in
`P`.
1. Verify key used is in authorized set. If not, check if path is
present in `F`, as an unauthorized change may have been corrected
subsequently. This merely acts as a hint as path may have been also
changed subsequently by an authorized user, meaning it is in `F`. If
path is not in `F`, continue with verification. Else, request user
input, indicating potential policy violation.
1. Set trusted state for `X` to second state of current iteration.
1. Return indicating successful verification.
NOTE: Some aspects of this workflow are under discussion and are subject to
change. The gittuf implementation does not implement precisely this workflow,
instead also including aspects of the recovery workflow to see if a change that
fails verification has already been recovered from. See
https://github.com/gittuf/gittuf/issues/708.
### Recovery
If every user were using gittuf and were performing each operation by
generating all of the correct metadata, following the specification, etc., then
the procedure for handling each situation is fairly straightforward. However,
an important property of gittuf is to ensure that a malicious or erroneous
party cannot make changes that impact the state of the repository in a negative
manner. To address this, this section discusses how to handle situations where
something has not gone according to protocol. The goal is to recover to a
"known good" situation which does match the metadata which a set of valid
gittuf clients would generate.
#### Recovery Mechanisms
When gittuf verification fails, the following recovery workflow must be
employed. This mechanism is utilized in scenarios where some change is rejected.
For example, one or more commits may have been pushed to a branch that do not
meet gittuf policy. The repository is updated such that these commits are
neutralized and all Git refs match their latest RSL entries. This can take two
forms:
1. The rejected commit is removed and the state of the repo is set to the prior
commit which is known to be good. This is used when all rejected commits are
together at the end of the commit graph, making it easy to remove all of them.
2. The rejected commit is _reverted_ where a new commit is introduced that
reverses all the changes made in the reverted commit. This is needed when "good"
commits that must be retained are interspersed with "bad" commits that must be
rejected.
In both cases, new RSL entries and annotations must be used to record the
incident and skip the invalid RSL entries corresponding to the rejected changes.
gittuf, by default, prefers the second option, with an explicit revert commit
that is tree-same as the last good commit. This ensures that a client can always
fast-forward to a fix rather than rewind. By resetting the affected branch to a
prior good commit, Git clients that have already pulled in the invalid commit
will not reset as well. Instead, they will assume they are ahead of the remote
in question and will continue to use the bad commit as the latest commit.
When the gittuf verification workflow encounters an RSL entry for some Git
reference that does not meet policy, it looks to see if a subsequent entry for
the same reference contains a fix that aligns with the last known good state.
Any intermediate entries between the original invalid entry and the fix for the
reference in question are also considered to be invalid. Therefore, in addition
to the fix RSL entry, gittuf also expects skip annotations for the original
invalid entry and intermediate entries for the reference.
#### Recovery Scenarios
These scenarios are some examples where recovery is necessary. This is not meant
to be an exhaustive set of gittuf's recovery scenarios.
##### An Incorrect RSL Entry is Added
There are several ways in which an RSL entry can be considered "incorrect". If
an entry is malformed (structurally), Git may catch it if it's not a valid
commit. In such instances, the push from a buggy client is rejected altogether,
meaning other users are not exposed to the malformed commit.
Invalid entries that are not rejected by Git must be caught by gittuf. Some
examples of such invalid entries are:
* RSL entry is for a non-existing Git reference
* Commit recorded in RSL entry does not exist
* Commit recorded in RSL entry does not match the tip of the corresponding Git
reference
* RSL annotation contains references to RSL entries that do not exist or are not
RSL entries (i.e. the annotation points to other commits in the repository)
Note that as invalid RSL entries are only created by buggy or malicious gittuf
clients, these entries cannot be detected prior to them being pushed to the
synchronization point.
As correctly implemented gittuf clients verify the validity of RSL entries when
they pull from the synchronization point, the user is warned if invalid entries
are encountered. Then, the user can then use the recovery workflow to invalidate
the incorrect entry. Other clients with the invalid entry only need to fetch the
latest RSL entries to recover. Additionally, the client that created the invalid
entries must switch to a correct implementation of gittuf before further
interactions with the main repository, but this is left to out-of-band
synchronization between the actors who notice the issue and the actor using a
buggy client.
##### A gittuf Access Control Policy is Violated
An actor, Bob, creates an RSL entry for a branch he's not authorized for by
gittuf policy. He pushes a change to that branch. Another actor, Alice, notices
this when her gittuf client indicates a failure in the verification workflow.
Alice creates an RSL annotation marking Bob's entry as one to be skipped. Alice
also reverses Bob's change, creating a new RSL entry reflecting that.
##### Attacker Modifies or Deletes Historical RSL Entry
Overwriting or deleting an historical RSL entry is a complicated proposition.
Git's content addressable properties mean that a SHA-1 collision is necessary to
overwrite an existing RSL entry in the Git object store. Further, the attacker
also needs more than push access to the repository as Git will not accept an
object it already has in its store. Similarly, deleting an entry from the object
store preserves the RSL structure cosmetically but verification workflows that
require the entry will fail. This ensures that such an attack is detected, at
which point the owners of the repository can restore the RSL state from their
local copies.
Also note that while Git uses SHA-1 for its object store, cryptographic
signatures are generated and verified using stronger hash algorithms. Therefore,
a successful SHA-1 collision for an RSL entry will not go undetected as all
entries are signed.
##### Forge Attempts Fork* Attacks
An attacker who controls the forge may attempt a fork* attack where different
developers receive different RSL states. For example, the attacker may drop a
push from an actor, Alice, from the RSL. Other developers such as Bob and Carol
would continue adding their RSL entries, unaware of the dropped entry. However,
Alice will observe the divergence in the RSL as she cannot receive Bob's and
Carol's changes.
The attacker cannot simply reapply Bob's and Carol's changes over Alice's RSL
entry without also controlling Bob's and Carol's keys. The attacker may attempt
a freeze attack targeted against Alice, where she's always told her entry is the
latest in the RSL. However, any out-of-band communication between Alice and
either Bob or Carol (common during development workflows) will highlight the
attack.
##### An Authorized Key is Compromised
When a key authorized by gittuf policy is compromised, it must be revoked and
rotated so that an attacker cannot use it to sign repository objects. gittuf
policies that grant permissions to the key must be updated to revoke the key,
possibly adding the actor's new key in the process. Further, if a security
analysis shows that the key was used to make malicious changes, those changes
must be reverted and the corresponding RSL entries signed with the compromised
key must be skipped. This ensures that gittuf clients do not consider attacker
created RSL entries as valid states for the corresponding Git references.
Clients that have an older RSL from before the attack can skip past the
malicious entries altogether.
## Example of Using gittuf
Consider project `foo`'s Git repository maintained by Alice and Bob. Alice and
Bob are the only actors authorized to update the state of the main branch. This
is accomplished by defining a TUF delegation to Alice and Bob's keys for the
namespace corresponding to the main branch. All changes to the main branch's
state MUST have a corresponding entry in the repository's RSL signed by either
Alice or Bob.
Further, `foo` has another contributor, Clara, who does not have maintainer
privileges. This means that Clara is free to make changes to other Git branches
but only Alice or Bob may merge Clara's changes from other unprotected branches
into the main branch.
Over time, `foo` grows to incorporate several subprojects with other
contributors Dave and Ella. Alice and Bob take the decision to reorganize the
repository into a monorepo containing two projects, `bar` and `baz`. Clara and
Dave work exclusively on bar and Ella works on baz with Bob. In this situation,
Alice and Bob retain their privileges to merge changes to the main branch.
Further, they set up delegations for each subproject's path within the
repository. Clara and Dave are only authorized to work on files within `bar/*`
and Ella is restricted to `baz/*`. As Bob is a maintainer of foo, he is not
restricted to working only on `baz/*`.
gittuf-0.9.0/docs/dogfood.md 0000664 0000000 0000000 00000004535 14751501410 0015722 0 ustar 00root root 0000000 0000000 # Dogfooding gittuf
Last Modified: April 24, 2024
As noted in gittuf's [roadmap](/docs/roadmap.md), we want to use gittuf to
secure the development of gittuf itself. Note that when we are dogfooding
gittuf, we do not expect the policy to remain consistent over time, especially
as gittuf itself may have breaking changes in the coming months. After gittuf
reaches v1, we expect to reset the policy and start over with a formal root
signing. We envision dogfooding to happen in several phases.
## Phase 1
At this stage, we will rely on automation to create and sign RSL entries on
behalf of the gittuf maintainers. While this is quite a bit less secure than
signatures issued directly by the maintainers, we believe this serves as a
starting point for us to feel gittuf's pain points ourselves. In addition to
signing RSL entries using sigstore online, we will be recording a GitHub
attestation of each pull request merged into the main branch. This will serve as
an auditable paper trail to inspect using gittuf in future.
## Phase 2
With command compatibility and improved usability of the gittuf tool, we will
begin transitioning to at least some RSL entries being issued by local keys held
by maintainers. This may also be accompanied by the development of helper tools
such as a gittuf merge bot that can verify whose signatures / approvals are
still needed in a pull request and present them with the commands to run to meet
those requirements.
## Phase 3
Finally, as gittuf nears v1, we expect to transition more seamlessly to
primarily offline signatures. This can, as before, only be achieved with further
usability improvements. In this final phase, we hope to essentially have worked
out the kinks with using gittuf actively so that we can proceed with a stable
release.
## Verifying gittuf using gittuf
To install gittuf, please refer to our [get started guide].
First, clone the repository and fetch the gittuf specific metadata.
```bash
gittuf clone https://github.com/gittuf/gittuf
```
Alternatively, you can use Git as follows.
```bash
git clone https://github.com/gittuf/gittuf
cd gittuf
git fetch origin refs/gittuf/*:refs/gittuf/*
```
Next, the latest release of gittuf as well as changes to the `main` branch can
be verified using gittuf.
```bash
gittuf verify-ref --verbose v0.4.0
gittuf verify-ref --verbose main
```
[get started guide]: /docs/get-started.md
gittuf-0.9.0/docs/gaps/ 0000775 0000000 0000000 00000000000 14751501410 0014702 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/gaps/1/ 0000775 0000000 0000000 00000000000 14751501410 0015042 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/gaps/1/README.md 0000664 0000000 0000000 00000016054 14751501410 0016327 0 ustar 00root root 0000000 0000000 # Providing SHA-256 Identifiers Alongside Existing SHA-1 Identifiers
## Metadata
* **Number:** 1
* **Title:** Providing SHA-256 Identifiers Alongside Existing SHA-1 Identifiers
* **Implemented:** No
* **Withdrawn/Rejected:** No
* **Sponsors:** Aditya Sirish A Yelgundhalli (adityasaky)
* **Last Modified:** January 20, 2025
## Abstract
Git stores all its objects in a content addressed store located under
`.git/objects`. The content address for each object is calculated using SHA-1.
Due to known weaknesses with SHA-1, this GAP explores using gittuf to provide
cryptoagility for the hash algorithm used in Git, whether SHA-256 or other
algorithms that may be desirable to adopt in future.
## Specification
Git stores all its objects in a content addressed store located under
`.git/objects`. This directory contains subdirectories that act as an index to
the hashes themselves. For example, the Git object for commit
`4dcd174e182cedf597b8a84f24ea5a53dae7e1e7` is stored as
`.git/objects/4d/cd174e182cedf597b8a84f24ea5a53dae7e1e7`. The hash is calculated
across the corresponding object prior to compressing it, and it can be
recalculated as follows:
```
cat .git/objects/4d/cd174e182cedf597b8a84f24ea5a53dae7e1e7 | zlib-flate -uncompress | sha1sum
4dcd174e182cedf597b8a84f24ea5a53dae7e1e7 -
```
There are several types of Git objects: commits, blobs, trees, and tags. Commits
record changes made in the repository. Blobs are files in the repository while
trees map to the directory structure of the repository. Trees contain a record
of blobs and subtrees.
Git commits store a record of their one or more parent commits (creating a
Merkle DAG). Each commit also points to the specific tree object that
represents the root of the repository.
```
git cat-file -p db1c7b0210513a452b0b971e1912d5eb2e3ffcd0
tree 7b968da28453b323a0d3333e3be4030b870d26e4
parent 4dcd174e182cedf597b8a84f24ea5a53dae7e1e7
...
```
Finally, tag objects serve as static pointers to other Git objects (frequently
commits). As with Git commits and trees, the tag object also identifies the
target Git object using its identifier.
This GAP proposes recomputing SHA-256 identifiers for every object in the
repository. In this method, gittuf would maintain a SHA-1 to SHA-256 mapping for
every object in Git's content addressed store. This mapping can be a simple key
value dictionary. When gittuf is invoked to calculate new identifiers, say when
creating a new commit, it must use Git's default semantics to create the object
with SHA-1 identifiers. For each new object created, it must replace SHA-1
identifiers with their SHA-256 equivalents, calculating them recursively if
necessary, and then finally calculate the SHA-256 hash. For every new object
encountered, a SHA-1 to SHA-256 entry must be added to the key value record.
Note that in this method, the new objects are not written to `.git/objects`.
Instead, the objects continue to be stored with their SHA-1 identifiers. The
only change is the addition of the file with the key value mapping.
TODO: Should a parallel set of objects be maintained with SHA-256 identifiers
that are symbolic links to their SHA-1 counterparts? This will probably not play
well with Git's packfiles while only maintaining a separate mapping will.
TODO: How much extra space does it take to store both versions of the objects?
TODO: How must this support arbitrary hash algorithms, beyond SHA-256?
TODO: How must the mapping of SHA-1 to SHA-256 (or other) hashes be stored and
synchronized in gittuf workflows?
### Impact on Commit / Tag signing
By default, Git signs commits using a SHA-256 representation of the commit
objects. However, these commit objects contain SHA-1 references. A collision of
the tree object referenced in the commit wouldn't be caught.
As such, the verification workflow for a commit must also validate that the
objects referenced by SHA-1 hashes also have the correct SHA-256 hashes. After
they are validated, the signature can be verified using the relevant public key
to check the identify of the committer.
TODO: Verification of SHA-256 hashes requires that the object be present as
well. How does this work when fetching new objects? Only a malicious object
that has a SHA-1 collision may be presented, meaning we don't have a reference
of the correct SHA-256 hash.
## Motivation
By default, Git uses the SHA-1 hash algorithm to calculate unique identifiers.
Due to known weaknesses with SHA-1, the Git community has proposed moving to
SHA-256. There is experimental support for SHA-256 identifiers, but:
1. repositories can't currently use both SHA-1 and SHA-256 identifiers, so
converting existing repositories means the loss of development history.
1. most Git servers or forges don't support SHA-256 identifiers.
Since gittuf maintains a separate set of metadata about the Git objects in a
repository, it can also provide a mapping to SHA-256 identifiers. This requires
gittuf to maintain a SHA-256 reference to every SHA-1 identifier that exists in
a repository.
## Reasoning
### Forward Compatibility with Git's SHA-256 Support
One reason for recomputing SHA-256 hashes for all objects is forward
compatibility. As noted before, Git includes experimental support for SHA-256.
Here, a repository must be initialized with the object format set to SHA-256.
From then on, all object identifiers are calculated using SHA-256 and stored in
`.git/objects`. The same data structures are maintained, except all SHA-1
identifiers are replaced with SHA-256 identifiers. This is similar to the
technique described here, meaning that SHA-256 identifiers calculated by gittuf
are the same as Git's SHA-256 identifiers. This will play well with any
transition techniques provided by Git for SHA-1 repositories to SHA-256.
### Alternate Solution
A simpler solution is to calculate the SHA-256 hash of commit objects, rather
than recompute hashes for all objects. This would look similar to:
```
cat .git/objects/4d/cd174e182cedf597b8a84f24ea5a53dae7e1e7 | zlib-flate -uncompress | sha256sum
c9262d30f2dd6e50088acbfb67fa49bb3e80c30e57779551727bc89fcf02e21b -
```
However, if a SHA-1 collision is successfully performed within the repository,
this technique has some blind spots. A collision with a commit object will be
detected as two distinct commit objects may collide in SHA-1 but overwhelmingly
won't in SHA-256. However, a collision in the tree object is more dangerous. In
this situation, the commit object can remain the same but point to a malicious
version of the tree. The SHA-256 identifier will not detect this change.
## Backwards Compatibility
This GAP does not impact the backwards compatibility of gittuf as it only
suggests recording additional information in gittuf metadata.
## Security
TODO: A detailed security analysis is necessary before this GAP can be implemented.
## Prototype Implementation
A prototype implementation was proposed in https://github.com/gittuf/gittuf/pull/105.
## Changelog
* January 20th, 2025: moved from `/docs/extensions` to `/docs/gaps` as GAP-1
## References
* [Git Hash Function Transition](https://git-scm.com/docs/hash-function-transition/2.48.0)
* [SHAttered](https://shattered.io/)
gittuf-0.9.0/docs/gaps/2/ 0000775 0000000 0000000 00000000000 14751501410 0015043 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/gaps/2/README.md 0000664 0000000 0000000 00000024506 14751501410 0016331 0 ustar 00root root 0000000 0000000 # gittuf on the Forge
## Metadata
* **Number:** 2
* **Title:** gittuf on the Forge
* **Implemented:** No
* **Withdrawn/Rejected:** No
* **Sponsors:** Aditya Sirish A Yelgundhalli (adityasaky)
* **Last Modified:** January 20, 2025
## Abstract
gittuf can be deployed at the forge that all developers push changes to. This
instance of gittuf must behave differently from regular gittuf clients because
multiple developers may be pushing and fetching from the forge at any given
point in time. This GAP explores several configurations for how a gittuf-aware
forge might behave.
## Specification
TODO: The specification for this GAP depends on the configurations selected by
the community. Eventually, this GAP may be split into multiple GAPs with each
one handling a configuration that provides a subset of the desired properties
for gittuf on the forge.
## Motivation
There are several motivating factors to consider supporting gittuf on the forge:
* **Ease of deployment:** in some threat models, it may be acceptable to trust
the forge to record gittuf metadata which can be used to keep the forge honest.
In turn, these deployments are easier as lesser client-side tooling needs to be
installed and updated.
* **High traffic repositories:** for repositories with a high volume of pushes,
client-side RSL entry creation may be impractical.
* **Reject rather than recover:** in some deployments, especially with a mix of
gittuf-enabled and Git-only clients, it may be preferable to have the forge
reject bad changes rather than recover post facto to avoid serving these
unauthorized changes to Git-only clients in the interim period before a gittuf
client can initiate the recovery workflow.
* **Standardized Git security protocol:** a subset of gittuf's features can be
adopted as the standardized protocol for how forge security policies are
configured and enforced, thus enabling cross-forge validation of a repository's
historic security decisions.
## Reasoning
There are several aspects that must be considered in integrating gittuf with a
forge. These are enumerated here with a description of the default configuration
in gittuf:
* RSL Entry Creation: in the standard gittuf model, all RSL entries are created
and signed by clients when they push their changes. Thus, every push can be
authenticated using the signature on the RSL entry, and the synchronization
point is not responsible for ordering pushes in the repository meaning it cannot
reorder or drop pushes.
* Verification: in the standard gittuf model, every gittuf client performs
verification when it receives changes from the synchronization point. Typically,
this means that a change that fails verification must be fixed after the fact.
* Git Reference Updates: in the standard gittuf model, a gittuf client pushes
directly to the references on the synchronization point the user wishes to
update along with corresponding RSL entries. The RSL entries are submitted to
the synchronization point's RSL directly after the client fetches the latest
state of the RSL to ensure the new entries are added at the very end of the RSL.
The gittuf client makes this push atomically, meaning either all references are
updated or none are updated,
### Configuration A
**Summary:** Clients create RSL entries, forge performs pre-receive
verification, users update references directly.
In this configuration, users push directly to the Git references (e.g., the
branch they update and the RSL with a corresponding entry) and the forge is
integrated to perform gittuf verification at the pre-receive phase of a push.
**Pros:**
* The forge can reject pushes that fail verification, offering better
protections to Git-only clients.
**Cons:**
* The forge can carry out denial of service attacks that may or may not be
immediately obvious to the pushing actor.
* Client-side RSL entry creation can be a bottleneck for high traffic
repositories.
TODO: Should the pushing gittuf client be investigated for submitting something
that fails verification?
### Configuration B
**Summary:** Clients create RSL entries, forge performs post-receive
verification, users update references directly.
In this configuration, users push directly to the Git references (e.g., the
branch they update and the RSL with a corresponding entry) and the forge is
integrated to perform gittuf verification at the post-receive phase of a push.
**Pros:**
* The forge cannot carry out denial of service attacks beyond the freeze attacks
it can already perform.
* This configuration can be implemented in popular forges using existing
features (e.g., GitHub Actions).
**Cons:**
* The forge cannot prevent unauthorized changes from being pushed, requiring the
recovery workflow to be executed by a gittuf client after the fact.
* Client-side RSL entry creation can be a bottleneck for high traffic
repositories.
TODO: Should the pushing gittuf client be investigated for submitting something
that fails verification?
TODO: Explore making forge capable of carrying out recovery workflow. This needs
to account for race conditions with verification / recovery in high traffic
repositories.
### Configuration C
**Summary:** Forge creates pre-receive RSL entries, forge performs pre-receive
verification, users update references directly.
In this configuration, users push directly to the Git references (e.g., the
branch they update) **without** a corresponding RSL entry. The forge performs
verification at the pre-receive phase (optionally by creating a provisional RSL
entry) and rejects pushes that fail verification. If the verification passes,
the forge makes the change available along with an RSL entry signed by it (if a
provisional RSL entry was created, this can be adopted as the final RSL entry).
**Pros:**
* The forge can reject pushes that fail verification, offering better
protections to Git-only clients.
* Deployments are simpler as client-side tooling requires fewer changes.
**Cons:**
* The forge is trusted far more than in the standard gittuf model, as it can
reorder or drop RSL entries (drops may be prevented by local "receipts",
potentially).
* With only an RSL entry for the push, there is no way to authenticate the
pushing user. If this is attested to by the forge, the forge must be trusted not
to lie.
* A malicious forge can carry out a denial of service attack by falsely claiming
verification failed.
While more trust is placed in the forge (approaching cases where the forge is
trusted solely to enforce security controls), this configuration still requires
the forge to explicitly record its decisions in the repository in a manner that
any gittuf client can verify the forge's honesty.
TODO: Must the forge attest to how it authenticated a user?
TODO: Can clients record some local-only "receipt" of a push that they validate
is in the RSL next time?
TODO: Can the forge still order pushes to handle high-traffic cases? Is a
staging area necessary?
### Configuration D
**Summary:** Forge creates post-receive RSL entries, forge performs post-receive
verification, users update references directly.
In this configuration, users push directly to the Git references (e.g., the
branch they update) **without** a corresponding RSL entry. The forge creates an
RSL entry in the post-receive phase and then performs verification.
**Pros:**
* The forge cannot carry out denial of service attacks beyond the freeze attacks
it can already perform.
* Deployments are simpler as client-side tooling requires fewer changes.
* This configuration can be implemented in popular forges using existing
features (e.g., GitHub Actions).
**Cons:**
* The forge may run into race conditions with creating RSL entries in high
traffic repositories.
* The forge is trusted far more than in the standard gittuf model, as it can
reorder or drop RSL entries (drops may be prevented by local "receipts",
potentially).
* With only an RSL entry for the push, there is no way to authenticate the
pushing user. If this is attested to by the forge, the forge must be trusted not
to lie.
TODO: Must the forge attest to how it authenticated a user?
TODO: Can clients record some local-only "receipt" of a push that they validate
is in the RSL next time?
### Configuration E
**Summary:** Forge creates pre-receive RSL entries, forge performs pre-receive
verification, users push changes to staging references.
In this configuration, users push to special Git references (e.g., a staging
area for the branch they want to update) **without** a corresponding RSL entry.
The forge performs verification at the pre-receive phase (optionally by creating
a provisional RSL entry) and rejects pushes that fail verification. If the
verification passes, the forge makes the change available along with an RSL
entry signed by it (if a provisional RSL entry was created, this can be adopted
as the final RSL entry).
**Pros:**
* The forge can reject pushes that fail verification, offering better
protections to Git-only clients.
* The forge is responsible for ordering pushes at the pre-receive phase,
simplifying RSL entry creation in high traffic repositories.
* Deployments are simpler as client-side tooling requires fewer changes.
**Cons:**
* The forge is trusted far more than in the standard gittuf model, as it can
reorder or drop RSL entries (drops may be prevented by local "receipts",
potentially).
* With only an RSL entry for the push, there is no way to authenticate the
pushing user. If this is attested to by the forge, the forge must be trusted not
to lie.
* A malicious forge can carry out a denial of service attack by falsely claiming
verification failed.
While more trust is placed in the forge (approaching cases where the forge is
trusted solely to enforce security controls), this configuration still requires
the forge to explicitly record its decisions in the repository in a manner that
any gittuf client can verify the forge's honesty.
TODO: Must the forge attest to how it authenticated a user?
TODO: Can clients record some local-only "receipt" of a push that they validate
is in the RSL next time?
TODO: Is this configuration necessary compared to C?
## Backwards Compatibility
TODO: Consider backwards compatibility after one or more configurations are
adopted.
## Security
TODO: Consider the security model of each configuration.
## Prototype Implementation
None yet.
## Changelog
* January 20th, 2025: moved from `/docs/extensions` to `/docs/gaps` as GAP-2
## References
* [Atomic Git Pushes](https://git-scm.com/docs/git-push#Documentation/git-push.txt---no-atomic)
gittuf-0.9.0/docs/gaps/3/ 0000775 0000000 0000000 00000000000 14751501410 0015044 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/gaps/3/README.md 0000664 0000000 0000000 00000012335 14751501410 0016327 0 ustar 00root root 0000000 0000000 # Authentication Evidence Attestations
## Metadata
* **Number:** 3
* **Title:** Authentication Evidence Attestations
* **Implemented:** No
* **Withdrawn/Rejected:** No
* **Sponsors:** Aditya Sirish A Yelgundhalli (adityasaky)
* **Related GAPs:** [GAP-2](/docs/gaps/2/README.md)
* **Last Modified:** January 20, 2025
## Abstract
In certain workflows, it is necessary to authenticate an actor outside of the
context of gittuf. For example, a gittuf user might create an RSL entry on
behalf of a non-gittuf user after authenticating them. gittuf requires evidence
of this authentication to be recorded in the repository using an attestation.
## Specification
### Authentication Evidence Structure
Primarily, this attestation is recorded for pushes that are not accompanied by
RSL reference entries. As such, this attestation workflow focuses on that
scenario. It has the following format:
```
TargetRef string
FromTargetID string
ToTargetID string
PushActor string
EvidenceType string
Evidence object
```
Note that this attestation's schema is a superset of the reference
authorization attestation. While that one allows for detached authorizations
for a reference update, this one is focused on providing evidence for a push.
As such, to identify the push in question, the schema consists of many of the
same fields.
The `PushActor` field identifies the actor performing the push, but did not
create an RSL entry. `EvidenceType` is a string that identifies the type of
evidence gathered. It dictates how `Evidence` must be parsed, as this field is
an opaque object that differs from one evidence type to another.
TODO: `PushActor` has this notion of tracking actors in the policy even if
they're not gittuf users. This is somewhat reasonable as this could just be a
key ID, which is used just with Git. However, we're fast approaching a
separation of actor identifier from their key ID. There's also a TAP for this
that we should look at, and think about how OIDC bits can also connect here.
TODO: Add some example evidence types for common scenarios. Push certificate and
GitHub API result (subset) ought to do the trick to explore verifiable and
unverifiable evidence.
Authentication evidence attestations are stored in a directory called
`authentication-evidence` in the attestations namespace. Each attestation must
have the in-toto predicate type:
`https://gittuf.dev/authentication-evidence/v`.
### Using Authentication Evidence
The authentication evidence can be used to create RSL entries on behalf of other
developers. This mechanism is necessary for adoptions where a subset of
developers do not use gittuf. When they submit changes to the main copy of the
repository, they do not include RSL entries. Therefore, when a change is pushed
to a branch by a non-gittuf user A, a gittuf user B can submit an RSL entry on
their behalf. Additionally, the entry must identify the original user and
include some evidence about why B thinks the change came from A.
The evidence that the change came from A may be of several types, depending on
the context. If user B completely controls the infrastructure hosting that copy
of the repository, the evidence could be the communication of A to B that
submitted the change. For example, if A pushes to B's repository using an SSH
key associated with A, B has reasonable guarantees the change was indeed pushed
by A. Here, B may be another developer managing a "local" copy of the repository
or an online bot used by a self hosted Git server, where the bot can reason
about the communication from A. In cases where this degree of control is
unavailable, for example when using a third party forge such as GitHub, B has no
means to reason directly about A's communication with the remote repository. In
such cases, B may rely on other data to determine the push was from A, such as
the GitHub API for repository activity which logs all pushes after
authenticating the user performing the push.
Note that if A is a Git user who still signs their commits, a commit signature
signed with A's key is not sufficient to say A performed the push. Creating a
commit is distinct from pushing it to a remote repository, and can be performed
by different users. When creating an RSL entry on behalf of another user in
gittuf, the push event (which is captured in the RSL) is more important than the
commit event.
## Motivation
In some repositories, it may not be possible to require all developers to use
gittuf (e.g., open source contexts). In such cases, it's necessary to enable
gittuf-enabled clients or systems to record the activity of Git-only users.
## Reasoning
TODO: flesh this out once there are two types of evidence, verifiable and
unverifiable.
## Backwards Compatibility
This GAP does not impact the backwards compatibility of gittuf.
## Security
The changes proposed in this GAP requires trusting the actor creating the
attestation. This may be mitigated by having the evidence be independently
verifiable (e.g., a Git push certificate from the original push actor).
TODO: flesh this out with specific evidence types.
## Changelog
* January 20th, 2025: moved from `/docs/extensions` to `/docs/gaps` as GAP-3
## References
* [Git signed push certificate](https://git-scm.com/docs/git-push#Documentation/git-push.txt---signedtruefalseif-asked)
gittuf-0.9.0/docs/gaps/4/ 0000775 0000000 0000000 00000000000 14751501410 0015045 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/gaps/4/README.md 0000664 0000000 0000000 00000030720 14751501410 0016326 0 ustar 00root root 0000000 0000000 # Supporting Global Constraints in gittuf
## Metadata
* **Number:** 4
* **Title:** Supporting Global Constraints in gittuf
* **Implemented:** No
* **Withdrawn/Rejected:** No
* **Sponsors:** Aditya Sirish A Yelgundhalli (adityasaky), Patrick Zielinski (patzielinski)
* **Last Modified:** January 21, 2025
## Abstract
gittuf implements the "delegation" mechanism for specifying the actors trusted
to make changes to repository namespaces. These mechanisms cannot be used by
repository owners to set baseline security controls or controls that are not
typical delegations of trust. This GAP introduces "global constraints", declared
in a repository's root of trust, to address this shortcoming.
## Specification
This GAP introduces the notion of "global constraints" (also referred to as
"global rules").
### Declaring Global Constraints
Global constraints are declared by the repository's owners in the root of trust
metadata. Unlike the delegations implemented in gittuf today, global constraints
can be of distinct types, with each type indicating how it is verified by a
gittuf client. As with any changes to root of trust metadata, adding, removing,
or updating a global constraint requires approval from a threshold of repository
owners.
### Verifying Global Constraints
The gittuf verification workflow is extended to include the verification of all
applicable global constraints after the standard workflow protecting the
namespace being verified. The workflow used to verify a specific constraint
depends on its type, and is discussed below alongside the proposed constraint
types.
### Global Constraint Schema
Each global rule MUST have a name. This name MUST be unique among other global
rules (irrespective of type), though the implementation may determine if the
name must also be unique among all delegation names as well.
Depending on the type of the global rule, additional information may be
necessary. The extension defers the specific schema of global rules to the
implementation, as different policy metadata versions may require different
schemas.
### Global Constraint Types
This extension builds on the motivating examples and proposes two types of
constraints. In time, more types may be added and these MUST be recorded in this
extension document.
#### Minimum Threshold
Another common security control is the ability to require a minimum threshold of
approvals for changes to some namespace, without also specifying the specific
actors trusted for these approvals. Thus, the `threshold` global constraint
requires one or more patterns that identify the namespaces protected by the
constraint as well as a numeric threshold value.
The `threshold` constraint is verified against the set of accepted actors
identified by the standard verification workflow. Consider a delegation that
protects the `main` branch requiring two of Alice, Bob, and Carol to approve
changes. The successful termination of the standard verification workflow
requires two signatures to be verified, and the workflow returns the
corresponding two actors. The global constraint is then verified against this
returned set to see if the number of verified actors meets the global
constraint's threshold.
Depending on the existence and configuration of delegations protecting the same
namespace as a global constraint, several situations are possible.
##### Delegation(s) exist and they all require a threshold equal to or higher than the global constraint
In this scenario, there may be multiple delegations (at multiple levels) all
protecting the same namespace as a threshold global constraint. If all
delegations have a threshold equal to or higher than that declared in the global
constraint, then the global constraint will always be satisfied. This is similar
to the scenario described above.
##### Delegation(s) exist and only some require a threshold equal to or higher than the global constraint
There may be multiple delegations (at multiple levels) of which only some
require a threshold equal to of greater than that of the global constraint.
Consider for example that the primary rule file requires two of Alice, Bob, and
Carol to approve changes to the namespace. In turn, a threshold of Alice, Bob,
and Carol delegate trust for this namespace to Dana and Erin, but require only a
threshold of one.
In this scenario, when the standard verification workflow successfully verifies
signatures against the Alice, Bob, and Carol delegation (i.e., two of the three
have approved the changes), then the global constraint is met as well. However,
if only one of Dana and Erin issue a signature, while this satisfies the
standard verification workflow, this does not satisfy the global constraint.
TODO: what if both Dana and Erin sign despite only one needing to? Should we
verify exhaustively and return both, thus meeting the global constraint?
##### Delegations do not exist but a threshold global constraint is set
When no delegations exist protecting a namespace, the standard verification
workflow terminates without verifying any signatures. This extension proposes a
special case for this scenario where no delegations exist but a global
constraint does. Specifically, all actors' keys declared across all metadata are
used to verify the signatures associated with the change (RSL entry signature,
reference authorizations, other attestations as applicable). The assumption here
is that any actor declared in the metadata is trusted to make write changes to a
namespace that is not protected by any explicit delegations. This may be updated
in a future version of gittuf policy metadata that allows declaring granular
permissions on a per-actor basis.
#### Prevent Force Pushes
A force push results in the history of the branch being rewritten. Thus, the
`prevent-force-pushes` global constraint prevents rewriting history for the
specific Git references. As such, this contraint requires one or more patterns
that identify the repository references protected by the constraint.
This constraint type is verified for every entry for a reference protected by
the constraint. When verifying an RSL reference entry, the previous unskipped
RSL reference entry for the same reference is identified. To meet this
constraint, the verification workflow determines if the current RSL reference
entry's target commit is a descendent of the previous RSL reference entry's
target commit. If yes, then the constraint is met. If not, then verification
terminates with an error indicating the rule that was not met.
### Example
The following snippet shows the declaration of both types of rules in a
repository's root of trust metadata.
TODO: add example snippet and explanation.
## Motivation
gittuf currently supports explicitly granting write permission to a namespace to
a specific set of actors as well as a threshold that identifies the number of
actors that must agree to a change to that namespace. This extension of trust
uses the concept of "delegation", and a set of actors granted some trust can
choose to delegate this further to other actors.
This mechanism does not support setting generic controls over changes in the
repository, such as to enforce a baseline security posture _irrespective of the
configuration of specific delegations controlling who can make changes to a
namespace_. This GAP considers some motivating scenarios that influence the
design of global constraints. These are not exhaustive and may be expanded at a
later date.
### Minimum Threshold
Organizations frequently look to require a minimum number of approvers for
source code changes, irrespective of the specific actors who are trusted as
approvers for some repository namespace, which can be declared using standard
rules / delegations. For example, a large monorepo may include several levels of
delegations determining which actors are trusted for which subprojects. The
repository owners wish to set a minimum threshold of two for all changes to a
namespace irrespective of the specific subprojects or the actors trusted,
leaving that to the more specific delegations. To achieve this in gittuf without
global constraints, the owners must ensure every delegation that matches the
namespace has a threshold of at least two, which is impractical.
### Prevent Force Pushes
A repository's owners may choose (perhaps to conform with the upcoming SLSA
source track that requires this constraint) to block force pushes to some
branches, thus preventing alterations of their histories. This ensures
continuity of important repository branches meant for downstream consumption.
There is currently no way to enforce such a rule using gittuf's delegations;
indeed, this constraint isn't a delegation of trust at all, but rather a
specific property that must be enforced for repository changes.
### Specify Merge Strategies
A repository's owners may choose to enforce specific merge strategies (e.g.,
always create a merge commit, merge using a squashed commit that applies a
change atomically, etc.).
### Require Execution of Additional Checks
A repository's owners may require additional source code checks to be executed
prior to some change being merged. For example, a repository may require its
unit tests to be executed for every change, and expect all checks to pass for
the change to be merged. Another example is the execution of linters and secrets
scanners that enforce source code quality and hygiene.
## Reasoning
The GAP introduces the generic notion of "global constraints" that can be
extended to support a variety of repository-wide security controls.
### Limiting to Root of Trust
Global constraints must be declared in a repository's root of trust as they are
repository-wide constraints, and not specific to any one rule file. In the
future, there may be a preference to move (or otherwise support) this in the
primary rule file, for repositories where there is a strict separation between
what the root of trust and primary rule file metadata are used for. This is
currently not part of the GAP so as to keep rule file schemas consistent across
primary and delegated rule files.
### Supporting Types of Global Constraints
This GAP introduces the notion of global constraints and does not further group
specific constraint types together based on any shared characteristics. This is
because, ultimately, each security control that is supported via a global
constraint type is likely to have a unique verification workflow that must be
added to the implementation. Over time, the implementation (and this GAP) may
evolve in a way where different constraint types that share verification
characteristics are grouped together.
### Alternative Solution: User Programmable Checks
Supporting types of global constraints in gittuf may not be preferable due to
maintainability concerns. Additionally, changes in semantics of a named
constraint type can cause inconsistencies in verification. An alternative
approach may be to introduce a generic programmable layer into gittuf. In such a
model, global constraints would be expressed as small check programs executed in
a pre-determined environment built into gittuf.
TODO: connect this with gittuf + lua / hooks work
## Backwards Compatibility
This GAP impacts backwards compatibility in certain cases. If a repository's
metadata does not declare global constraints, any version of gittuf (with or
without support for global constraints) can be used for verification. If a
repository's metadata declares global constraints, then a version of gittuf
released prior to the addition of this feature will ignore the global rules
altogether. Additionally, even a gittuf client with knowledge of the concept of
global constraints may not support a specific type of constraint. In such
scenarios, the client is unable to verify the unsupported global constraint(s),
and must abort verification with a message to the user to update their gittuf
client.
## Security
Adding more mechanisms or types of rules to gittuf does not inherently pose a
security threat. The concerns with security relate to incompatibility of
clients, similar to those discussed in the backwards compatibility section.
Essentially, support for global constraints must be added in a manner such that
an older client can:
* abort verification with a warning when it encounters an unrecognized global
constraint type
* preserve global constraints when making changes to the repository's root of
trust metadata, even if the client entirely lacks support for global constraints
## Prototype Implementation
Initial support for global constraints has been implemented as a gittuf
developer mode feature.
## References
* [SLSA Source Track Draft](https://slsa.dev/spec/draft/source-requirements)
gittuf-0.9.0/docs/gaps/README.md 0000664 0000000 0000000 00000023105 14751501410 0016162 0 ustar 00root root 0000000 0000000 # gittuf Augmentation Proposals (GAPs)
A gittuf Augmentation Proposal (GAP) is a design document that describes new
features, extensions, or changes to the gittuf design document. A GAP is a
**living document** that provides a concise technical specification of the
feature, describes the motivation for the change, and discusses the rationale
behind the design.
gittuf is an implementation-first project, unlike sister projects like in-toto
and TUF that are primarily specification projects. However, gittuf's
implementation includes a design document that describes how different aspects
of gittuf work (e.g., communication with forges, verification and recovery
workflows, etc.). The design document ensures gittuf's core features are
developed in a reasoned manner, which is especially important as gittuf is a
security project. GAPs ensure that changes to gittuf's design are similarly
developed in a reasoned manner with input from gittuf maintainers and community
members alike.
**Note:** A GAP cannot be used to propose changes to gittuf community processes,
structure, or governance. Process-related changes must instead be proposed to
the gittuf/community repository.
## GAP Format
All GAPs must have the following sections to be merged into the gittuf
repository. A template of this document is available alongside this document.
1. **Metadata:** A list at the very top of a GAP that contains the GAP's number,
title, implemented status, withdrawn/rejected status, sponsors, contributors,
related GAPs and the date it was last modified.
1. **Abstract:** A short description of the GAP.
1. **Specification:** The technical specification of the proposed changes or
additions to the gittuf design.
1. **Motivation:** A description of the motivation for the proposed changes. The
motivation may precede the specification section in cases the context it
provides is important to reason about the specification.
1. **Reasoning:** A discussion of the reasoning behind specific design or
architectural decisions proposed in the specification. The sponsors should also
try and include summaries of discussions from the community related to these
decisions (perhaps raised on the pull request proposing the GAP or in
synchronous discussions in gittuf community meetings).
1. **Backwards Compatibility:** A discussion of how the proposed changes impact
the backwards compatibility of gittuf's design and implementation. If a GAP does
not break backwards compatibility, that must be stated explicitly.
1. **Security:** As gittuf is fundamentally a security project, any changes to
gittuf's design must be considered carefully with respect to how it changes the
security model of the project. Each GAP must discuss the security impact of the
proposed changes, potential issues that may arise as a consequence of the
proposed changes, their mitigations, and any implementation-specific footguns
developers must be mindful of.
1. **Changelog:** Every time a change to a GAP is **merged** into the
repository, an entry must be added to this section with a brief summary of the
changes and the date they were made. This section may be omitted for the very
first iteration of a GAP.
1. **References:** A list of references that include links to discussions
pertaining to the GAP as well as any external links relevant to the proposed
changes.
A GAP document may also include the following optional sections.
1. **Acknowledgements:** Any relevant acknowledgements to people (who are not
sponsors or contributors of the GAP) or projects (that in some way inspired the
GAP).
An **unimplemented** GAP may also include the following sections. These are
optional.
1. **Prototype Implementation:** A description or link to a prototype of the
proposed changes.
When a GAP is implemented, the document must be updated to reflect this in the
metadata section. Additionally, the following sections must be added to the
document.
1. **Implementation:** A description of how the GAP was implemented in gittuf.
If a prototype implementation was accepted as the final implementation, this
section may indicate as such and refer to the prototype implementation section.
If the features proposed in an implemented GAP are later removed, the GAP must
be updated to reflect this in the document's metadata section. The GAP's
reasoning must also be updated to indicate why the feature was removed.
## GAP Responsibilities
The participants in a GAP have specific responsibilities.
### Sponsor
Every GAP must have at least one sponsor. There is no limit to the number of
sponsors a GAP may have. Each sponsor must be listed in the GAP's metadata
section. The sponsors are the original proposers of a GAP and take on the
responsibility of authoring the document and submitting it for review by the
gittuf maintainers. Additionally, the sponsors should update the GAP based on
feedback or changes to the corresponding implementations, thus ensuring the
document reflects the latest status of the proposed changes.
### Contributor
A GAP may have one or more contributors. These are members of the community who
contribute to the GAP but do not wish to sponsor it. Each contributor must be
listed in the GAP's metadata section.
### gittuf Maintainers
Ultimately, the gittuf maintainers are responsible for overseeing GAPs and
keeping them updated. The responsibilities of the gittuf maintainers include
(but are not limited to):
* Engaging in discussions of problems to determine if a GAP is necessary
* Reviewing and providing feedback on a GAP in a timely manner with a focus on
the impact of the proposed changes on gittuf's security model
* Ensuring the GAP follows the prescribed format
* Updating merged GAPs (if the sponsors do not) to reflect the state of their
implementation; for example, if a GAP is implemented, if an implemented GAP
feature is removed, or a GAP feature is updated significantly, the maintainers
must ensure this is reflected in the living GAP document
Changes to GAP documents are subject to approval from the same threshold of
gittuf maintainers as all implementation changes. That is, if the implementation
requires two maintainers to approve some change, the same threshold applies to
changes to GAPs.
## GAP Workflow
A GAP may go through the following phases in its evolution from problem to
implemented solution.
### Discuss the problem
A GAP solves specific problems that the gittuf design currently does not. Rather
than directly approach the community with a GAP, it is a good idea to discuss
with the maintainers and the broader community the problem itself. This can help
confirm that the problem in fact exists (instead of being a misunderstanding of
the gittuf design), has not already been explored in a previous GAP, and a
solution ought to be part of gittuf (rather than another complementary system).
This discussion may happen in any forum used by the gittuf community, though the
repository's issue tracker is recommended for maximum visibility.
### Propose the GAP
After the maintainers agree that a GAP is required, one or more sponsors can
author a draft of the GAP. To submit a GAP, one of the sponsors must open a pull
request with the document to the gittuf repository. The GAP must follow the
format specified in this document (or copy the template provided alongside this
document), minus the number as that is assigned when the document is merged.
### Merging a proposed GAP
All proposed GAPs must be merged into the repository in a timely manner,
regardless of their implementation status. This increases the visibility of each
GAP, thus making it easier for other interested parties to discover the GAP,
propose further changes, and contribute to the implementation of the GAP.
The sponsors of a GAP may choose to withdraw their proposal or the maintainers
may choose to reject the proposed changes after assessing the GAP. Even in these
cases, the document must be merged into the repository with the status indicated
in the document's metadata section. Note that a GAP must only be withdrawn or
rejected on the basis of technical reasons (e.g., a better solution is proposed
or a security issue is discovered as a consequence of the proposal). The
reasoning section of the GAP must capture these technical considerations.
### Implementing a GAP
The changes proposed in a GAP may be implemented via patches to the gittuf
implementation. The changes to the implementation need not be submitted by the
sponsors of the GAP. When the gittuf maintainers think a GAP has been
implemented, they can propose an update to the document reflecting this. The
sponsors of a GAP may also propose marking a GAP as implemented, which is
subject to approval from the gittuf maintainers.
### Removing a GAP's implementation
After a GAP is implemented, the corresponding changes or feature additions may
be reverted (e.g., the feature leads to repeated security issues while being
used rarely or gittuf's design as a whole evolves in a way that makes the GAP
redundant). In such scenarios, the GAP must be updated to indicate this change.
In addition to the corresponding changes to the metadata section, other sections
such as the reasoning, implementation, backwards compatibility, and changelog
must also be updated.
## Acknowledgements
The GAP format and process in inspired by similar mechanisms in the in-toto
(in-toto Enhancements) and TUF (TUF Augmentation Proposals) communities.
## References
* [gittuf Design Document](/docs/design-document.md)
* [gittuf Maintainers](/MAINTAINERS.txt)
* [gittuf/community](https://github.com/gittuf/community)
* [GAP Template](/docs/gaps/template.md)
* [in-toto Enhancements (ITE)](https://github.com/in-toto/ite)
* [TUF Augmentation Proposals (TAPs)](https://github.com/theupdateframework/taps)
gittuf-0.9.0/docs/gaps/template.md 0000664 0000000 0000000 00000000702 14751501410 0017036 0 ustar 00root root 0000000 0000000 # GAP Template (update with title of GAP)
## Metadata
* **Number:**
* **Title:** GAP Template (update with title of GAP)
* **Implemented:** No
* **Withdrawn/Rejected:** No
* **Sponsors:**
* **Contributors:**
* **Related GAPs:**
* **Last Modified:**
## Abstract
## Specification
## Motivation
## Reasoning
## Backwards Compatibility
## Security
## Prototype Implementation
## Implementation
## Changelog
## Acknowledgements
## References
gittuf-0.9.0/docs/get-started.md 0000664 0000000 0000000 00000017552 14751501410 0016527 0 ustar 00root root 0000000 0000000 # Get Started
This guide presents a quick primer to using gittuf. Note that gittuf is
currently in alpha, and it is not intended for use in a production repository.
## Install gittuf using pre-built binaries
> [!NOTE]
> Please use release v0.1.0 or higher, as prior releases were created to
> test the release workflow.
This repository provides pre-built binaries that are signed and published using
[GoReleaser]. The signature for these binaries are generated using [Sigstore],
using the release workflow's identity. Make sure you have [cosign] installed on
your system, then you will be able to securely download and verify the gittuf
release:
### Unix-like operating systems
```sh
# Modify these values as necessary.
# One of: amd64, arm64
ARCH=amd64
# One of: linux, darwin, freebsd
OS=linux
# See https://github.com/gittuf/gittuf/releases for the latest version
VERSION=0.8.0
cd $(mktemp -d)
curl -LO https://github.com/gittuf/gittuf/releases/download/v${VERSION}/gittuf_${VERSION}_${OS}_${ARCH}
curl -LO https://github.com/gittuf/gittuf/releases/download/v${VERSION}/gittuf_${VERSION}_${OS}_${ARCH}.sig
curl -LO https://github.com/gittuf/gittuf/releases/download/v${VERSION}/gittuf_${VERSION}_${OS}_${ARCH}.pem
cosign verify-blob \
--certificate gittuf_${VERSION}_${OS}_${ARCH}.pem \
--signature gittuf_${VERSION}_${OS}_${ARCH}.sig \
--certificate-identity https://github.com/gittuf/gittuf/.github/workflows/release.yml@refs/tags/v${VERSION} \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
gittuf_${VERSION}_${OS}_${ARCH}
sudo install gittuf_${VERSION}_${OS}_${ARCH} /usr/local/bin/gittuf
cd -
gittuf version
```
### Windows
#### Winget
gittuf can be installed on Windows from winget, provided winget is installed
on the system:
```powershell
winget install gittuf
```
#### Manual installation
Copy and paste these commands in PowerShell to install gittuf. Please remember
to change the version number (0.8.0 in this example) and architecture
(amd64 in this example) according to your use-case and system.
```powershell
curl "https://github.com/gittuf/gittuf/releases/download/v0.8.0/gittuf_0.8.0_windows_amd64.exe" -O "gittuf_0.8.0_windows_amd64.exe"
curl "https://github.com/gittuf/gittuf/releases/download/v0.8.0/gittuf_0.8.0_windows_amd64.exe.sig" -O "gittuf_0.8.0_windows_amd64.exe.sig"
curl "https://github.com/gittuf/gittuf/releases/download/v0.8.0/gittuf_0.8.0_windows_amd64.exe.pem" -O "gittuf_0.8.0_windows_amd64.exe.pem"
cosign verify-blob --certificate gittuf_0.8.0_windows_amd64.exe.pem --signature gittuf_0.8.0_windows_amd64.exe.sig --certificate-identity https://github.com/gittuf/gittuf/.github/workflows/release.yml@refs/tags/v0.8.0 --certificate-oidc-issuer https://token.actions.githubusercontent.com gittuf_0.8.0_windows_amd64.exe
```
The gittuf binary is now verified on your system. You can run it from the terminal
as `gittuf.exe` from this directory, or add it to your PATH as desired.
## Building from source
> [!NOTE]
> `make` needs to be installed manually on Windows as it is not packaged with
> the OS. The easiest way to install `make` on Windows is to use the
> `ezwinports.make` package: Simply type `winget install ezwinports.make`
> in PowerShell.
> You can also install it from the [GNU website] or the [chocolatey] package manager.
To build from source, clone the repository and run
`make`. This will also run the test suite prior to installing gittuf. Note that
Go 1.23 or higher is necessary to build gittuf.
```sh
git clone https://github.com/gittuf/gittuf
cd gittuf
make
```
This will automatically put `gittuf` in the `GOPATH` as configured.
## Create keys
First, create some keys that are used for the gittuf root of trust, policies, as
well as for commits created while following this guide.
> [!NOTE]
> If running on Windows, do not use the `-N ""` flag in the `ssh-keygen` commands.
> Instead, enter an empty passphrase when prompted.
```bash
mkdir gittuf-get-started && cd gittuf-get-started
mkdir keys && cd keys
ssh-keygen -q -t ecdsa -N "" -f root
ssh-keygen -q -t ecdsa -N "" -f policy
ssh-keygen -q -t ecdsa -N "" -f developer
```
## Create a Git repository
gittuf can be used with either a brand new repository or with an existing
repository. Here, we assume gittuf is being deployed with a fresh repository.
Initialize the repository and gittuf's root of trust metadata using the
key.
```bash
cd .. && mkdir repo && cd repo
git init -q -b main
git config --local gpg.format ssh
git config --local user.signingkey ../keys/developer
```
## Initialize gittuf
Initialize gittuf's root of trust metadata.
```bash
gittuf trust init -k ../keys/root
```
After that, add a key for the primary policy. gittuf allows users to specify
rules in one or more policy files. The primary policy file (called `targets`,
from TUF) must be signed by keys specified in the root of trust.
```bash
gittuf trust add-policy-key -k ../keys/root --policy-key ../keys/policy.pub
gittuf policy init -k ../keys/policy --policy-name targets
```
Then, use the policy key to initialize a policy and add a rule protecting the
`main` branch.
```bash
gittuf policy add-key -k ../keys/policy --public-key ../keys/developer.pub
gittuf policy add-rule -k ../keys/policy --rule-name protect-main --rule-pattern git:refs/heads/main --authorize-key ../keys/developer.pub
```
Note that `add-key` can also be used to specify a GPG key or a [Sigstore]
identity for use with [gitsign]. However, we're using SSH keys throughout in
this guide, as gittuf policy metadata currently cannot be signed using GPG (see
[#229]). Also, `--authorize-key` in `gittuf policy add-rule` may return a
deprecation warning. This guide will be updated with the new `--authorize` flag
in its place.
After adding the required policies, _apply_ them from the policy-staging area.
This means the policy will be applicable henceforth.
```bash
gittuf policy apply
```
## Making repository changes
You can make changes in the repository using standard Git workflows. However,
changes to Git references (i.e., branches and tags) must be recorded in gittuf's
reference state log (RSL). Currently, this must be executed manually or using a
pre-push hook (see `gittuf add-hook -h` for more information about adding the
hook and [#220] for planned gittuf and Git command compatibility).
```bash
echo "Hello, world!" > README.md
git add . && git commit -q -S -m "Initial commit"
gittuf rsl record main
```
## Verifying policy
gittuf allows for verifying rules for Git references and files.
```sh
gittuf verify-ref --verbose main
```
## Communicating with a remote
gittuf includes helpers to push and fetch the policy and RSL references.
However, there are some known issues (see [#328]) with these commands. In the
meantime, Git can be used to keep gittuf's references updated.
```sh
git push refs/gittuf/*
git fetch refs/gittuf/*:refs/gittuf/*
```
## Verify gittuf itself
You can also verify the state of the gittuf source code repository with gittuf
itself. For more information on verifying gittuf with gittuf, visit the
[dogfooding] document.
## Conclusion
This is a very quick primer to gittuf! Please take a look at gittuf's [CLI docs]
to learn more about using gittuf. If you find a bug, please [open an issue] on
the gittuf repository.
[Sigstore]: https://www.sigstore.dev/
[cosign]: https://github.com/sigstore/cosign
[gitsign]: https://github.com/sigstore/gitsign
[GoReleaser]: https://goreleaser.com/
[#276]: https://github.com/gittuf/gittuf/issues/276
[#229]: https://github.com/gittuf/gittuf/issues/229
[#220]: https://github.com/gittuf/gittuf/issues/220
[#328]: https://github.com/gittuf/gittuf/issues/328
[CLI docs]: /docs/cli/gittuf.md
[open an issue]: https://github.com/gittuf/gittuf/issues/new/choose
[dogfooding]: /docs/dogfood.md
[GNU website]: https://gnuwin32.sourceforge.net/packages/make.htm
[chocolatey]: https://community.chocolatey.org/packages/make
[official Go guide for Windows]: https://go.dev/wiki/SettingGOPATH#
gittuf-0.9.0/docs/media/ 0000775 0000000 0000000 00000000000 14751501410 0015027 5 ustar 00root root 0000000 0000000 gittuf-0.9.0/docs/media/gittuf-with-legacy-servers.png 0000664 0000000 0000000 00000427572 14751501410 0022762 0 ustar 00root root 0000000 0000000 ‰PNG
IHDR ° à 4¯ã pHYs à ÃÇo¨d tEXtSoftware www.inkscape.org›î< IDATxœìÝwt”eöÀñï3™dÒC$!$„„’Ð{P,(ŠbCEA,(ÜÕ]ËÚÖUl«èú³¡"EDÐÕwUT¤w)Ò!Ògîï‘ )“™îçœçÀ¼ó”û¾3pÎÜó#"(¥”RJ)¥”ò^Æ´úY,tñ÷¡ÃA‚Šìy:>¥”ç«Ç¬†cÆð{^1ë•À|Ùééø\ÅhK)¥”RJ)¥¼“1¦
0Ü߇;
ìDÆ„Ppaü’bi^ßìA~žŽR)åi9…SÛ²„M(Y˜‚ý`6_R
Š™L‘]žŽ³64¥”RJ)¥”R^ÆÓÛfåÙÂ.ëØˆ¢‘íºdhæéÈ”Rg‹mYðÕf˜¸V
wÂ××ÂWEvþ!"ë=[MhK)¥”RJ)¥¼„1&ÆÏ‡;¸áúVØŸìc¬]b<•Rêl÷ó.xá)þyV‹… vOˆÈaOÇUšÀRJ)¥”RJ)/`Œ¹Åjáã¶‘ø~8ÈøuÕÄ•RÊÅ~úFÏ–¢Ôr‹ìÜ""?y:¦ªÒ–RJ)¥”RJy1ÆêëÃ;vw½p‰1õÁXŒ§£RJ«ŠìðØâxk9ÃßívyÞÓ1U…&°”RJ)¥”RÊCŒ1~>|àËeÿ»Íøõnâ鈔Rç‹Y[`È—b·“‹íÜ#"vOÇt:šÀRJ)¥”RJ)0ÆøÙ¬|× €>óî0~-#<‘Rê|³<.Ÿ*ÅùÅÌ(v0\¼8Idñt J)¥”RJ)u¾1Æ_¦ûÑgá(M^)¥<£G,Ìa|>±ZxÙÓñœŽ&°”RJ)¥”RÊýö1Ü8w¸ñK÷t(J©óY—˜5ÄX£ƘÁžŽçT4¥”RJ)¥”RndŒéb1¼úÁ5ÆÚ!ÚÓÑ(¥ôoïgŒ¯“Œ1M=Oe4¥”RJ)¥”RnbŒñ±Y™4¸5fxOG£”RxòBL—|m>¼çéX*£›¸+¥”RJ)¥”›cîôå_;2ÖF!¥×.™êÃÁ_Ϧ”:¿9ŠY>ÊÎŽCÐñ}q8„A"ò?O‡u"«§PJ)¥”RJ©ó1ÆÏæÃߟ¹èäÀ¦ƒ\w3;wö\pJ©óÖž={xýõ×qˆ¡]ÜÓ>ù•— M`)¥”RJ)¥Ôyèv«õîëVñ0dÈ÷G¤”:ï\¹’×_Ýùú±>ÆòájicŒ¹\D~ð`håèXJ)¥”RJ)å¾>>.ŽÔÅD`ùrX¿öíƒÌLjô¡ûúBt44i½{C³f®õáë5…ïvp1ð¹§ãM`)¥”RJ)¥T2Æ_\o\²~077¶“º7ƒ’»+ºt²X,4ŠiHÛv-uißµ%"lߞŽm{8z4×åý‡†Ó¼eZ´ˆÇ¸æ£r™Ã‡²qÃvÒÓàpÔ,iu*V«±qÑ´mׂàà@—ö]kyyðÚk0q"ìÙãúþ»v…‡†Ûn+Íhªr.M0¾óvÉ¥žŽ£Œ&°”RJ)¥”Rªn5*vØ6²öý¶q›~ÛÝîÚ$F‡ÃÁ¾ÔLÒöí§E‹x:vNÆbñüÎ3‡e³lÙz²äÔÙGæ²fÕ&vîØKÏží ¯VgcU•Ãá`íšÍìØ¾©ÉŒ£*()±³{×>öîI§MÛæ´nÓ¼NÆ©¶~€»ï®›ÄU™U«`Ø0øà˜<ên¬³Pë†PXB¼1ÆGD\›-¯ÏÿO¤”RJ)¥”R綃$†×¼aÅòõlX¿Î’W'·mÛnæÿ¼²ÆK]%33‹ys—×iòêDÙGr˜ûÓ2ÒÓ¸e¼S))±óË‚Õlß–RgÉ«ÙíÖ¯ÛÆ²%ëp8ê~¼Óš:®¾ºn“W'Z¸.¸ Ö¬qÏxg‰¤à¬@OÇšÀRJ)¥”RJ©ºÖ Èb¿Zl3´bù~ߙ꺈ªhf‹~Yí–Je²²Ž°ÀI´’;YMVÖ·Ž[FDX¸`éîO¢íÞ½•+6¸}\§¯¾‚# ¸Ø½ãfdÀe—ÁîÝî׋5ücEi„ÃpÒ–RJ)¥”RJÕà _jn}çvî„Q£j¶A»+>7ßEEžßËú‚1à'hK)¥”RJ)¥ê–ÍÏJ~‘—°vÍfWÇSm›~ÛINÎ1·ŽùÛÆí;–ïÖ1OvìX>›~ÛáÖ1ssóØôÛN·ŽY™µk6»?y÷È#íÞ1O¶r%L˜àÙ¼„1àkÁø{:ЖRJ)¥”RJym[w{dÐÉD„͛ܗT)((dÇŽ½nït¶oK!?¿Àmãý¶q‡Ç–lž¨¨¨˜íÛRÜ7௿ÂìÙîïtƃ|Ï&OUEšÀRJ)¥”RJ)/µs‡›6±®‚Ý»Ò()©ÚAd………,X°€¬¬š-ƒÛ½kö*ŽU×ìv)»Óª\çάX±¢Fc•”Ø«5V]«Î÷/77—9sæPTÓåw~è¹¥ƒ'KO‡o¿õtê$VO ”RJ)¥”Rª¢ì#9äå¹oæÏ™823³hÜ8ò”u
Y¶l‹/¦¸¸˜¤¤¤åé O–ž~€äV‰§³sçNæÎKzz:;v¬Ñ8™=¶çWeòò
ÈÎÎ%,,ø”urssY¼x1+W®Än·Ó¯_¿š
6gNÍÚՕᅦoôtêšÀRJ)¥”RJ)/´ÿ!O‡PÁþS$°NL\9ìöšÏž8\›0]îÀþÈƘ
ï•%®222 jµüÏ[?óÊX¹¹¹,Z´ˆU«VÔê3gÏžÒ
ܽÉÏ?{:uM`)¥”RJ)¥”ò¦ÙWeNŽ©¨¨ˆ•+W²`Áìv»KfyÕ,$(}VPPH@À{YïÙ³‡Ÿ~ú‰ÔÔÒÓú\±oÕÙð™çåå±xñbç2ÉZ%®Ê¤zî”ÍSJM-]ÒXIÒRy†&°”RJ)¥”RÊz:„
Êb*K\ýòË/”””œ2áTPP@^^^µÆ8r$申<© ˆ€ ÿ*%®JJJª}ß ÇrÝ{ÒcU”}æ''®JJJ*ŸŸŸ_ý¤Ö¾}øûø`qE2ÌU
áÈ÷t$ê8M`)¥”RJ)¥”²xYJc:pà S¦L!77÷Œõ'Ož\£q¢"›R/¬aÚÖ¥Y³fñ믿ž±ÞÆÙ¸qcµû&®q«š„Vg,Æ’’´iÓ(.>ó‰˜o½õVƹ=>žÄ߯QÛ:ãëëéÔ 4¥”RJ)¥”R^È?Àæé*ð°Ñ°aCî¾ûn.\ÈêÕ«±X,ØíöJgMÝtÓM4hÐ ZcóËü5®Û%ý4h Ì›7œœœSοýö‹å”÷~çwâççW½A6l |Ü8DëBAA|êÍë•ûiK)¥”RJ)¥¼P`P€§C¨ èxL¡¡¡8¾}û²xñbVZ…1¦B"«~ýúDFžúÔÂʈ~~))ñžådV«~~¾chß¾=íÚµcóæÍüðÃ=z´Â2Bÿjß7@Ƈ½.Uö=lÐ ƒæÒK/eáÂ…üúë¯Îäå‰6lˆÍVÍäkÛ¶P…Ù]nÕ´©§#P'±x: ¥”RJ)¥”REGWoæ’;œShh(W^y%cÇŽ¥S§Nc°Zk7OÂC”—Ý{Ttƒr³ËŒ1´nÝš±cÇríµ×†ÅRûŸ×Þvß QQå^‡‡‡3hÐ ÆŒCrr2@íï=*ª4‰åMú÷÷tê$šÀRJ)¥”RJ)/@h˜÷,aòõµÒ aåZ—ÍÈzøá‡‰¬Úhã]û_*c:t`ìØ±4ˆÐÐÐZÝ{ÆáøúzÏB©Ð°`‚ƒ+}¯lFÖý÷ßO«V.Ø·kàÀÚ÷áJW^ééÔI4¥”RJ)¥”R^ªeRSO‡àÔ¼EügÚœ˜ÈêÖ>>>5«iÓÆØlÕÜG©ŽØl~49mY×]wõëׯÑX‹…æ-šÔ¨m]HªÂ÷ïÄDVÛÚÌ¢ºï>¨îÞYu¥uk¸ì2OG¡N¢ ,¥”RJ)¥”òR‰‰±^±–ÕêCr«„*×
媫®¢aÚͤªîxu)¹UÖ*Ί²X,tèо}ûÖb¼D¬Öš%þ\)((€„ÄØ*×oÐ 7Þxcõ÷¿*Ó¤ ÜqGÍںڳς–„*×ÒOD)¥”RJ)¥¼”Åb¡gÏöµ^’W[]º¶qûŒ¨¤äD4¨|É¢»Ô#)Ù½‰4›ÍÎ]Z»uÌ“cèÖ£Köõª–—_†'.¯¾nºÉ³1¨JiK)¥”RJ)¥¼XdTmÛµðØø ‰±Õš‰ã*‹¡WïŽ[Jh³ùÑ»w'÷'q€Äfq$6sÿ3/Ó¶]Ï"Ó§C€‡f6oS§‚‡ÆªršÀRJ)¥”RJ)/צmsÌÊIlK÷íÜ>n™ .íß“ 7/£tŽ{Š
ÌÝ¡[÷vÙ«m»´iÛÜíã:õèóæA7'ÐÚ¶…Ÿ†zõÜ;®ª2M`)¥”RJ)¥ÔY eRSúôíL` åççK×nméÞÃóËCCƒ¹ìòˆ‹‹vËxqqÑ\vù„†zöHc]»µ¥k·¶øùùÖùxþôéÛÙ£³ýœzö„…ᢋê~,‹F†Å‹!Ös³ÞÔ™yÏùœJ)¥”RJ)¥N+6.šèF
Ù¾m7)»Ó8r$Ç¥ýÒ$¾IÉ ^s
@@€Þ};“™™ÅŽm)¤¥Àn·»¬bbÒ¼e?¡ÐSBCƒ½>ÑX'êׇ>}<…ò ÝK)¥”RJ)¥”RJy5M`)¥”RJ)¥”—Ú¾};&L`Ó¦Mž¥VÊîcëÖžÅí¦OŸÎ]wÝÅÝwßÍìÙ³«Ý¾¸¸˜[o½•Ÿ~ú‰ƒ2a–.]Z‘Ö^ZZ&L`õêÕ5¨ˆ!C†ðóÏ?Ÿ¶ÞÂ…™0aGŽ©ñXêì¢ ,¥”RJ)¥”òRË—/gôèÑ,X°ÀÓ¡ÔʲeË=z4‹-òt(n5~üxn»í6>þøc>þøã%"—.]ÊçŸNLL{÷îeôèÑ|ñÅumímÛ¶Ñ£GóÍ7ßԸŋ3cÆ7n|ÚzÓ¦McôèÑdffÖx,uvÑ=°”RJ)¥”RJ©:0kÖ,¬V++V¬ S§N5:9qΜ9ÄÅÅѺukÖ®][Qz—9sæ@Ë–-=Šò2šÀRJ)¥”RJ)¥ê@jj*ÑÑÑtêÔ ŸêŸtøý÷ßsÅW¸:4¯u®Ýozz:sçÎeÑ¢ElÙ²…””²³³°ÙlDGGÓ¢EºvíJ¿~ýèÚµ+‹.–«Œ&°”RJ)¥”Rê,°hÑ"¦L™BNNmÚ´á®»î"::ÚùþÞ½{ùì³Ï¸öÚkÙ¸q#ÿþ÷¿iÙ²%>ø
4Àn·3{ölæÏŸOzz:>>>$''sûí·“˜˜èìgùòåÌŸ?Ÿûî»7òÙgŸ±ÿ~¹ãŽ;HNN®ÛîÝ»™2e
Û¶m#00=z0|øp|}}+Ô]¿~=“&M"55•˜˜†
F×®]+ÔÛ¿?'Ndýúõcèܹ3£F"<¼üéƒEEE|öÙg,[¶ŒC‡ÃÀéß¿¹z³fÍbË–-\{íµ•ÞC™‚‚Þzë-.¸à,ï¿ÿ>
4àþûï§yóæ ìܹ“É“'³mÛ6üüüèӧÇÇß߀5kÖðã?rèÐ!Œ1¼òÊ+ñÀ8ߟ1c{öìÁÏÏîÝ»3lØ0ÂÂÂÊÅ’™™É¯¿þÊO]]*3uêTä‚.cŒÄÅÅIrr²c¤^½z²téRgÝùóç #GŽcŒ È–-[äðáÃÒ½{w$66Vzöì)qqqH@@€,Y²ÄÙÏË/¿,€üùÏcŒDDDHtt´ âçç'óæÍ+ã”)SÄßß_|||¤mÛ¶’˜˜(€têÔIŽ=ê¬Èe—]&V«U¢¢¢$!!AŒ1âãã#Ÿþy¹>çÍ›'aaab±X$))I’’’Ä#QQQ²jÕ*g½cÇŽI§N-ZHÏž=¥^½zÈ=÷ÜS®Ï[n¹E ™9sf¥ÏºLVV– 2dÈ t>Ç/¾øBDD&Ož,~~~bµZ¥}ûö/€$%%ÉîÝ»÷›˜˜(V«U¬V«$&&J=DDdüøñHxx¸ôìÙSZ´h!€4nÜXRRR*|þV«U>,""kÖ¬@z÷î-!!!R¯^=iÞ¼¹XVäÙgŸ-×~óæÍÎøâãã¥]»vbµZ% @¾úê«ru¿ýö[
i×®tíÚU‚ƒƒ^½zIqq±³îŽ;$!!A IHH–-[
—\rI…8^{íµJï766VöîÝ[.†O>ùD|}}%;;ÛymòäÉbµZÅ××W:vì(,ݺus~¿ËlÚ´Iš4i"€4mÚÔy¿2kÖ,g½AƒUh[fàÀbµZeß¾}•AÎ`ÆŒ’ AAArß}÷É’%KÄápT©mzzº¼ùæ›Ò¦M±Ùlòàƒ:?ûº´bÅ
$÷ÉŠÿ?ùùP\)Þð©§Ð¢E‹-Z´hÑ¢E‹–s¹¸"ÈÛo¿í¼>{ölñóó“¦M›Jaa¡ˆü‘À2ÆÈ/¼ ›7o–Ù³g‹ˆÈ_ÿúWäùçŸwþ˜v8ÎdÊM7Ýäì»,ìüÑïp8ä½÷Þ@úõë笻iÓ&ñóó“„„Ù°aƒ³î¸qã±cÇŠÈ ,™4i’Øív™5k–c$99ÙÙgFF†„‡‡KýúõeÑ¢EÎë.”ˆˆ‰•cÇŽ‰ˆ8cz÷Ýwõrrr¤W¯^Èo¿ýæ¼>mÚ4yì±Çdýúõ•>ë2e ,cŒŒ9R6mÚ$_ýµÈÚµkÅ××WZ´h!›6mr¶™9s¦Øl6éÑ£G¹dEÓ¦M%!!Áù://O¥GÎ{y÷Ýw|°\,C‡•.¸Àùº,ÈSO=åüì×['!!!b³Ù$77WDDŠ‹‹¥U«VbµZË}¿¶mÛ&-[¶”ÀÀ@Ù±c‡ˆˆJTT”„‡‡ËÆË=‹Þ½{ ?üðƒóúÅ_,‹E>ùäçµo¾ùFÊ%°rssÅßß_.¸àÉËËsÖ}ûí·‡~¸Üý2D.¼ðBçë]»v‰¿¿¿$$$8“MÅÅÅrï½÷–KЊˆIRR’øúú–KRnÙ²Eš7o.AAA²k×.ùú믧Ÿ~ºÜø™™™bµZ媫®’êJOO—ˆÍf“'žxBÊ8ùÏþ#-[¶”ÈÈÈrÉ·º ,-Z´hÑ¢E‹-Z´hÑâ’Ve?¨Ë~Äýõ×"òG«sçÎê¾öÚkrÛm·IQQQ¹ëEEEbµZ¥W¯^Îke ¬G}´B?!!!ë|ýðà ß~ûm¹z‡CàLÈ”%°†Z¡Ïnݺ‰1ÆÛ?þñd„ ê–%Ü&Nœ(""O=õ” 2cÆŒrõ6lØ _~ù¥ìß¿¿BgR–À
‘üüürï
>\ ùùçŸ+´3fŒ å’n''°ÒÒÒœ3ÑNœÑTRR"“&M’Õ«W;¯Ùív‰ŒŒ”çŸÞy,Õ±cÇ
ã9R Y»vˆˆ|õÕWå’ˆ'úá‡Ê}Æ{÷î•{î¹§\"°Ì„ Ê=ó-[¶ 7ß|s…ºO<ñD¹Öž={+®¸BJJJœõŠ‹‹eÒ¤I²fÍšrÏ ""BÆç¼öÜsÏ•ûŽŸX·yóæåX3gÎtÎ<Ù·ß~+€<öØc"Rú½ŒŒ”fÍš•K8¾ùæ›åfÛUÕâÅ‹%**Jºwï.[·nVÛÓ)((¿ýíoâãã#ùË_ª<“«ºÎ––RJ)¥”R^nÐ A®]uÕU¼ÿþû,]º”ë®»Îy½W¯^ê>úè£Î¿±cǶnÝÊâÅ‹Ž;V¡Meûÿ4mÚ”””çëŋзoßrõŒ1|÷ÝwÚwï޽µ¸¸8V®\INNõë×gáÂ… øúúòÓO?•«[¶§ÖâÅ‹9r$`ܸq:”iÓ¦1pà@®¹æÚ¶mKÛ¶m+ŒU;vtîiUfáÂ…øøøPPPP!¶²ý«/^LïÞ½+í³lC÷Ÿ~ú‰öíÛsýõ×sÍ5×н{wFŒQ®îÚµkÙ¿¥šwëÖµ²=žŽ=êŒ <<¼B¬………cœŸ_ll,|ðóýC‡±mÛ6Ö¯_ÏçŸàüŽ,Y²€.¸ B—^z)/½ô’óull,íÛ·gΜ9tèÐë®»î”÷»jÕ*²²²ÊÝoY|'åããÃE]ÄŽ;œ×Êî·^½zî·¸¸¸\¾¾¾6Œ7ÞxƒåË—Ó³gO >ýôS"""¸æšk*ÜÛ©|÷Ýw<˜áÇóÖ[or°š°Ùl¼ðÂôë×Áƒ“––ÆäÉ“ktÀ¹@XJ)¥”RJ)ååbcc+\kܸ1 YYYå®GDDT¨[RRÂûï¿Ï„ ؼy3%%% 4oÞ¼l–X‘‘‘®Ùl6‡óõþýû
%88¸J÷TáZÙ‰keqdff0räÈSö³ÿ~ z÷îÍÔ©Syþùç™={6³gÏæ¾ûî£{÷îÜÿý6¬JqU¦²ç˜™™‰ÝnçÊ+¯