Limits and defaults¶
Every bound here exists because the unbounded version is a fault waiting for a bad day. None is configurable unless a column says so.
HTTP¶
| Value | Configurable | |
|---|---|---|
| Request timeout | 5 minutes | artifacts.WithHTTPClient |
| Signed index | DefaultIndexURL |
artifacts.WithIndexURL |
The default client is &http.Client{Timeout: 5 * time.Minute}. An artefact is
tens of megabytes, so a transfer that stalls is a fault rather than slowness, and
a resolver that hangs takes the tool down with it.
Supplying your own client replaces the timeout entirely, so set one.
Download ceilings¶
| Fetch | Ceiling |
|---|---|
| Index and its signature | 1 MiB each |
| Manifest and signature | 1 MiB each |
| Artefact | the publisher's signed length, capped at 1 GiB |
A manifest is a few hundred bytes; 1 MiB is generous. The artefact ceiling is generous but finite: the largest artefact mirrored today is around 40 MB, and the bound exists so a compromised or confused channel cannot stream forever.
Each read stops one byte past its ceiling, so an oversized response is detected
rather than silently truncated. An artefact longer than its signed length fails as
ErrUnverified the moment it overruns; an oversized manifest or signature is
refused before it is parsed.
Cache¶
| Value | |
|---|---|
| Conventional root | <os.UserCacheDir()>/phpboyscout/artifacts |
| Layout | <root>/<artefact>/<version>/<file> |
| Directory mode | 0755 |
| File mode | 0600 |
| Write strategy | stream to a quarantine file, hash in flight, then rename |
| Read strategy | re-hashed against the signed digest on every hit |
Directories are 0755: readable by all, writable only by the owner. An artefact
is public data, fetched from a public channel, but a world-writable cache would
let any local user swap verified bytes for their own after verification has
happened.
Files land at 0600, inherited from the temporary file the atomic write creates.
The practical consequence is that a cache is shared between one user's tools, not
between users; see
Choose a cache location.
Path components from the manifest are sanitised before use: separators and
traversal are stripped, so a manifest naming ../../.ssh/authorized_keys lands
inside the cache or nowhere. A signature proves who published a name, not that
the name is harmless.
Trust¶
| Value | Configurable | |
|---|---|---|
| Release identity | artifacts-release@phpboyscout.uk |
no; it is the key |
| Anchors | embedded key and WKD, must agree | no |
| Failure mode | fail closed | no |
| WKD fetch client | go/signing default, 30s timeout |
trust.WithHTTPClient |
| Key set caching | resolved once, on success only | no |
The failure mode is deliberately not an option. go/signing's composite resolver
defaults to fail-open (a WKD outage falls back to the embedded key with a
warning), which suits self-update and not artefact resolution. See
The trust model.
A failed resolution is not cached, so a transient WKD outage does not poison the verifier for the lifetime of the process.
Dependencies¶
The root package links no cryptographic implementation, enforced by a test.
OpenPGP arrives through artifacts/trust, so importing that subpackage is the
point at which a consumer opts into cryptography, and until then go-crypto and
its curve implementations are not in the binary.
Its full dependency set is github.com/spf13/afero (the filesystem seam behind
WithFS) and afero's own golang.org/x/text. A second test names that set, so
an addition is a decision somebody recorded rather than something that arrived.
Requires the Go release named on the go line of go.mod, or newer.