Documentation
¶
Overview ¶
Package dockercompose validates and runs docker compose invocations safely.
Index ¶
- Constants
- Variables
- func CheckCLI(p ParsedArgs) []safe.Violation
- func CheckModel(m Model, cwd string) []safe.Violation
- func Prepare(ctx context.Context, args []string, cwd string, r Resolver) ([]safe.Violation, error)
- func WantsGlobalHelp(args []string) bool
- type Model
- type Mount
- type ParsedArgs
- type Resolver
- type Service
Constants ¶
const RealBinary = "realdocker"
RealBinary is the second command name the profile binds to the actual docker binary, reachable only from the "docker" wrapper.
It is deliberately not "docker": nono puts its shim directory first on PATH, and the wrapper is itself bound to the name "docker" in the command profile. Resolving "docker" from inside anything that runs behind that wrapper — including this model resolution, which shells out on the wrapper's behalf — would resolve back to the wrapper's own shim and argv_prepend would fire again, recursing without bound (measured on the equivalent git case, four levels deep, before the probe was killed). The profile instead gives the real docker binary this second name, resolvable only from the wrapper, so looking it up here reaches the real binary through its own shim with no recursion.
It is also deliberately not "docker-real", or anything else starting with "docker-": git's own multi-call dispatch treats a "git-<word>" argv[0] as an attempt to run "<word>" as a builtin directly (measured; see git.RealBinary), silently discarding the rest of argv. docker is not known to do the same, but naming this the same shape as git.RealBinary anyway is what keeps it from being a trap for whoever copies this pattern next. Do not change this back to "docker", and do not give it a "docker-" prefix either.
Variables ¶
var ErrResolve = errors.New("safe docker-compose: resolve failed")
ErrResolve wraps any failure to resolve the Compose model (for example an invalid compose file or a docker error).
Functions ¶
func CheckCLI ¶
func CheckCLI(p ParsedArgs) []safe.Violation
CheckCLI refuses subcommands that are entrypoints for arbitrary command execution, and fails closed on any leading flag ParseArgs could not classify.
func CheckModel ¶
CheckModel validates the resolved Compose model against the built-in rules, using cwd as the mount boundary.
func Prepare ¶
Prepare runs the full safety pipeline for a docker compose invocation.
It parses args, applies CLI-level rules (which short-circuit before any docker process runs), resolves the canonical model, and applies model-level rules. The returned slice lists every violation found; an empty slice means the invocation is safe to execute. A non-nil error indicates an operational failure (the model could not be resolved) and the caller must run nothing.
func WantsGlobalHelp ¶
WantsGlobalHelp reports whether args request help at the global level (`docker-compose --help` or `-h`), before any subcommand.
Types ¶
type Model ¶
Model is the resolved Compose project as emitted by `docker compose config`.
func DecodeModel ¶
DecodeModel parses `docker compose config --format json` output.
type Mount ¶
type Mount struct {
Type string `json:"type"` // "bind", "volume", or "tmpfs"
Source string `json:"source"` // absolute host path for bind; volume name for volume
Target string `json:"target"`
}
Mount is a normalized service mount from the resolved Compose model.
type ParsedArgs ¶
type ParsedArgs struct {
GlobalFlags []string // global flags (and their values) before the subcommand
Subcommand string // e.g. "up", "run"; "" when none is present
Rest []string // subcommand and everything after it
Unrecognized string // a leading flag we could not classify; "" when none
HelpRequested bool // --help / -h given at the global level (before any subcommand)
}
ParsedArgs is the result of separating docker compose global flags from the subcommand and its arguments.
func ParseArgs ¶
func ParseArgs(args []string) ParsedArgs
ParseArgs walks the leading flags, treating the first non-flag token as the subcommand. Every leading flag must be a recognized docker compose global flag; an unrecognized one sets Unrecognized and stops parsing, so the caller can fail closed rather than misidentify the subcommand and run it anyway.
type Resolver ¶
Resolver produces the canonical Compose model for the given global flags.
func NewResolver ¶
func NewResolver() Resolver
NewResolver returns the default Resolver, which runs `realdocker compose <globalFlags> config --format json`, with argv[0] set to "docker" (see the comment in Resolve).
type Service ¶
type Service struct {
Privileged bool `json:"privileged"`
NetworkMode string `json:"network_mode"`
Pid string `json:"pid"`
Ipc string `json:"ipc"`
UsernsMode string `json:"userns_mode"`
CapAdd []string `json:"cap_add"`
SecurityOpt []string `json:"security_opt"`
Devices []json.RawMessage `json:"devices"`
Volumes []Mount `json:"volumes"`
}
Service holds the security-relevant fields of one resolved service.