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
- type Attester
- type ChannelStatus
- type Config
- type Option
- func WithAPIBaseURL(baseURL string) Option
- func WithAttester(attester Attester) Option
- func WithChannel(channel string) Option
- func WithClock(now func() time.Time) Option
- func WithHTTPClient(client *http.Client) Option
- func WithProgress(progress remote.ProgressFunc) Option
- func WithRepository(repository string) Option
- func WithSignerWorkflow(workflow string) Option
- func WithStateDirectory(directory string) Option
- func WithToken(token string) Option
- func WithTransferPolicy(policy remote.TransferPolicy) Option
- func WithTrustedRoot(trustedRootJSON []byte) Option
- type RateLimitBudget
- type RefusalError
- type Release
- type ReleaseRef
- type Source
- func (s *Source) Changed(ctx context.Context) (ChannelStatus, error)
- func (s *Source) Cleanup() error
- func (s *Source) Dependencies() []sources.Dependency
- func (s *Source) ID() sources.ID
- func (s *Source) Identity() string
- func (s *Source) IsOptional() bool
- func (s *Source) Name() string
- func (s *Source) Observe(ctx context.Context, _ ...sources.Option) (sources.Observation, error)
- func (s *Source) ReadChannel(ctx context.Context) (Release, error)
- func (s *Source) ReadRelease(ctx context.Context, tag string) (Release, error)
- func (s *Source) RollbackTarget() (ReleaseRef, error)
- type State
Constants ¶
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" )
const (
// RateLimitWarnPercent is the used share that raises a budget warning.
RateLimitWarnPercent = 80
)
const SourceName = "Public GitHub Catalog"
SourceName is the human-readable name of this 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 ¶
WithAPIBaseURL sets the REST API root.
func WithAttester ¶
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 ¶
WithChannel sets the branch ref that carries the channel document.
func WithHTTPClient ¶
WithHTTPClient overrides the HTTP client.
func WithProgress ¶
func WithProgress(progress remote.ProgressFunc) Option
WithProgress sets the transfer progress callback.
func WithRepository ¶
WithRepository sets the `owner/name` repository that publishes the catalog.
func WithSignerWorkflow ¶
WithSignerWorkflow sets the workflow path that the trust policy requires.
func WithStateDirectory ¶
WithStateDirectory sets the directory that holds the durable source state.
func WithTransferPolicy ¶
func WithTransferPolicy(policy remote.TransferPolicy) Option
WithTransferPolicy overrides the transfer bounds.
func WithTrustedRoot ¶
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 ¶
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) Dependencies ¶
func (s *Source) Dependencies() []sources.Dependency
Dependencies reports the external tools this source needs. It needs none.
func (*Source) Identity ¶
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 ¶
IsOptional reports whether a sync can succeed without this source.
func (*Source) Observe ¶
Observe verifies the release the channel selects and returns it as one immutable observation.
func (*Source) ReadChannel ¶
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 ¶
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.