Documentation
¶
Index ¶
Constants ¶
const ( // ActionsReadPermission is required by authoritative lifecycle // reconciliation. The scale-set message stream identifies a run and job, // but deciding whether an old row is still queued requires the workflow-run // jobs endpoint. Read is sufficient; the fleet never dispatches, cancels or // modifies a workflow run through this credential. ActionsReadPermission = "actions" // OrganizationRunnersPermission is what POST /orgs/{org}/actions/runners/ // registration-token requires. Repository `administration` does not cover // it: an organization entity without this permission creates its GARM // entity and then fails on the first scale set, which is the shape this // deployment hit. OrganizationRunnersPermission = "organization_self_hosted_runners" OwnerTypeOrganization = "organization" OwnerTypeUser = "user" )
The account that owns a GitHub App decides which registration form can create it. An organization-owned App is not reachable through the personal form at all, so picking the wrong one is the difference between a bootstrap that can recreate the deployed credential and one that cannot.
Variables ¶
This section is empty.
Functions ¶
func NormalizeAppName ¶
Types ¶
type Options ¶
type Options struct {
Registry tenant.Registry
// Tenant names which registered account this App will serve. Empty means
// the default tenant, so an existing invocation keeps working unchanged.
Tenant string
// OrganizationRunners requests the organization runner permission. Set it
// when the App will back an organization entity; leave it off for a
// repository entity, which does not need it.
OrganizationRunners bool
ListenAddress string
Repository string
// OwnerType is the kind of account that owns the App and receives its
// installation. Both are the repository owner: the fleet credential is
// owned by, installed on, and scoped to one account. A mixed arrangement
// is not a supported deployment and fails closed.
OwnerType string
AppName string
HomepageURL string
OutputDirectory string
OpenBrowser bool
}
type Runner ¶
type Runner struct {
HTTPClient *http.Client
APIBaseURL string
OpenURL func(string) error
Random io.Reader
}
func (Runner) Verify ¶
func (r Runner) Verify(ctx context.Context, options VerifyOptions) (VerifiedInstallation, error)
Verify re-reads a live installation and writes a current bundle for it.
Every check `bootstrap-github-app` applies after the manifest is approved applies here too, because it is the same function: the installation must belong to the tenant's account, its repository selection must be one this deployment accepts, and its permissions must be exactly the least-privilege set the tenant asked for. What this skips is only the part that creates an App, which is the part that must not happen.
type VerifiedInstallation ¶
type VerifiedInstallation struct {
SchemaVersion int `json:"schema_version"`
AppID int64 `json:"app_id"`
AppSlug string `json:"app_slug"`
InstallationID int64 `json:"installation_id"`
AccountLogin string `json:"account_login"`
OwnerType string `json:"owner_type"`
Repository string `json:"repository"`
RepositorySelection string `json:"repository_selection"`
Permissions map[string]string `json:"permissions"`
PrivateKeyPath string `json:"private_key_path"`
VerifiedAt time.Time `json:"verified_at"`
}
func RedactedResult ¶
func RedactedResult(verified VerifiedInstallation) VerifiedInstallation
type VerifyOptions ¶
type VerifyOptions struct {
Registry tenant.Registry
// Tenant names the registered account. Identity comes from the registry.
Tenant string
// Repository, OwnerType and OrganizationRunners are held to the same values
// `bootstrap-github-app` would have used, so a bundle written here is
// indistinguishable from one written there.
Repository string
OwnerType string
OrganizationRunners bool
// AppID and InstallationID name the App being re-verified. Both are
// non-secret and both appear in the credential anchor.
AppID int64
InstallationID int64
// PrivateKeyPath is the existing App key. It is read, used to sign one JWT
// and copied into the new bundle; it is never logged.
PrivateKeyPath string
// OutputDirectory must not exist. A bundle is written whole or not at all.
OutputDirectory string
}
VerifyOptions re-verifies an App that already exists.
`bootstrap-github-app` is the only writer of a credential bundle, and it always creates a new App, because the manifest flow has no other shape. That is the wrong tool for the case this exists for: an App whose *permissions* changed after its bundle was written.
The bundle records the permissions it was written with, and `garmbootstrap.Reconcile` reads them from that file rather than from GitHub — deliberately, since the file is what a reviewer approved. So approving a new permission on a live installation leaves a bundle that is now wrong about it, and an organization entity built from that bundle fails closed. Before this command the only remedy was to create a second App and retire the first, which churns an installation, an anchor and a registry row to fix a stale JSON file.