githubapp

package
v0.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package githubapp turns a GitHub App's private key into short-lived installation tokens.

**Why this exists.** A personal access token in a Secret is long-lived, broadly scoped, and rotated by whoever remembers. An installation token is scoped to the installation and expires in an hour, which is the difference between a leaked credential being an incident and being a nuisance. For a tool whose pitch is that promotion should be evidence-gated rather than merge-rights-gated, holding a permanent write credential to every fleet repository is the weakest part of the threat model (#118).

An installation token works both as an API token and as a git password, so one source feeds the provider APIs and the git steps that push. Two credential paths would defeat the point.

Index

Constants

View Source
const (
	KeyAppID          = "appID"
	KeyClientID       = "clientID"
	KeyInstallationID = "installationID"
	KeyPrivateKey     = "privateKey"
)

Secret keys a GitHub App credential is read from. Deliberately not `token`: a Secret carrying these is not interchangeable with one carrying a PAT, and a key that silently meant something else would be worse than a missing one.

Variables

This section is empty.

Functions

func HasAppKeys

func HasAppKeys(data map[string][]byte) bool

HasAppKeys reports whether a Secret looks like a GitHub App credential rather than a static token.

Types

type Credentials

type Credentials struct {
	// Issuer is the App's client ID, or its numeric app ID. GitHub recommends
	// the client ID and accepts both.
	Issuer string
	// InstallationID identifies which installation to mint a token for. An App
	// installed on two organisations has two, and they are not interchangeable.
	InstallationID string
	// PrivateKey is the App's PEM-encoded RSA key.
	PrivateKey []byte
	// BaseURL is the API root, for GitHub Enterprise Server. Empty is
	// api.github.com.
	BaseURL string
}

Credentials are what a GitHub App needs to mint installation tokens.

func FromSecret

func FromSecret(data map[string][]byte, baseURL string) (Credentials, error)

FromSecret reads credentials from a Secret's data.

type Source

type Source struct {
	// contains filtered or unexported fields
}

Source hands out a currently-valid installation token, minting and caching as needed.

Safe for concurrent use: several steps in one Passage can ask at once, and each mint is an API call worth not making twice.

func New

func New(creds Credentials, client *http.Client) (*Source, error)

New builds a Source. It does not contact GitHub; the first Token call does.

func SourceFor

func SourceFor(creds Credentials) (*Source, error)

SourceFor returns a shared Source for a credential, minting the hourly token once however many callers ask.

Package-level because the callers are deliberately independent: a Passage's git steps and its provider steps each resolve credentials on their own, and a cache per caller would mint a token per step against a rate limit shared with everything else the App does.

Keyed by the credential's content rather than by Secret name: rotating the key must produce a new Source, and two namespaces with the same Secret name must not share one.

func (*Source) Token

func (s *Source) Token(ctx context.Context) (string, error)

Token returns a valid installation token, minting one if the cached token is missing or close to expiry.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL