authz

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package authz implements a Docker daemon authorization plugin (CAPABILITY_SPEC domain 8 / 15). For standalone Docker there is no API server to run an admission controller, so the daemon's AuthZ plugin framework is the only enforceable gate on dangerous API calls. This package evaluates each proxied Docker API request against a policy and returns allow/deny using the exact wire contract Docker expects, so `dockerd --authorization-plugin` can point at it.

The policy engine is pure and table-driven — Evaluate maps a (method, path, parsed body) to a Decision with no I/O — so it is golden-testable; the HTTP server is a thin adapter over it (see server.go).

Index

Constants

This section is empty.

Variables

View Source
var SensitiveHostPaths = []string{
	"/", "/etc", "/var/run", "/run", "/proc", "/sys", "/dev",
	"/var/lib/docker", "/root", "/home",
}

SensitiveHostPaths are host locations whose bind-mount into a container is a container-to-host escape or credential-theft vector.

Functions

func Command

func Command(args []string) int

Command dispatches `dsecrat authz <serve>`.

Types

type Decision

type Decision struct {
	Allow bool
	// Msg is shown to the Docker user on allow; Reason explains a deny.
	Msg    string
	Reason string
	// Rule is the id of the policy rule that decided (for logging/audit).
	Rule string
}

Decision is the plugin's verdict.

type Policy

type Policy struct {
	// DenyPrivileged denies `POST /containers/create` (and run) with
	// HostConfig.Privileged=true.
	DenyPrivileged bool
	// DenyHostNamespaces denies host PID/IPC/Network/UTS namespace sharing.
	DenyHostNamespaces bool
	// DenyHostPathMounts denies bind-mounting sensitive host paths (see
	// SensitiveHostPaths); DenyDockerSocketMount is the most important special
	// case and is implied when this is set.
	DenyHostPathMounts bool
	// DenyDockerSocketMount denies mounting /var/run/docker.sock into a container
	// (host-root-equivalent), even when general host-path mounts are allowed.
	DenyDockerSocketMount bool
	// DenyCapAdd denies adding any capability in this set (case-insensitive,
	// with or without the CAP_ prefix), e.g. SYS_ADMIN, NET_ADMIN.
	DenyCapAdd []string
	// ReadOnly denies all mutating API calls (POST/PUT/DELETE), turning the
	// daemon into a read-only endpoint. Useful for locked-down hosts.
	ReadOnly bool
	// contains filtered or unexported fields
}

Policy configures which dangerous operations to deny. Every field defaults to the safe-but-permissive off, so an empty policy allows everything (a no-op plugin); operators opt into each guardrail.

func (*Policy) Evaluate

func (p *Policy) Evaluate(req Request) Decision

Evaluate returns the plugin decision for a request. Allow-by-default: only a matched deny rule blocks. The first matching deny wins and names itself.

type Request

type Request struct {
	Method string // HTTP method, e.g. "POST"
	URI    string // request URI incl. query, e.g. "/v1.43/containers/create"
	Body   []byte // decoded request body (may be nil for GETs)
}

Request is the subset of Docker's AuthZReq we reason about. Docker sends more fields; we decode only what a policy needs. RequestBody is base64 in the wire message; the server decodes it before calling Evaluate.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server adapts the pure Policy to Docker's HTTP plugin protocol.

func NewServer

func NewServer(p *Policy, log *slog.Logger) *Server

NewServer builds a plugin HTTP server for a policy.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP lets the server drop into http.Serve or httptest.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL