Documentation
¶
Overview ¶
Package trust decides whether the devvault-managed files inside a repository may be used to run something on the host.
devvault clones repositories the user does not control, and then hands repository-owned files to `docker compose` and `container build`. Those files decide mounts, privileges and build steps, so they are exactly the inputs that must not be trusted blindly.
The rule is: a managed file is trustworthy when it is byte-identical to what devvault would render from the trusted config, or when the user approved its current content. Approvals live in the user-owned registry under ~/.devvault, never in the repository — a repository can never approve itself.
Index ¶
- Variables
- func Digests(report Report) map[string]string
- func RecordAfterGenerate(root, projectID string) error
- func Require(root string, cfg config.Config, approved map[string]string) error
- func RequireProject(root string, cfg config.Config, projectID string) error
- func UnifiedDiff(path, repoContent, generated string) (string, error)
- type FileStatus
- type ProjectReport
- type Report
- type ReviewItem
- type State
- type UntrustedError
Constants ¶
This section is empty.
Variables ¶
var ErrDiffTooLarge = fmt.Errorf("file is too large to diff")
ErrDiffTooLarge reports that a file is too large to diff line by line.
Functions ¶
func Digests ¶
Digests returns the digests observed in a report, ready to be stored as approvals. Missing files contribute nothing.
func RecordAfterGenerate ¶
RecordAfterGenerate stores the digests of the files devvault just generated, so the very next command does not stop at a file devvault wrote itself. A directory without a registry entry has nowhere to store approvals; that is not an error, it only means the files have to keep matching their templates.
Only the managed target paths are recorded, never a repository-supplied fallback such as ./docker-compose.yml — generating files must not turn pre-existing repository content into approved content.
func Require ¶
Require returns an actionable error when an enforced file of the project at root is neither generated nor approved.
func RequireProject ¶
RequireProject is the enforcement entry point of every command that runs something inside the container.
func UnifiedDiff ¶
UnifiedDiff renders the difference between the file the repository ships and the file devvault would generate, in unified diff format. It returns ErrDiffTooLarge when a side exceeds the review limits.
Types ¶
type FileStatus ¶
type FileStatus struct {
// Path is the repository-relative path of the file devvault actually
// found, which for a fallback candidate differs from Expected.
Path string
// Expected is the repository-relative path devvault manages.
Expected string
State State
// Enforced reports whether drift in this file blocks execution.
Enforced bool
// Digest is "sha256:<hex>" of the current content, empty when missing.
Digest string
// MatchesTemplate reports whether the content on disk is byte-identical to
// what devvault would render from the trusted config right now. It answers
// a different question than State: State is the security verdict — did
// anything change since devvault generated the file or the user approved
// it — while MatchesTemplate is the consistency one: does the file still
// follow the config. The two come apart after a config change: a file that
// carries an approval stays StateOK because nothing was smuggled into it,
// but it no longer matches the config, and `devvault sync` is the way back.
//
// It is false wherever devvault has no rendered content for the path it
// found, so it reads as "not known to follow the config", never as "known
// to differ": a missing file, a repository-supplied fallback such as
// ./docker-compose.yml or .devcontainer/Dockerfile, and every unexpected
// entry inside .devvault/scripts. HasTemplate tells those apart from a real
// mismatch.
MatchesTemplate bool
}
FileStatus is the verdict for one managed file of a project.
func (FileStatus) HasTemplate ¶ added in v0.2.2
func (f FileStatus) HasTemplate() bool
HasTemplate reports whether MatchesTemplate is the outcome of an actual comparison. It is true exactly for a managed file that exists at the path devvault manages, and false where nothing could be compared — see MatchesTemplate.
type ProjectReport ¶
type ProjectReport struct {
Report
// Project is the registry key, empty for a directory that is not
// registered.
Project string
// Registered reports whether devvault has a place to store approvals for
// this directory.
Registered bool
}
ProjectReport adds the registry project the approvals belong to.
func Accept ¶
Accept stores the digests currently found in the repository as approvals. This is a deliberate security decision by the user; callers must confirm it first.
func InspectProject ¶
InspectProject inspects root using the approvals stored for projectID. An empty projectID falls back to the project registered for root, if any.
type Report ¶
type Report struct {
Files []FileStatus
// Trusted is false as soon as one enforced file drifted or is unmanaged.
Trusted bool
}
Report is the verdict for a whole project.
func Inspect ¶
Inspect classifies every managed file of the project at root. cfg must be the trusted config (see projectcontext.LoadTrustedConfig); approved maps repository-relative paths to digests the user approved.
func (Report) Stale ¶ added in v0.2.2
Stale reports whether at least one managed file no longer matches what devvault would render from the trusted config — the state a `devvault tools bump` or a hand-edited `.devvault/config.yaml` leaves behind. It is deliberately independent of Trusted: a file that has not changed since the user approved it keeps its approval and blocks nothing, it has merely fallen behind the config. `devvault sync` regenerates it.
type ReviewItem ¶
type ReviewItem struct {
File FileStatus
// Diff is a unified diff between the repository content and the content
// devvault would generate. It is empty when Note explains why there is
// none.
Diff string
// Note replaces the diff when comparing is impossible or pointless.
Note string
// Size is the size of the repository file in bytes.
Size int64
// Approved reports that this exact content carries the user's approval and
// only fell behind the config. The diff below is then not evidence that
// someone changed the file — it is what `devvault sync` would write.
Approved bool
}
ReviewItem is what the user has to look at for one file that is neither generated nor approved.
func Review ¶
Review collects the files a user has to look at before approving anything, plus the approved ones that no longer match the config: the diff against the freshly rendered template is exactly what a user wants to see before running `devvault sync`.
The content of an unmanaged file is never echoed: devvault would run it, but it is repository-owned data and printing it raw is how a crafted file reaches the terminal.
type State ¶
type State string
State is the verdict for a single managed file.
const ( // StateOK means the file matches a freshly rendered template or an // approved digest. StateOK State = "ok" // StateDrifted means the file exists where devvault manages it, but its // content is neither generated nor approved. StateDrifted State = "drifted" // StateMissing means devvault did not find the file. Missing files never // block: the backends fail with their own, more precise message. StateMissing State = "missing" // StateUnmanaged means devvault would use a file outside the managed // layout — a repository-supplied fallback such as ./docker-compose.yml. // Such a file can never match a template and always needs an approval. StateUnmanaged State = "unmanaged" )
type UntrustedError ¶
type UntrustedError struct {
// Project is the registry key used in the suggested commands.
Project string
// Registered reports whether an approval could be stored at all.
Registered bool
Files []FileStatus
}
UntrustedError explains which files stopped devvault and what to do about them. The paths it names are devvault's own managed paths and fallback candidates — compile-time constants, never strings taken from the repository.
func (*UntrustedError) Error ¶
func (e *UntrustedError) Error() string