3.7 KiB
Restricted Docker agent
Security objective
The agent reduces the chance that an application bug becomes arbitrary Docker control. Because Docker socket access is effectively host-level privilege, the agent is small, independently testable and deny-by-default.
Allowed V1 operations
CreateInstance(plan)StartInstance(instance_id)StopInstance(instance_id, timeout)RestartInstance(instance_id, timeout)ReplaceInstance(plan, expected_revision)for configuration/update recreationDeleteContainer(instance_id)without deleting host dataInspectInstance(instance_id)GetInstanceStats(instance_id)CheckPorts(bindings)without disclosing unrelated container detailsCheckDisk(paths)ListRegisteredInstances()only
There is no generic Docker request, arbitrary command, arbitrary exec, arbitrary container ID, image-build endpoint, host filesystem browser or list-all-containers endpoint.
Registration binding
Each managed container has labels such as:
io.dogama.managed=true
io.dogama.instance-id=<opaque-id>
io.dogama.template-id=<template-id>
io.dogama.template-version=<version>
io.dogama.plan-digest=<sha256-of-canonical-plan>
Labels alone are insufficient. The agent keeps a durable registry of instance ID, expected container identity and plan digest, authenticated by an agent-local key or MAC. An operation succeeds only when request, registry and inspected labels agree.
Deployment-plan validation
Before create or replace, the agent verifies:
- instance and template identifiers have valid syntax;
- image reference matches the canonical approved plan and preferably a resolved digest;
- command, entrypoint, capabilities, devices and security options exactly match allowed template fields;
- no privileged mode, host PID/IPC/network namespace, device mount or Docker socket mount;
- every bind source resolves below an allowed root after symlink-aware canonicalization;
- every container destination is declared by the template;
- port protocols and container ports match the template and host ports do not conflict;
- resource limits are present and within administrator limits;
- labels use the reserved namespace and cannot be overridden;
- only approved DoGaMa networks are attached.
V1 templates do not expose arbitrary Docker security options. The agent applies a secure fixed baseline: no-new-privileges where compatible, dropped capabilities by default, bounded PIDs and a non-host network mode.
Authentication and replay defense
Requests use a shared secret read from a Docker secret file. Sign method, path, body digest, timestamp and nonce. Reject clock-skewed or reused nonces. Use constant-time comparison, small body limits and short timeouts. Rotate the token through an explicit maintenance workflow.
The agent listens only on the internal control network and publishes no host port. Authentication remains mandatory even on that network.
Failure semantics
- Validate the full plan before pulling or mutating anything.
- Return typed, non-sensitive errors.
- Create with a deterministic name only after registration intent is persisted.
- On partial create, remove the incomplete container but never delete bind-mounted data.
- On replace failure, retain or recreate the prior container plan when safe; otherwise leave the instance stopped and report intervention required.
- Agent startup reconciles its registry with Docker but never adopts unknown containers automatically.
Testing focus
Negative integration tests must cover forged labels, unknown IDs, path traversal, symlink escape, reserved-label overrides, host networking, privileged flags, extra mounts, image substitution, conflicting ports, replayed requests and attempts to target unrelated containers.