Security Architecture
Platform scope for all claims on this page: arm64 / Ubuntu 24.04 / kernel 6.8 / Flannel VXLAN only. All privilege posture descriptions are Tier 2 (validated by design, ADR-accepted). No Tier 1 proof-file measurements appear on this page.
0. Current Security Posture (Sprint 34 Proven)
Sprint 34 Phase B hardened the operator→agent gRPC control plane — the privileged channel
over which the operator drives checkpoint, transfer, and restore on each node agent — and proved
each control against a gate criterion (GC-B1 through GC-B8) on the same cluster as the Sprint 33
cold-path end-to-end migration. The full live-migration regression ran with the complete security
stack active: the migration reached Phase=Complete, the stateful workload's in-memory counter was
restored intact, and all 22/22 Phase A cold-path assertions continued to pass — zero regression.
Scope. The controls below are proven on the Sprint 34 gate cluster (kind, kindnet, amd64, kernel 6.17, containerd 1.7.24, Kubernetes v1.32.0). They harden the operator↔agent gRPC channel specifically. They do not change the shipping v0.1.0-alpha Helm-chart posture described in the sections below, and they do not add certificate lifecycle automation, checkpoint-at-rest encryption, supply-chain signing/SBOM, or default RBAC — those remain unimplemented (see §3, §6, §7, §8).
The hardened model rests on four properties, each backed by a public ADR in docs/adr/.
ADR-SEC-A — mTLS, per-RPC authorization, and size caps
Establishes mutual TLS on the operator↔agent gRPC channel, a per-RPC authorization interceptor that classifies the peer's SPIFFE identity and gates each method by role, and gRPC message size caps (512 MiB on both server and client, plus a 2 GiB decompression limit on the checkpoint tar). The operator is fail-closed: absent TLS material it refuses to start rather than degrade to plaintext.
- GC-B1 — mTLS enforced, fail-closed. Deleting the TLS secret puts the operator into
CrashLoopBackOff; it never serves or dials in plaintext. - GC-B2 — Per-RPC authorization. An RPC without an authenticated, permitted identity is
rejected with
PermissionDenied("role not permitted"). Authorization is enforced per RPC, not only at connection setup. - GC-B3 — gRPC size caps. A 537 MB message is rejected with
ResourceExhaustedagainst the 512 MiB cap on both server and client; checkpoint-tar decompression is independently capped at 2 GiB.
ADR-SEC-B — Signed checkpoint provenance and anti-replay
Each checkpoint carries a manifest signed with an operator key pinned per-migration. The agent
verifies the signature, then verifies the transferred bytes against a wire hash, before extracting
into a staging directory. Restored socket state is bound to the migration's migration_uid, so a
valid signed checkpoint from a different migration is rejected as replay.
- GC-B4 — Checkpoint signing. A checkpoint with an invalid manifest signature is rejected with
PermissionDenied; verification occurs before extraction, so unverified bytes never reach the staging extract step. - GC-B5 — Transfer integrity. A wire-hash mismatch is rejected with
DataLossbefore decompression, so corrupt or tampered payloads are never expanded on disk. - GC-B6 — Socket-state anti-replay. A checkpoint bearing a valid signature but a stale
migration_uidis rejected withPermissionDenied.
ADR-SEC-C — SPIFFE identity verification on operator dial
The operator dials the agent by node IP, but the agent's certificate carries only a SPIFFE URI SAN —
no IP or DNS SAN — so standard x509 IP validation would reject the peer. The resolution is identity
verification, not coordinate binding: the operator supplies a custom VerifyPeerCertificate that
(1) verifies the presented chain against the configured RootCAs pool and (2) exact-matches the
SPIFFE URI spiffe://podmotion.io/ns/<ns>/sa/podmotion-agent. This is proven live — the operator
logs ADR-SEC-C: operator→agent peer verified spiffe=... four times per migration. SPIFFE identity is
stable across node IP changes; node IPs are not.
ADR-SEC-D — migration_uid CR-binding namespace resolution
verifyMigrationUID previously resolved the namespace from os.Getenv("POD_NAMESPACE") with a
hardcoded podmotion-system fallback, but PodMigration CRs live in default and the agent
DaemonSet carried no POD_NAMESPACE env, so the lookup resolved against the wrong namespace. The fix
is a namespace-agnostic resolution: a default-first Get, then a List-by-name fallback across all
namespaces, matching the agent's cluster-wide controller-runtime cache.
Gate criteria summary
| ID | Criterion | Result |
|---|---|---|
| GC-B1 | mTLS enforced + fail-closed | PASS |
| GC-B2 | Per-RPC authorization | PASS |
| GC-B3 | gRPC message size caps | PASS |
| GC-B4 | Checkpoint signing | PASS |
| GC-B5 | Transfer integrity | PASS |
| GC-B6 | Socket-state anti-replay | PASS |
| GC-B7 | Full live migration regression | PASS |
| GC-B8 | Constitutional invariants held | PASS |
TrafficVerified=True was reached before the source pod was deleted, and the checkpoint tmpfs
remained mounted mode 0700 throughout (GC-B8) — the architectural invariants from prior milestones
held under the full security stack.
What is still not implemented. Sprint 34 hardens the control-plane channel; it does not close the gaps tracked elsewhere on this page: certificate issuance and rotation are not yet automated (the fail-closed posture must currently be maintained across rotation by hand), checkpoint encryption at rest is not implemented (§3), no SBOM/signed images/SLSA provenance are produced (§7), and no default RBAC ships (§6).
1. Node-Agent DaemonSet Privilege Model
The PodMotion node agent runs as a DaemonSet and requires an elevated privilege posture for CRIU checkpoint/restore. That privilege is not held uniformly across the pod: the one irreducible long-lived host-level privilege is isolated in a small sidecar, and the main agent container runs de-privileged. Every field below is load-bearing — none is present for convenience.
Pod-level posture. The agent pod runs hostPID: true (CRIU must see the target PID in the
host PID namespace to attach via ptrace(2)) and hostNetwork: true, and the main agent container
mounts the containerd Unix socket read-write.
Privilege Isolation — the netns-broker sidecar
Under the ADR-0148 amendment, the sole long-lived container in the agent pod that runs
privileged: true is a narrow sidecar: the netns-broker. CRIU restore must open the target
pod's network-namespace path from the host mount namespace (--join-ns net:<path>), which requires
a host-mount-namespace bind-mount privilege (CAP_SYS_ADMIN, mount/umount2 in the host init
mount namespace) that cannot be reduced away. Rather than hold that privilege in the long-lived,
broad-surface main agent, the chart isolates it in the broker: it serves only a root-owned Unix
socket (mode 0600) and speaks no gRPC. Its full operation set — per-migration netns lifecycle
plus host-mount-namespace exec, process signalling/liveness, and cgroup placement — and its
server-side input-validation model are documented on the
Node Agent Architecture §3 page.
Two short-lived init containers also run privileged: true under the default chart values, and
each exits before the agent serves gRPC:
init-checkpoint-tmpfs(unconditional) — enters the host mount namespace to set up the mode-0700checkpoint tmpfs at/run/podmotion/checkpoints.install-apparmor-profile(rendered wheneveragent.apparmorProfileis notunconfined— the chart default islocalhost/podmotion-agent, so it renders by default) — loads the narrowpodmotion-agentAppArmor profile onto the node and reloads it viaapparmor_parser.
Both carry narrowly-scoped, init-only host-namespace privilege and are gone before the agent accepts
traffic; the long-lived privileged surface is the netns-broker alone. The main agent container
itself runs privileged: false (below).
Main Agent Container
hostPID: true — set at the pod level. CRIU must attach to the target process using
ptrace(2) across namespace boundaries; without hostPID, the agent cannot see the target PID in
the host PID namespace and CRIU cannot initiate a checkpoint.
privileged: false — the main agent container does not run privileged. It drops ALL
capabilities and adds back only the minimum set CRIU and the eBPF relay require (below), with
allowPrivilegeEscalation: true (CRIU's PTRACE_SEIZE + parasite-code injection requires
no_new_privs cleared on the tracer). The privileged: true surface lives only in the
netns-broker sidecar and the two short-lived init containers above.
seccomp Profile
Current default: no seccomp profile is wired on the agent container. A CRIU-scoped Localhost
seccomp profile ships in the chart at charts/podmotion/profiles/agent-criu.json, but it is
opt-in — agent.seccompProfile.enabled defaults to false, so the agent container runs
Unconfined unless an operator enables it and installs the profile (localhostProfile: podmotion/agent-criu.json) onto each node's kubelet seccomp root out-of-band. Enforcing the seccomp
profile by default is part of the ADR-0148 hardening roadmap.
Capability Set (main agent container)
The main agent container drops ALL capabilities and adds back only the following. One sentence of
justification is provided per capability.
| Capability | Justification |
|---|---|
SYS_PTRACE | CRIU attaches to and inspects the target process's memory and register state via ptrace(2). |
SYS_ADMIN | CRIU namespace/mount operations (setns, unshare, mount/umount2, userfaultfd) during checkpoint and restore. |
CHECKPOINT_RESTORE | CRIU 4.x kerndat init and checkpoint/restore-privileged operations; scopes CRIU privilege more narrowly than SYS_ADMIN (kernel 5.9+). |
DAC_READ_SEARCH | Under privileged: false, CRIU pre-dump must open /proc/<pid>/map_files for a process the agent does not own; this bypasses the file read/search DAC check. |
SYS_RESOURCE | CRIU reads the target's rlimits via prlimit64 across a credential boundary. |
NET_ADMIN | Manipulate network interfaces, routes and neighbor entries, and eBPF TC/XDP attach during TCP connection migration. |
NET_RAW | Open the AF_PACKET socket used to send the gratuitous ARP at IP handoff. |
KILL | Signal (SIGCONT) the source workload tree, which runs under the container image's own non-root UID. |
BPF, PERFMON | eBPF program load / map ops and perf_event_open on kernel ≥ 5.8 (agent.kernelGE58, default true); folded into SYS_ADMIN on older kernels. |
Control-Plane Taint Toleration
The node agent must run on all nodes in the cluster, including control-plane nodes, to provide
full cluster coverage for pod migration. The DaemonSet therefore includes a toleration for the
standard control-plane taint (node-role.kubernetes.io/control-plane: NoSchedule). Omitting
this toleration would prevent the agent from scheduling on control-plane nodes and would leave
any pod on a control-plane node unmigrateable.
Risk: because the DaemonSet tolerates all taints, the privileged netns-broker sidecar (and the
short-lived privileged init containers) run on EVERY node — including control-plane nodes —
alongside a hostPID, host-network main agent with a read-write containerd socket mount. That is a
node-root-equivalent surface cluster-wide. Recommended mitigation today: scope the agent with a
nodeSelector/taint to a dedicated migration-node pool.
Current Posture vs. ADR-0148 Hardening Roadmap
The posture above reflects the shipping v0.1.0-alpha DaemonSet, including the ADR-0148 amendment that de-privileges the main agent and isolates the irreducible long-lived host-mount-namespace privilege in the netns-broker sidecar. ADR-0148 (Accepted) tracks the hardening items that remain, not yet the default:
- Enforce the CRIU-scoped seccomp profile by default (it ships, but
agent.seccompProfile.enableddefaults tofalse). - Replace the read-write containerd socket mount with a read-only mount where feasible.
hostPID: falsevia an NRI-supplied PID.readOnlyRootFilesystem: trueon the agent container.- Evaluate user-namespace isolation for the agent container.
mTLS channel enforcement (fail-closed) is out of scope for ADR-0148 and is tracked separately under ADR-0159 (cert-manager / ACME webhook TLS, Draft) and ADR-0161 control C4 (TLS/mTLS on all control-plane communications, GA+6mo horizon, Draft / not implemented — see §4).
The audit/ directory is currently empty. Structured audit logging is not implemented in
v0.1.0-alpha. PhaseTransition Kubernetes events are emitted; structured audit records are not.
Audit logging implementation is part of the ADR-0148 hardening scope.
2. Controller-Manager Hardened Posture
The PodMotion controller-manager operates in a hardened security context as a counterbalance to
the node agent's elevated privileges. The controller-manager performs no CRIU operations; it
reconciles PodMigration CRs and coordinates the migration state machine via gRPC with the
node agent.
The controller-manager security context:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
runAsNonRoot: true— the controller-manager runs as an unprivileged user at all times.seccompProfile: RuntimeDefault— the container runtime's default seccomp profile is applied, filtering the system call surface to a safe baseline.readOnlyRootFilesystem: true— the container filesystem is immutable at runtime, preventing any in-place modification of binaries or configuration.capabilities: drop: ALL— all Linux capabilities are dropped. The controller-manager requires none.
3. Checkpoint Storage Threat Model
What Checkpoint Images Contain
CRIU checkpoint images contain the full memory snapshot of the checkpointed process at the moment of freeze. This includes:
- All in-memory secrets, tokens, and credentials held by the process (e.g., database passwords, API keys, TLS private keys loaded into memory).
- All in-flight data: pending network buffers, open file descriptors, pipe contents.
- Application heap and stack state, which may include session tokens, cached query results, or user data.
Treat checkpoint images as having the same sensitivity as the process's most sensitive secret.
Storage Location and Access Control
Checkpoint images are written to tmpfs at /run/podmotion/checkpoints/<ref>/ (mode 0700) on the
source node. The directory is owned by root (uid 0) and wiped on node reboot. No other process on
the node has read access unless it is running as root or has DAC_OVERRIDE capability.
Because checkpoint images are stored on the node filesystem, node-level compromise is equivalent to checkpoint image compromise. Harden node access accordingly.
For checkpoint retention, event observability, and the Checkpointed status condition
semantics, see the Observability Reference.
Checkpoint Encryption — Not Implemented in v0.1.0-alpha
Checkpoints are currently written in plaintext. The encryption code path is not wired into the CRIU writer, transfer layer, or registry. There are no Helm values or environment variables that produce encrypted checkpoint output in the current release.
ADR-0029 (Accepted, 2026-06-09 — Superseded by ADR-0160, 2026-06-14) recorded an
ECDHEncryption struct (ECDH P-256 + AES-256-GCM) as on-by-default. That decision was never
wired into the CRIU dump or transfer path. The struct in
internal/agent/encryption/encrypt.go is a passthrough stub whose own doc comment states:
"When disabled, EncryptionStub logs a warning and passes data through unencrypted...
Integration with cosign/imgcrypt is deferred to M13." The struct is not called from the
checkpointer. ADR-0029's on-by-default claim was dead code from the time of its acceptance
and is not an operative design commitment.
ADR-0160 (Draft) is the single authoritative forward plan for checkpoint encryption. It
defines a CheckpointCrypto provider interface with the following providers:
| Provider | Description |
|---|---|
none | Default — no encryption; plaintext on tmpfs as today |
aes-gcm | Self-managed KEK stored in a podmotion-system Secret; AES-256-GCM |
aws-kms | Envelope encryption via AWS KMS |
gcp-kms | Envelope encryption via GCP Cloud KMS |
azure-kms | Envelope encryption via Azure Key Vault |
vault | Envelope encryption via HashiCorp Vault |
The ADR-0160 design targets in-flight AES-256-GCM so that checkpoint plaintext never touches disk. ADR-0160 is Draft and not implemented.
ADR-0161 (Draft) defines the optional FIPS-140-2 validated build path as a post-GA compliance roadmap item. ADR-0161 is Draft and not implemented.
If your workload processes secrets or sensitive data, treat checkpoint plaintext-on-tmpfs as the operative threat model and harden node access accordingly. Encryption will be disclosed and documented when ADR-0160 is implemented and tested.
4. mTLS for Inter-Component gRPC
Default Behavior
The inter-component gRPC endpoint between the controller-manager and the node agent listens on
port :9090. When TLS certificates are not configured, this channel is plaintext (unencrypted).
Any process on the node network path with access to the pod-to-pod network can observe or
inject gRPC traffic.
For any environment where the pod network is not fully trusted, configure mTLS before deploying PodMotion.
mTLS Is Opt-In and Currently Fails Open
In v0.1.0-alpha, enabling mTLS does not guarantee channel enforcement. The mTLS option is opt-in via Helm values or environment variables; however, the current implementation fails open: enabling the option does not enforce mutual authentication on the channel. Do not rely on mTLS configuration as a security boundary in v0.1.0-alpha.
gRPC mTLS enforcement (fail-closed) is out of scope for ADR-0148 and is tracked as a separate workstream: ADR-0161 control C4 (TLS/mTLS on all control-plane communications, GA+6mo horizon) builds on ADR-0079 (webhook TLS lifecycle) and ADR-0159 (cert-manager / ACME webhook TLS, Draft). It is not implemented in v0.1.0-alpha and fails open today.
Strict-Mode Integrity — ADR-0049 Amendment D (Accepted 2026-06-15)
Strict-mode privileged mutating steps now FAIL CLOSED. Prior to Amendment D, three privileged
mutating operations — zero-window arm, checkpoint-image patch, and non-veth resolver — returned
nil on error and logged a warning, producing migrations that reported TCP preservation without
actually achieving it (false-green migrations). Amendment D converts all three to hard failures:
if any privileged mutating step cannot complete, the migration fails rather than continuing with
an incorrect state.
This eliminates the prior class of false-green migrations where tcpPreservationMode: Strict
reported TCP preservation that never actually occurred.
amd64 Strict-mode active-TCP preservation remains NOT proven. The Sprint 32 gate failed all proof attempts for amd64 Strict-mode active-TCP preservation. Amendment D hardens correctness; it does not establish that proof. Do not interpret this amendment as evidence that Strict-mode active-TCP preservation works on amd64. The proven scope remains: arm64 / Ubuntu 24.04 / kernel 6.8 / Flannel VXLAN only.
Enabling mTLS via Helm Values
Supply a CA certificate, a server certificate and key for the node agent, and a client certificate and key for the controller-manager. Reference them as Kubernetes Secrets:
mtls:
enabled: true
caSecretName: podmotion-mtls-ca # Secret with key: ca.crt
serverSecretName: podmotion-mtls-server # Secret with keys: tls.crt, tls.key (node agent)
clientSecretName: podmotion-mtls-client # Secret with keys: tls.crt, tls.key (controller-manager)
All three Secrets must exist in the podmotion-system namespace before the Helm release is
installed or upgraded.
Enabling mTLS via Environment Variables
If you manage certificate injection outside Helm, set the following environment variables on both the node-agent and controller-manager containers:
Node agent (server side):
PODMOTION_GRPC_TLS_ENABLED=true
PODMOTION_GRPC_TLS_CA_FILE=/etc/podmotion/tls/ca.crt
PODMOTION_GRPC_TLS_CERT_FILE=/etc/podmotion/tls/tls.crt
PODMOTION_GRPC_TLS_KEY_FILE=/etc/podmotion/tls/tls.key
Controller-manager (client side):
PODMOTION_GRPC_TLS_ENABLED=true
PODMOTION_GRPC_TLS_CA_FILE=/etc/podmotion/tls/ca.crt
PODMOTION_GRPC_TLS_CERT_FILE=/etc/podmotion/tls/tls.crt
PODMOTION_GRPC_TLS_KEY_FILE=/etc/podmotion/tls/tls.key
Mount the certificate files from a Kubernetes Secret into the container at the paths above.
State Summary
| mTLS configured | gRPC channel state |
|---|---|
| No (default) | Plaintext — unencrypted |
| Yes (Helm or env vars) | Option enabled — channel enforcement not guaranteed in v0.1.0-alpha (fails open) |
Admission Webhook TLS
Per ADR-0159 (Draft), the chart value webhook.certManager.enabled defaults to true. However,
the chart ships no Certificate or Issuer resource. Enabling this value leaves the admission
webhook without a TLS secret, and the webhook crashloops on startup. cert-manager ACME issuance
for the webhook is planned under ADR-0159 and is not implemented in v0.1.0-alpha.
For webhook TLS lifecycle, rotation, and failurePolicy behavior, see ADR-0079.
5. Vulnerability Disclosure
To report a security vulnerability in PodMotion:
- Do not open a public GitHub issue. Public disclosure before a fix is available puts all users at risk.
- Primary channel — email: Send a description of the vulnerability, steps to reproduce, and any proof-of-concept to security@podmotion.io.
- Equivalent encrypted path: Open a GitHub private security advisory on the podmotion-io/podmotion repository if you prefer encrypted browser-based submission.
SECURITY.md in the repository states this same channel and SLA; the two must not diverge.
Response SLA
The maintainer will acknowledge receipt within 72 hours and will target a fix within 90 days of acknowledgment for critical and high-severity findings.
Coordinated Disclosure Policy
PodMotion follows a coordinated disclosure model:
- The reporter submits the vulnerability privately.
- The maintainer acknowledges within 72 hours and begins triage.
- A fix is developed and validated in a private branch.
- A patch release is cut and published simultaneously with the public disclosure.
- CVE credit is provided to the reporter in the release notes and the CVE record.
The target fix window is 90 days from acknowledgment for critical and high-severity findings. For issues that require upstream changes (e.g., kernel or CRIU), the timeline will be communicated to the reporter as soon as the dependency is identified.
6. RBAC
No default least-privilege ClusterRoles ship with the PodMotion chart in v0.1.0-alpha.
The chart does not bundle a migration-operator or migration-reader ClusterRole in the
current release. Operators must provision any required RBAC bindings manually.
ADR-0078 defines the least-privilege boundary roadmap for the operator and node-agent
service accounts. ADR-0161 (Draft) plans default migration-operator and migration-reader
ClusterRoles as a pre-GA requirement. Neither is implemented today.
7. Supply Chain
No SBOM, no signed images, and no signed provenance are produced for v0.1.0-alpha.
As of v0.1.0-alpha there are NO signed images, NO SBOM, NO SLSA provenance, and NO published release checksums. Artifacts must be treated as unverified. The plan (ADR-0077, supersedes ADR-0103): cosign keyless image signing, CycloneDX SBOM via syft, SLSA L2 provenance, and a grype release-gate. Status: Accepted, unimplemented.
- Container images are not signed. No cosign signature or DSSE attestation is available.
- No SBOM (CycloneDX or SPDX) is generated or published for any released artifact.
- No SLSA provenance record exists for the v0.1.0-alpha build.
ADR-0077 (supersedes ADR-0103) defines the authoritative forward plan: cosign image signing, SBOM generation, and a vulnerability-disclosure process. ADR-0077 is not yet implemented.
Do not treat v0.1.0-alpha artifacts as having a verified supply chain. No published release checksums, signatures, or SBOM exist for v0.1.0-alpha. There is currently no supply-chain artifact to verify against. cosign keyless signing, CycloneDX SBOM (syft), and grype release-gate scanning are the authoritative forward plan under ADR-0077 (which supersedes ADR-0103); none are implemented yet. Treat v0.1.0-alpha artifacts as unverified.
8. Compliance Roadmap
The following items are planned under ADR-0161 (Draft, post-beta). None are implemented today.
- CNCF Security TAG self-assessment — a formal OpenSSF CII Best Practices + TAG Security self-assessment is a pre-GA requirement. Status: Planned / not yet drafted. Target: Pre-GA, Sprint 33–35 (per ADR-0161 sequencing recommendation, step 1). This is a BLOCKING sandbox-graduation gate — no regulated-framework work begins until this self-assessment clears. Not submitted or drafted.
- Default RBAC —
migration-operatorandmigration-readerClusterRoles (see §6 and ADR-0161). - Per-migration structured audit log — a structured audit record per
PodMigrationCR, distinct fromPhaseTransitionKubernetes events. Not implemented; theaudit/directory is currently empty. - Optional FIPS-140-2 validated crypto build — an opt-in build variant using BoringCrypto or a FIPS-validated KMS backend is planned under ADR-0161. Not implemented and not available in v0.1.0-alpha.
Compliance Framework Planning Horizon (ADR-0161 Draft)
Planning horizon only. None of the frameworks or controls below are implemented today.
PodMotion is infrastructure software, not a certified service — it cannot itself be certified; the goal is to not structurally block a customer's certification and to make evidence collection possible (ADR-0161).
The table below is sourced verbatim from ADR-0161 (Draft). No framework work begins before the CNCF Security TAG self-assessment gate is cleared.
| Framework | Target horizon | Notes |
|---|---|---|
| CNCF Security TAG self-assessment | BLOCKING — sandbox graduation gate | Pre-GA requirement; OpenSSF CII Best Practices + TAG Security self-assessment. Must be completed before any regulated-framework work begins. |
| SOC 2 Type II | GA+3mo readiness | Readiness gap analysis only; no audit engagement. |
| ISO 27001 | GA+6mo gap analysis | Gap analysis only; no certification body engagement. |
| HIPAA | GA+12mo | Alignment assessment; PodMotion is infrastructure, not a covered entity. |
| PCI DSS v4.0 | GA+12mo | Alignment assessment; PodMotion is infrastructure, not a QSA-assessed service. |
| FedRAMP Moderate + FIPS-140-2 build | GA+18mo | Requires FIPS-140-2 validated build toolchain (BoringCrypto or equivalent). |
No timeline above is a commitment or guarantee. Each horizon is a planning target under ADR-0161 (Draft).
Architectural Commitments Being Built (C1–C6)
The following controls are the architectural commitments recorded in ADR-0161 that underpin the framework horizons above. All are Draft/not-implemented as of v0.1.0-alpha.
| Commitment | Description | Status |
|---|---|---|
| C1 — Structured audit log | A structured audit record per PodMigration CR, distinct from PhaseTransition Kubernetes events. The audit/ directory is currently empty. | Draft / not implemented |
| C2 — RBAC-gated migration ops | Default migration-operator and migration-reader ClusterRoles shipped with the chart. No default least-privilege ClusterRoles ship today (see §6). | Draft / not implemented |
| C3 — Checkpoint encryption with key ref in MigrationCheckpoint status | AES-256-GCM checkpoint encryption (ADR-0160) with the key reference surfaced in the MigrationCheckpoint status field. Checkpoints are currently plaintext (see §3). | Draft / not implemented |
| C4 — TLS/mTLS on all control-plane communications | Enforced mutual TLS on the controller-manager ↔ node-agent gRPC channel. The option exists but fails open in v0.1.0-alpha (see §4). | Draft / not implemented |
| C5 — Checkpoint data-residency node-name in status | The node name where the checkpoint resides surfaced in the MigrationCheckpoint status to support data-residency audits. | Draft / not implemented |
| C6 — FIPS 140-2 validated crypto path | A FIPS 140-2 validated crypto module (e.g. BoringCrypto or an external FIPS-validated KMS) for the checkpoint encryption path — a build-time choice behind the ADR-0160 CheckpointCrypto interface; required only for FedRAMP Moderate. | Draft / not implemented |
PodMotion is currently maintained by a single maintainer (Chad N. Ingle, oanministries.org). This is an acknowledged risk (ADR-0091). The project roadmap targets multi-org maintainership as a pre-graduation requirement. See GOVERNANCE for the current maintainer-growth plan.
Security disclosures and coordinated disclosure policy are also linked from the Community section of the PodMotion website.