github

package
v0.16.5 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package github observes the attested public catalog channel of one GitHub repository.

Discovery reads the channel document from the mutable `catalog/v1` branch through the repository contents endpoint. The request carries the stored validator, so an unchanged channel costs one request and no body. Verification runs before anything becomes active. The source verifies the channel document attestation first. It then verifies the immutable release that the document selects: every named asset, its recorded checksum and size, and the build provenance of the archive.

A document whose sequence moves backwards is a replay and the source rejects it. A release whose provenance fails the trust policy never becomes active. The release that verification last accepted stays the rollback target in the caller-supplied state directory.

The package reads no environment variable. Every setting arrives through an option. Every error carries a safe reason code, which holds no URL, no token, and no host of a custom deployment.

Index

Constants

View Source
const (
	// DefaultRepository is the public Starmap catalog repository.
	DefaultRepository = "agentstation/starmap"

	// DefaultChannel is the public discovery channel branch.
	DefaultChannel = artifact.ChannelName

	// DefaultSignerWorkflow is the repository-relative path of the workflow
	// that signs every published catalog release.
	DefaultSignerWorkflow = ".github/workflows/catalog-generation.yaml"

	// DefaultAPIBaseURL is the public GitHub REST API root.
	DefaultAPIBaseURL = "https://api.github.com"

	// SourceIdentity is the safe name of this source. It carries no URL, no
	// token, and no host of a custom deployment.
	SourceIdentity = "public_github"
)
View Source
const (
	// RateLimitWarnPercent is the used share that raises a budget warning.
	RateLimitWarnPercent = 80
)
View Source
const SourceName = "Public GitHub Catalog"

SourceName is the human-readable name of this source.

