Documentation
¶
Overview ¶
Package supplychain handles agent extension artifacts (skills, plugins, hooks, slash commands, agent definitions) as content-addressed trees (ADR-0028): reading them from the policy repo, fetching pinned remote sources (git commit, OCI digest), computing their digest, and the static scan run by `halo validate` and `halo release build`.
It has no internal dependencies so policy, release and halod can all use it.
Index ¶
- Constants
- Variables
- func CRLFFiles(t Tree) []string
- func CRLFWarning(files []string) string
- func CheckPath(p string) error
- func DigestOf(sums map[string]string) string
- func Listing(sums map[string]string) []byte
- func SplitOCIRef(ref string) (repo, dgst string, err error)
- type Finding
- type GitRunner
- type Rule
- type Tree
Constants ¶
const ( MaxFiles = 512 MaxBytes = 8 << 20 )
Limits on one artifact. A skill or hook is a handful of small text files; anything near these is not one.
Variables ¶
var ( // CommitRe is a full git object id (SHA-1 or SHA-256 repositories). CommitRe = regexp.MustCompile(`^([0-9a-f]{40}|[0-9a-f]{64})$`) // OCIRefRe is a digest-pinned OCI reference: host/repo@sha256:<hex>. OCIRefRe = regexp.MustCompile(`^[a-z0-9]([a-z0-9.:-]*[a-z0-9])?(/[a-z0-9._-]+)+@sha256:[0-9a-f]{64}$`) )
var Rules = []Rule{
{"hidden-unicode", "zero-width, bidirectional-override or Unicode tag characters, which hide text from a reviewer but not from a model"},
{"html-comment-instruction", "an HTML comment (invisible when Markdown renders) that carries an instruction: ignore previous instructions, do not tell the user, run curl/bash, ..."},
{"permission-bypass", "a permission-bypass mode or flag (bypassPermissions, danger-full-access, --dangerously-skip-permissions, --yolo, ...): AGENTS.md invariant 1"},
{"remote-exec", "fetch-and-execute: curl/wget piped to a shell or interpreter, sh -c \"$(curl ...)\", bash <(curl ...), iex (irm ...)"},
{"credential-path", "a credential location: ~/.ssh, ~/.aws, gcloud credentials, .netrc, .git-credentials, docker or kube config, or reading a .env file"},
{"exfil-url", "a URL on a request-capture, tunnel or paste service (webhook.site, ngrok, interact.sh, pastebin, Discord webhooks, ...) or a public raw-IP URL"},
{"base64-blob", "a base64 run of 1024 characters or more (inline data: images excepted)"},
{"executable-binary", "a native executable or Java class file (ELF, Mach-O, PE, CAFEBABE)"},
}
Rules is the documented ruleset, in report order.
Functions ¶
func CRLFFiles ¶
CRLFFiles lists the files containing "\r\n", sorted. Digests are over the committed bytes: a Windows checkout with core.autocrlf=true hashes CRLF bytes that Linux CI and a remote git fetch never see.
func CRLFWarning ¶
CRLFWarning explains files (from CRLFFiles) and the .gitattributes fix.
func Listing ¶
Listing is the canonical text an artifact digest covers: one "<sha256 hex> <path>\n" line per file, sorted by path in byte order. It is exactly what `sha256sum` prints for the sorted file list, so the digest can be reproduced without Halos (see docs/adr/0028).
func SplitOCIRef ¶
SplitOCIRef splits a digest-pinned "host/repo@sha256:..." reference.
Types ¶
type Finding ¶
type Finding struct {
Rule string `json:"rule"`
Path string `json:"path"`
Line int `json:"line,omitempty"`
Detail string `json:"detail"`
}
Finding is one rule match. Line is 1-based (0 = whole file).
type Rule ¶
Rule is one static check. The ruleset is deliberately small and conservative: each rule matches something an extension has no ordinary reason to contain, so a finding is worth a human look (ADR-0028).
type Tree ¶
Tree is an artifact's content: slash-separated relative path -> bytes.
func FetchGit ¶
FetchGit fetches exactly commit from url (shallow) and reads sub ("" = the whole repository) from it. The checkout is verified to be commit, so a moved branch or tag can never stand in for the pin.
func FetchOCI ¶
FetchOCI reads the artifact whose OCI manifest has digest dgst from src. Each layer is one file named by its org.opencontainers.image.title annotation, which is what `oras push <ref> <file>...` writes. Every blob is digest-verified as it is read. ponytail: directory layers (oras push of a directory, a tar+gzip blob) are refused; push the files instead.
func ReadPath ¶
ReadPath reads a file (keyed by its base name) or a directory tree. .git directories are skipped; symlinks and other non-regular files are refused, so a checkout cannot point the artifact outside itself.