WIP: judge an access by who writes it, and act on its path only on a warrant (issue 567)

Paused: ADR 0325 replaces runs-as and the group grant. Kept for reuse: the
bounded descriptor walks, the warrant-backed access act (share, create),
the access wait and the missing-path waiting state.
This commit is contained in:
2026-10-12 17:00:41 +02:00
parent dd9ab7927d
commit fc3975d535
14 changed files with 990 additions and 16 deletions
+26
View File
@@ -1207,6 +1207,25 @@ type Container struct {
// Health is how this resource is ready (novox/hq ADR 0240 rule 2, Phase B): one kind and its
// timing, judged by the node-engine beside liveness. Absent: judged alive or not, and nothing more.
Health *Health `json:"health,omitempty"`
// RunsAs is the identity the container's code writes as, "<uid>:<gid>", resolved by the controller
// from the module's settings like any value (novox/hq ADR 0322 §1): image software that takes its
// identity from its environment (PUID and PGID) runs as neither the runtime's user nor anything the
// engine could read off the image. Only judged by: a read-write access is writable for it when its
// uid owns the path or its gid is the path's group (§2). Never passed to the runtime and not part of
// the spec, so declaring it recreates nothing. Absent: judged by the granted group alone (ADR 0312 §1).
RunsAs string `json:"runs-as,omitempty"`
}
// ParseRunsAs reads a container's runs-as, "<uid>:<gid>", as two non-negative numbers.
func ParseRunsAs(s string) (uid, gid int, err error) {
u, g, ok := strings.Cut(s, ":")
uid, uerr := strconv.Atoi(u)
gid, gerr := strconv.Atoi(g)
if !ok || uerr != nil || gerr != nil || uid < 0 || gid < 0 || strings.ContainsAny(s, "+ ") {
return 0, 0, fmt.Errorf("runs-as is %q, and it is two non-negative numbers, \"<uid>:<gid>\"", s)
}
return uid, gid, nil
}
func (c *Container) Identity() string { return c.ID }
@@ -1289,6 +1308,13 @@ func (c *Container) validate(where string, _ bool) []string {
problems = append(problems, where+": networks is for a container that keeps running; a step "+
"runs and exits, and joins nothing afterwards")
}
// Judged as it arrived, after the controller resolved it (novox/hq ADR 0322 §1): a setting that was never
// given, or is not a number, is refused here, naming the container, not read as some identity.
if c.RunsAs != "" {
if _, _, err := ParseRunsAs(c.RunsAs); err != nil {
problems = append(problems, where+": container "+c.Name+": "+err.Error())
}
}
return append(problems, checkImage(where, c.Image)...)
}