View Source
const (
	// StateSchemaVersion is the current durable state schema version.
	StateSchemaVersion uint64 = 1
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Attester

type Attester func(
	ctx context.Context,
	bundleJSON []byte,
	artifactDigest string,
	policy attestation.Policy,
) (attestation.Result, error)

Attester verifies one Sigstore bundle against a trust policy and one exact artifact digest.

internal/attestation.Verify is the default. This function type exists because a caller may refresh the Sigstore engine on its own schedule. The default engine reaches no network.

type ChannelStatus

type ChannelStatus struct {
	// Changed reports whether the channel document moved since the last
	// verified read.
	Changed bool

	// ETag is the validator the reply carried.
	ETag string

	// Budget reports the request budget and the request count of the check.
	Budget RateLimitBudget
}

ChannelStatus is the result of one conditional channel check.

type Config

type Config struct {
	// Repository is `CATALOG_SOURCE_REPOSITORY`, in `owner/name` form.
	Repository string

	// Channel is `CATALOG_SOURCE_CHANNEL`, the branch that carries the
	// channel document. The source reads that document from the repository
	// contents endpoint at this ref.
	Channel string

	// SignerWorkflow is `CATALOG_SOURCE_SIGNER_WORKFLOW`.
	SignerWorkflow string

	// Token is `CATALOG_SOURCE_TOKEN`. It is optional, because every public
	// catalog release is readable without one.
	Token string

	// APIBaseURL is `CATALOG_SOURCE_URL`, the REST API root.
	APIBaseURL string

	// StateDirectory holds the durable ETag, sequence, and rollback target.
	// The caller owns the directory and supplies it.
	StateDirectory string

	// TrustedRootJSON overrides the compiled Sigstore trusted root. A
	// connected caller refreshes the root through TUF and passes it here.
	TrustedRootJSON []byte

	// TransferPolicy bounds every request and every body read.
	TransferPolicy remote.TransferPolicy

	// Progress receives transfer progress. It may be nil.
	Progress remote.ProgressFunc

	// HTTPClient overrides the transfer client. It may be nil.
	HTTPClient *http.Client

	// Attester verifies one Sigstore bundle. It defaults to the hermetic
	// engine in internal/attestation.
	Attester Attester

	// Now reads the clock. It defaults to time.Now.
	Now func() time.Time
}

Config holds the settings of one GitHub catalog source.

Each field carries one canonical `CATALOG_SOURCE_*` setting. The package never reads the environment. A caller resolves the environment and passes the result through the options below.

type Option

type Option func(*Config)

Option configures one GitHub catalog source.

func WithAPIBaseURL

func WithAPIBaseURL(baseURL string) Option

WithAPIBaseURL sets the REST API root.

func WithAttester

func WithAttester(attester Attester) Option

WithAttester overrides the Sigstore verification engine. A caller that refreshes its own engine build passes it here. The default engine needs no network and no override.

func WithChannel

func WithChannel(channel string) Option

WithChannel sets the branch ref that carries the channel document.

func WithClock

func WithClock(now func() time.Time) Option

WithClock overrides the clock.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient overrides the HTTP client.

func WithProgress

func WithProgress(progress remote.ProgressFunc) Option

WithProgress sets the transfer progress callback.

func WithRepository

func WithRepository(repository string) Option

WithRepository sets the `owner/name` repository that publishes the catalog.

func WithSignerWorkflow

func WithSignerWorkflow(workflow string) Option

WithSignerWorkflow sets the workflow path that the trust policy requires.

func WithStateDirectory

func WithStateDirectory(directory string) Option

WithStateDirectory sets the directory that holds the durable source state.

func WithToken

func WithToken(token string) Option

WithToken sets the optional GitHub token.

func WithTransferPolicy

func WithTransferPolicy(policy remote.TransferPolicy) Option

WithTransferPolicy overrides the transfer bounds.

func WithTrustedRoot

func WithTrustedRoot(trustedRootJSON []byte) Option

WithTrustedRoot overrides the compiled Sigstore trusted root.

type RateLimitBudget

type RateLimitBudget struct {
	// Observed reports whether the reply carried a usable budget.
	Observed bool

	// Limit is the number of requests that the window allows.
	Limit int

	// Used is the number of requests already spent in the window.
	Used int

	// Remaining is the number of requests left in the window.
	Remaining int

	// ResetAt is the time the window restarts.
	ResetAt time.Time

	// Requests is the number of requests this refresh cycle sent.
	Requests int
}

RateLimitBudget reports the GitHub request budget that the response headers declare, together with the request count of the cycle that read them.

GitHub sends the budget on every REST reply, so one cycle always knows how much of its hourly allowance remains before the next cycle starts.

func (RateLimitBudget) Exhausted

func (b RateLimitBudget) Exhausted() bool

Exhausted reports whether the window has no request left.

func (RateLimitBudget) UsedPercent

func (b RateLimitBudget) UsedPercent() int

UsedPercent returns the spent share of the window, from zero to one hundred. An unobserved or empty budget returns zero.

func (RateLimitBudget) Warn

func (b RateLimitBudget) Warn() bool

Warn reports whether the cycle should warn about the remaining budget.

type RefusalError

type RefusalError struct {
	// Status is the refused HTTP status code.
	Status int

	// Resource is the safe operation label.
	Resource string

	// NotBefore is the earliest time the caller may retry. It is zero when
	// the reply declared no boundary.
	NotBefore time.Time

	// Budget is the request budget the refusal reported.
	Budget RateLimitBudget

	// Err is the underlying typed API error.
	Err error
}

RefusalError reports a refused GitHub reply together with the hard not-before boundary the reply declared. A caller passes the boundary to fleet.NotBefore, which adds the jitter that keeps a fleet from retrying at one instant.

func (*RefusalError) Error

func (e *RefusalError) Error() string

Error implements the error interface.

func (*RefusalError) Unwrap

func (e *RefusalError) Unwrap() error

Unwrap implements errors.Unwrap, so a caller keeps the typed API error.

type Release

type Release struct {
	// Tag is the immutable release tag.
	Tag string

	// GenerationID is the catalog generation the release carries.
	GenerationID string

	// CatalogDigest is the facts-only semantic digest of the catalog the
	// release carries. The publisher keys the release tag and the channel
	// document by this digest, not by the exact payload checksum that the
	// generation manifest records.
	CatalogDigest string

	// PublishedAt is the publication time the channel recorded. It is zero
	// for a release that a caller read by tag.
	PublishedAt time.Time

	// Sequence is the channel sequence that selected the release. It is zero
	// for a release that a caller read by tag.
	Sequence uint64

	// Generation is the verified immutable catalog generation.
	Generation catalogs.Generation

	// Provenance is the verified build provenance of the archive.
	Provenance attestation.Result

	// Budget reports the request budget and the request count of the cycle.
	Budget RateLimitBudget
}

Release is one verified immutable catalog release. Every field describes evidence that verification already accepted.

type ReleaseRef

type ReleaseRef struct {
	Tag           string    `json:"tag"`
	GenerationID  string    `json:"generation_id"`
	CatalogDigest string    `json:"catalog_digest"`
	VerifiedAt    time.Time `json:"verified_at"`
}

ReleaseRef names one verified immutable catalog release.

func (ReleaseRef) Empty

func (r ReleaseRef) Empty() bool

Empty reports whether the reference names no release.

type Source

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

Source observes the attested catalog channel of one GitHub repository.

func New

func New(opts ...Option) (*Source, error)

New builds one GitHub catalog source. It requires a state directory, because replay rejection and the rollback target must survive a restart.

func (*Source) Changed

func (s *Source) Changed(ctx context.Context) (ChannelStatus, error)

Changed reports whether the channel document moved since the last verified read. It sends one conditional request, and an unchanged channel returns no body. It never advances the durable validator, because only a complete verification may move the replay floor.

func (*Source) Cleanup

func (s *Source) Cleanup() error

Cleanup releases source resources. This source holds none.

func (*Source) Dependencies

func (s *Source) Dependencies() []sources.Dependency

Dependencies reports the external tools this source needs. It needs none.

func (*Source) ID

func (s *Source) ID() sources.ID

ID returns the stable identity of this source.

func (*Source) Identity

func (s *Source) Identity() string

Identity returns the safe source name that fleet pacing hashes. It carries no URL, no token, and no host of a custom deployment.

func (*Source) IsOptional

func (s *Source) IsOptional() bool

IsOptional reports whether a sync can succeed without this source.

func (*Source) Name

func (s *Source) Name() string

Name returns the human-friendly name of this source.

func (*Source) Observe

func (s *Source) Observe(ctx context.Context, _ ...sources.Option) (sources.Observation, error)

Observe verifies the release the channel selects and returns it as one immutable observation.

func (*Source) ReadChannel

func (s *Source) ReadChannel(ctx context.Context) (Release, error)

ReadChannel discovers, verifies, and returns the release the channel selects. It advances the durable validator, the replay floor, and the rollback target only after every check passes.

func (*Source) ReadRelease

func (s *Source) ReadRelease(ctx context.Context, tag string) (Release, error)

ReadRelease reads and verifies one immutable release by tag. It accepts the canonical namespace and both retired namespaces, so a rollback target and a legacy release stay readable. It never advances the durable state, because a read by tag is an explicit override and not a discovery.

func (*Source) RollbackTarget

func (s *Source) RollbackTarget() (ReleaseRef, error)

RollbackTarget returns the release that verification last accepted. It is empty before the first verified read.

type State

type State struct {
	SchemaVersion uint64     `json:"schema_version"`
	Repository    string     `json:"repository"`
	Channel       string     `json:"channel"`
	ChannelETag   string     `json:"channel_etag"`
	Sequence      uint64     `json:"sequence"`
	Verified      ReleaseRef `json:"verified"`
	UpdatedAt     time.Time  `json:"updated_at"`
}

State is the durable discovery state of one repository channel. It carries the conditional-request validator, the replay floor, and the release that verification last accepted.

Jump to

Keyboard shortcuts

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