githubtokens

package
v1.76.0-rc.3 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package githubtokens is how another module asks the GitHub module for an installation token (docs/decisions/0071): a Minter port, the in-process implementation that holds the App's key and talks to GitHub, and the modcall pair (Register, Client) that carries the same call as the `github` module's `mint_installation` method.

The split is the decision and the credential. The issuer decides which grant a request is minted under and what it is narrowed to; whoever implements the Minter holds the App's private key, signs for it and calls GitHub. Until the GitHub module has a function of its own, the issuer's process holds the InProcess minter and nothing crosses a boundary; the pair is the seam the split will use, exercised today over modcall.Local.

Index

Constants

View Source
const (
	Module                 = "github"
	MethodMintInstallation = "mint_installation"
)

Module is the module that answers, and MethodMintInstallation its method.

View Source
const CallerIssuer = "issuer"

CallerIssuer is the one caller class that may ask for an installation token: the issuer decides the grant, and no other module has a reason to hold one.

Variables

View Source
var (
	// ErrUnavailable is an App that cannot mint: not created, not installed,
	// or uninstalled on GitHub since.
	ErrUnavailable = errors.New("that GitHub App cannot mint a token")
	// ErrScope is a narrowing wider than the installation: a repository the
	// installer did not select, or a permission they have not accepted.
	ErrScope = errors.New("the request is wider than any grant this proof holds")
	// ErrUpstream is GitHub failing, or the App's key failing.
	ErrUpstream = errors.New("GitHub did not mint the token")
)

The refusals minting ends in. They are the issuer's (`invalid_target`, `invalid_scope`, `server_error`) and survive the module boundary by code.

Functions

func Register

func Register(s *modcall.Server, m Minter)

Register makes m answer the module's method on s.

Types

type AppStore

type AppStore interface {
	Get(ctx context.Context, id string) (catalogueapp.Record, string, bool, error)
}

AppStore is where a created App's record and key are kept.

type Client

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

Client is a Minter in another module.

func NewClient

func NewClient(c modcall.Caller) *Client

NewClient calls the GitHub module through c.

func (*Client) MintInstallation

func (c *Client) MintInstallation(ctx context.Context, r Request) (Minted, error)

MintInstallation implements Minter.

type InProcess

type InProcess struct {
	// Store is nil where the deployment keeps no catalogue Apps; every
	// request is then refused as naming an App that cannot mint.
	Store AppStore
	// HTTP reaches GitHub. Nil uses a client with a thirty-second timeout.
	HTTP *http.Client
	// Now is the clock the App's JWT is signed against. Nil is time.Now.
	Now func() time.Time
}

InProcess is the Minter that holds the keys: it reads the App, signs its JWT and calls GitHub.

func (InProcess) MintInstallation

func (m InProcess) MintInstallation(ctx context.Context, r Request) (Minted, error)

MintInstallation implements Minter.

type Minted

type Minted struct {
	Token     string    `json:"token"`
	ExpiresAt time.Time `json:"expires_at"`
	// Repositories and Permissions are what was granted, not what was asked.
	Repositories []string          `json:"repositories,omitempty"`
	Permissions  map[string]string `json:"permissions,omitempty"`
	// Installation is the GitHub installation it was minted in, for the trail.
	Installation int64 `json:"installation,omitempty"`
}

Minted is an installation token and what GitHub says it carries. It holds the secret; nothing logs it.

func (Minted) Granted

func (m Minted) Granted() githubapp.MintedToken

Granted is the part GitHub minted, as the GitHub client spells it.

type Minter

type Minter interface {
	// MintInstallation mints for the request. The error wraps [ErrUnavailable],
	// [ErrScope] or [ErrUpstream].
	MintInstallation(ctx context.Context, r Request) (Minted, error)
}

Minter asks GitHub for an installation token.

type Request

type Request struct {
	// App is the catalogue id, without the `github-app:` prefix.
	App string `json:"app"`
	// Repositories are names within the installation's account; empty narrows
	// to none.
	Repositories []string `json:"repositories,omitempty"`
	// Permissions are name to level; empty narrows to none.
	Permissions map[string]string `json:"permissions,omitempty"`
}

Request is one installation token asked for: an App of the catalogue and what the token is cut down to. The decision is already made.

func (Request) Narrowing

func (r Request) Narrowing() githubapp.Narrowing

Narrowing is the request's cut as the GitHub client spells it.

Jump to

Keyboard shortcuts

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