Documentation
¶
Overview ¶
Package release defines the signed release formats: the release record (one per version, signed by an offline release key) and the channel manifest (the list of releases a channel offers, signed by the CI manifest key), and verifies them. It makes no network calls.
Index ¶
- Constants
- Variables
- func LoadTrust() (release, manifest packages.TrustSet, err error)
- func ManifestTrust() packages.TrustSet
- func MarshalRecord(rec Record) ([]byte, error)
- func ReleaseTrust() packages.TrustSet
- func SplitRecordSig(s string) (keyID, sig string, err error)
- func ValidVersion(v string) bool
- func VerifyArtifact(rec *Record, platform string, r io.Reader, o Options) error
- func VerifyRecordSig(rel packages.TrustSet, recordBytes []byte, recordSig string) error
- type Artifact
- type ChannelManifest
- type Entry
- type Options
- type RampStep
- type Record
- type Verified
- type Yank
Constants ¶
const ( // MaxManifestLifetime is the longest expires_at - issued_at Verify accepts. // The tools issue 14 days; a day of slack covers clock rounding. MaxManifestLifetime = 15 * 24 * time.Hour // MaxArtifactSize is the hard cap on an artifact, whatever its record says. MaxArtifactSize = 256 << 20 )
Variables ¶
var ( ErrManifest = errors.New("release manifest is not valid") ErrExpired = errors.New("release manifest has expired") ErrNotFresh = errors.New("release manifest has no valid issued_at / expires_at") ErrChannelMismatch = errors.New("release manifest is for a different channel") ErrVersion = errors.New("version is not in the form vMAJOR.MINOR.PATCH[-prerelease]") ErrNoSuchRelease = errors.New("release is not in the channel manifest") ErrRecordSig = errors.New("release record signature is not valid") ErrRecordMismatch = errors.New("release record does not match the channel entry") ErrArtifactSize = errors.New("artifact size does not match the release record") ErrArtifactHash = errors.New("artifact sha256 does not match the release record") )
Verification failures; test with errors.Is.
var Channels = []string{"stable", "edge", "canary"}
Channels lists the channel names a manifest may carry.
var Platforms = []string{"linux-amd64", "linux-arm64", "darwin-amd64", "darwin-arm64"}
Platforms lists the targets every record must carry.
Functions ¶
func LoadTrust ¶
LoadTrust reads the embedded public keys: files named release-*.pub form the release set, manifest.pub and manifest-*.pub the manifest set.
func ManifestTrust ¶
ManifestTrust returns the keys that may sign channel manifests.
func MarshalRecord ¶
MarshalRecord renders rec as the bytes that are signed and published: indented JSON (map keys sorted by encoding/json) and a trailing newline.
func ReleaseTrust ¶
ReleaseTrust returns the keys that may sign release records.
func SplitRecordSig ¶
SplitRecordSig splits "<key_id>:<base64 signature>".
func ValidVersion ¶
ValidVersion reports whether v is the one form releases use everywhere: vMAJOR.MINOR.PATCH with an optional -prerelease, no build metadata and no missing "v". Lookups compare versions as exact strings, so only this form may be signed.
func VerifyArtifact ¶
VerifyArtifact checks that r holds exactly the build rec names for platform: size within the cap, then sha256. At most size+1 bytes are read.
Types ¶
type Artifact ¶
type Artifact struct {
SHA256 string `json:"sha256"` // lowercase hex, 64 chars
Size int64 `json:"size"`
}
Artifact is one built binary named in a Record.
type ChannelManifest ¶
type ChannelManifest struct {
Channel string `json:"channel"` // "stable", "edge" or "canary"; signed so a mirror cannot swap channels
IssuedAt string `json:"issued_at"`
ExpiresAt string `json:"expires_at"`
Releases []Entry `json:"releases"`
Yanked []Yank `json:"yanked"`
}
ChannelManifest is the signed content of a channel file.
func VerifyManifest ¶
func VerifyManifest(manifestDoc []byte, o Options) (*ChannelManifest, error)
VerifyManifest checks a signed channel manifest: the envelope signature against the manifest keys, then its validity window.
type Entry ¶
type Entry struct {
Version string `json:"version"`
RecordSig string `json:"record_sig"` // "<key_id>:<base64 signature>"
Ramp []RampStep `json:"ramp"`
Halted bool `json:"halted"`
// HaltReason says why Halted was set; omitted when empty.
HaltReason string `json:"halt_reason,omitempty"`
}
Entry offers one release on a channel.
type Options ¶
type Options struct {
Channel string // the channel being checked, "stable", "edge" or "canary"; required
Release, Manifest packages.TrustSet // nil means the embedded set
Now func() time.Time // nil means time.Now
MaxArtifact int64 // 0 means MaxArtifactSize
}
Options tune Verify. The zero value verifies against the embedded trust sets at the current time.
type RampStep ¶
type RampStep struct {
At string `json:"from"` // RFC 3339; "from" because a quoted two-letter name trips check-neutral
Pct int `json:"pct"` // 0..100
}
RampStep raises the share of installs offered a release to Pct from At.
type Record ¶
type Record struct {
Version string `json:"version"` // "v1.4.2"
Kind string `json:"kind"` // "patch", "minor" or "major"
Security bool `json:"security"`
SDK string `json:"sdk"`
// SDKCompatibleWith lists earlier SDK versions this build still serves;
// omitted when empty, so older records stay byte-identical.
SDKCompatibleWith []string `json:"sdk_compatible_with,omitempty"`
SchemaHead int64 `json:"schema_head"`
RollbackFloor string `json:"rollback_floor"`
MinFrom string `json:"min_from"`
NotesURL string `json:"notes_url"`
Artifacts map[string]Artifact `json:"artifacts"` // by platform, e.g. "linux-amd64"
}
Record describes one release. Its signature covers the exact bytes MarshalRecord produced.
type Verified ¶
type Verified struct {
Record Record
Entry Entry
Yanked *Yank // set when the manifest yanks this version; reported, not enforced
}
Verified is what Verify proved about a release.
func Verify ¶
func Verify(manifestDoc []byte, version string, recordBytes []byte, platform string, artifact io.Reader, o Options) (*Verified, error)
Verify proves that version, as offered by a signed channel manifest, is the release recordBytes describes and that artifact (the build for platform) is the file the record names. Order: manifest signature, freshness, channel entry, record signature, record fields, artifact size and sha256.