PodMotion is alpha software (v0.1.0-alpha). APIs and behaviors may change without notice. Not recommended for production workloads.

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 ResourceExhausted against 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 DataLoss before 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_uid is rejected with PermissionDenied.

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

IDCriterionResult
GC-B1mTLS enforced + fail-closedPASS
GC-B2Per-RPC authorizationPASS
GC-B3gRPC message size capsPASS
GC-B4Checkpoint signingPASS
GC-B5Transfer integrityPASS
GC-B6Socket-state anti-replayPASS
GC-B7Full live migration regressionPASS
GC-B8Constitutional invariants heldPASS

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-0700 checkpoint tmpfs at /run/podmotion/checkpoints.
  • install-apparmor-profile (rendered whenever agent.apparmorProfile is not unconfined — the chart default is localhost/podmotion-agent, so it renders by default) — loads the narrow podmotion-agent AppArmor profile onto the node and reloads it via apparmor_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-inagent.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.

CapabilityJustification
SYS_PTRACECRIU attaches to and inspects the target process's memory and register state via ptrace(2).
SYS_ADMINCRIU namespace/mount operations (setns, unshare, mount/umount2, userfaultfd) during checkpoint and restore.
CHECKPOINT_RESTORECRIU 4.x kerndat init and checkpoint/restore-privileged operations; scopes CRIU privilege more narrowly than SYS_ADMIN (kernel 5.9+).
DAC_READ_SEARCHUnder 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_RESOURCECRIU reads the target's rlimits via prlimit64 across a credential boundary.
NET_ADMINManipulate network interfaces, routes and neighbor entries, and eBPF TC/XDP attach during TCP connection migration.
NET_RAWOpen the AF_PACKET socket used to send the gratuitous ARP at IP handoff.
KILLSignal (SIGCONT) the source workload tree, which runs under the container image's own non-root UID.
BPF, PERFMONeBPF 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.enabled defaults to false).
  • Replace the read-write containerd socket mount with a read-only mount where feasible.
  • hostPID: false via an NRI-supplied PID.
  • readOnlyRootFilesystem: true on 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:

ProviderDescription
noneDefault — no encryption; plaintext on tmpfs as today
aes-gcmSelf-managed KEK stored in a podmotion-system Secret; AES-256-GCM
aws-kmsEnvelope encryption via AWS KMS
gcp-kmsEnvelope encryption via GCP Cloud KMS
azure-kmsEnvelope encryption via Azure Key Vault
vaultEnvelope 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 configuredgRPC 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:

  1. The reporter submits the vulnerability privately.
  2. The maintainer acknowledges within 72 hours and begins triage.
  3. A fix is developed and validated in a private branch.
  4. A patch release is cut and published simultaneously with the public disclosure.
  5. 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 RBACmigration-operator and migration-reader ClusterRoles (see §6 and ADR-0161).
  • Per-migration structured audit log — a structured audit record per PodMigration CR, distinct from PhaseTransition Kubernetes events. Not implemented; the audit/ 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.

FrameworkTarget horizonNotes
CNCF Security TAG self-assessmentBLOCKING — sandbox graduation gatePre-GA requirement; OpenSSF CII Best Practices + TAG Security self-assessment. Must be completed before any regulated-framework work begins.
SOC 2 Type IIGA+3mo readinessReadiness gap analysis only; no audit engagement.
ISO 27001GA+6mo gap analysisGap analysis only; no certification body engagement.
HIPAAGA+12moAlignment assessment; PodMotion is infrastructure, not a covered entity.
PCI DSS v4.0GA+12moAlignment assessment; PodMotion is infrastructure, not a QSA-assessed service.
FedRAMP Moderate + FIPS-140-2 buildGA+18moRequires 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.

CommitmentDescriptionStatus
C1 — Structured audit logA structured audit record per PodMigration CR, distinct from PhaseTransition Kubernetes events. The audit/ directory is currently empty.Draft / not implemented
C2 — RBAC-gated migration opsDefault 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 statusAES-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 communicationsEnforced 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 statusThe 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 pathA 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.