Documentation
¶
Overview ¶
Package github implements GitHub App authentication for agent tokens (gha_). It handles JWT signing with the App's private key, installation token generation via the GitHub API, and token caching with automatic renewal. This is the credential backend for agent tokens — when an agent uses a gha_ token, the proxy resolves it to a GitHub App installation token obtained through this package.
Index ¶
- type AppConfig
- type AppRegistry
- func (r *AppRegistry) Count() int
- func (r *AppRegistry) DefaultOrOnlyID() string
- func (r *AppRegistry) Get(appID string) (*AppTokenProvider, error)
- func (r *AppRegistry) GetDefault() (*AppTokenProvider, error)
- func (r *AppRegistry) GetDefaultID() string
- func (r *AppRegistry) GetInstallationToken(ctx context.Context, installationID int64, repos []string, ...) (string, error)
- func (r *AppRegistry) GetInstallationTokenForApp(ctx context.Context, appID string, installationID int64, repos []string, ...) (string, error)
- func (r *AppRegistry) LoadAll(ctx context.Context) error
- func (r *AppRegistry) Reload(ctx context.Context) error
- func (r *AppRegistry) TotalApps() int
- type AppTokenProvider
- func (p *AppTokenProvider) GetInstallationToken(ctx context.Context, installationID int64, repos []string, ...) (string, error)
- func (p *AppTokenProvider) ListInstallationRepositories(ctx context.Context, installationID int64) ([]InstallationRepository, error)
- func (p *AppTokenProvider) ListInstallations(ctx context.Context) ([]Installation, error)
- type Installation
- type InstallationAccount
- type InstallationRepository
- type InstallationTokenError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AppConfig ¶
type AppConfig struct {
AppID int64
PrivateKey string // PEM-encoded RSA private key
BaseURL string // GitHub API base URL, defaults to https://api.github.com
}
AppConfig holds configuration for GitHub App authentication.
type AppRegistry ¶
type AppRegistry struct {
// contains filtered or unexported fields
}
AppRegistry manages multiple AppTokenProviders, one per configured GitHub App.
func NewAppRegistry ¶
NewAppRegistry creates a new registry. Call LoadAll to populate it.
func NewRegistryWithState ¶
func NewRegistryWithState(providerIDs []string, defaultID string) *AppRegistry
NewRegistryWithState constructs an AppRegistry with pre-populated provider slot IDs and an optional default ID. Provider values are nil — Get() returns a clear error ("not initialized") instead of a nil pointer, so calling GetInstallationToken on a test registry safely fails.
This helper exists in production code (not a _test.go file) because it is called cross-package from internal/server/api_test.go and Go does not support cross-package test-only exports.
func (*AppRegistry) Count ¶
func (r *AppRegistry) Count() int
Count returns the number of loaded providers.
func (*AppRegistry) DefaultOrOnlyID ¶
func (r *AppRegistry) DefaultOrOnlyID() string
DefaultOrOnlyID returns the default app ID, or if no default is set and exactly one app is loaded, returns that app's ID. Returns empty string only when there are zero or 2+ apps with no explicit default.
func (*AppRegistry) Get ¶
func (r *AppRegistry) Get(appID string) (*AppTokenProvider, error)
Get returns the AppTokenProvider for the given app ID.
func (*AppRegistry) GetDefault ¶
func (r *AppRegistry) GetDefault() (*AppTokenProvider, error)
GetDefault returns the AppTokenProvider for the default app.
func (*AppRegistry) GetDefaultID ¶
func (r *AppRegistry) GetDefaultID() string
GetDefaultID returns the database ID of the default app, or empty string if none.
func (*AppRegistry) GetInstallationToken ¶
func (r *AppRegistry) GetInstallationToken(ctx context.Context, installationID int64, repos []string, permissions map[string]string) (string, error)
GetInstallationToken resolves an installation token using the default app provider. Satisfies the proxy.AppTokenProvider interface.
func (*AppRegistry) GetInstallationTokenForApp ¶
func (r *AppRegistry) GetInstallationTokenForApp(ctx context.Context, appID string, installationID int64, repos []string, permissions map[string]string) (string, error)
GetInstallationTokenForApp resolves an installation token using a specific app's provider. If appID is empty, falls back to the default provider. Satisfies the proxy.MultiAppTokenProvider interface.
func (*AppRegistry) LoadAll ¶
func (r *AppRegistry) LoadAll(ctx context.Context) error
LoadAll reads all App records from the store and creates an AppTokenProvider for each one that has a valid private key.
func (*AppRegistry) Reload ¶
func (r *AppRegistry) Reload(ctx context.Context) error
Reload re-reads apps from the store and updates providers. It rebuilds every provider so that changes to an existing app (rotated private key, base_url change, etc.) take effect immediately without a restart.
func (*AppRegistry) TotalApps ¶
func (r *AppRegistry) TotalApps() int
TotalApps returns the number of App records in the store as of the last LoadAll or Reload call. This may differ from Count() when apps exist in the store but fail to load (e.g. bad private keys). Use this to distinguish "no apps in store" from "apps present but none loaded".
type AppTokenProvider ¶
type AppTokenProvider struct {
// contains filtered or unexported fields
}
AppTokenProvider generates GitHub App installation tokens.
func NewAppTokenProvider ¶
func NewAppTokenProvider(cfg AppConfig) (*AppTokenProvider, error)
NewAppTokenProvider creates a provider from the given config.
func (*AppTokenProvider) GetInstallationToken ¶
func (p *AppTokenProvider) GetInstallationToken(ctx context.Context, installationID int64, repos []string, permissions map[string]string) (string, error)
GetInstallationToken returns a GitHub installation token for the given installation, scoped to the specified repositories and permissions. Results are cached, keyed by installation ID plus the requested repos and permissions, and evicted automatically after installationTokenTTL.
func (*AppTokenProvider) ListInstallationRepositories ¶
func (p *AppTokenProvider) ListInstallationRepositories(ctx context.Context, installationID int64) ([]InstallationRepository, error)
ListInstallationRepositories returns repositories accessible to the given installation.
func (*AppTokenProvider) ListInstallations ¶
func (p *AppTokenProvider) ListInstallations(ctx context.Context) ([]Installation, error)
ListInstallations returns all installations for this GitHub App. Raw HTTP is used instead of the go-github SDK so that the full permissions map from the API is preserved — the SDK's typed InstallationPermissions struct only exposes a subset of the permission fields GitHub supports.
type Installation ¶
type Installation struct {
ID int64 `json:"id"`
Account InstallationAccount `json:"account"`
Permissions map[string]string `json:"permissions"`
RepositorySelection string `json:"repository_selection"`
}
Installation represents a GitHub App installation (API response DTO).
type InstallationAccount ¶
type InstallationAccount struct {
Login string `json:"login"`
ID int64 `json:"id"`
Type string `json:"type"`
}
InstallationAccount is the GitHub account (user or org) associated with an installation.
type InstallationRepository ¶
type InstallationRepository struct {
FullName string `json:"full_name"`
Name string `json:"name"`
Private bool `json:"private"`
}
InstallationRepository represents a repository accessible to an installation (API response DTO).
type InstallationTokenError ¶
type InstallationTokenError struct {
StatusCode int
Message string
RequestedPermissions map[string]string
GrantedPermissions map[string]string
}
InstallationTokenError represents a failed installation token request, carrying the upstream HTTP status code, GitHub's error message, and permission diagnostics.
func (*InstallationTokenError) Error ¶
func (e *InstallationTokenError) Error() string
func (*InstallationTokenError) MissingPermissions ¶
func (e *InstallationTokenError) MissingPermissions() map[string]string
MissingPermissions returns the permissions that were requested but not granted (or granted at a lower level than requested).