Skip to content

Make the Restricted workload profile usable and limit agent credentials to the agent #714

Open

Description

@Baylem

Setting podSecurity.enforceRestricted=true labels the games namespace but does not make generated game pods satisfy Restricted admission. On a cluster enforcing PSA without exemptions or a mutating admission layer, normal game pods are rejected, including templates specifying a nonroot UID. Operators currently cannot obtain the advertised namespace hardening simply by enabling the option.

This is static inspection of 04e41075cafc4c1a99bcb3723b0a8745ee810957, not a runtime reproduction. It follows #503, which corrected documentation to describe existing game-container defaults. The issue requests a working opt-in profile plus related in-pod credential hardening; it does not claim a PSA bypass or proven node escape.

Evidence:

Recommended implementation:

  1. Wire an explicit workload-security profile into reconciliation and validate module compatibility before admission failure. Apply appropriate nonroot identities, volume ownership, seccomp, capability drops, and escalation restrictions to game and init containers. For compatible images:
# Fragment of PodSpec; select compatible per-container UIDs.
securityContext:
  runAsNonRoot: true
  seccompProfile: {type: RuntimeDefault}
containers:
  - name: game
    securityContext:
      runAsUser: 1000
      allowPrivilegeEscalation: false
      capabilities: {drop: [ALL]}
initContainers:
  - name: config-init
    securityContext:
      runAsUser: 1000
      allowPrivilegeEscalation: false
      capabilities: {drop: [ALL]}
  1. Reject incompatible capture requests with a clear condition, or explicitly design a separately authorized exception profile. Do not weaken the whole namespace implicitly. Select a supported PSA version policy instead of unexplained latest drift.
  2. Disable pod-level service-account token automount. Project a short-lived token, CA certificate, and namespace only into the agent at its existing client configuration paths, preserving rotation and the narrow per-server Role. Game/config-init containers need no API credentials.
  3. Make shared PID namespace a deliberate profile decision. Agent-only volume mounts are insufficient as a strict credential boundary when /proc/<pid>/root is accessible under Unix/process permissions. Preserve metrics through a compatible alternative or document the profile's remaining in-pod trust assumption. Agent leaf certificates are ServerAuth-only, so their theft does not automatically authenticate a client to other agents.

Acceptance criteria:

  • CI admits representative game/config-init pods under enforced Restricted PSA and verifies startup, writable data, and upgrades.
  • Incompatible modules/capture produce actionable errors before repeated failed pod creation; compatible existing installs have a documented migration path.
  • Game and init containers lack mounted API tokens; agent heartbeats survive projected-token rotation.
  • Security checks cover every regular, init, and optional ephemeral container and verify the chosen process-sharing behavior.
  • Documentation distinguishes Restricted compliance, namespace isolation, and the residual trust shared by containers within one pod.

Activity

  1. ValgulNecron commented on Oct 20, 2026

    @ValgulNecron
    Collaborator

    Thanks, confirmed on master: podSecurity.enforceRestricted only labels the games namespace (charts/gameplane/templates/namespaces.yaml:8-10), while the game and config-init containers set none of the fields Restricted requires (operator/internal/controller/gameserver_controller.go:2136-2144, buildConfigInitContainer), so turning it on makes game pods fail admission. The game container also gets the agent ServiceAccount token mounted.

    Go ahead with a PR. Decisions on the open points:

    • Hardening: set runAsNonRoot, allowPrivilegeEscalation: false, capabilities.drop: [ALL] and seccompProfile: RuntimeDefault on the game and config-init containers when the profile is on, and stop exposing the agent's ServiceAccount token to the game container (only the agent should have it).
    • Packet capture: don't simply reject it. Add a separately authorized admin exception so an admin can still run a capture on a hardened server. Keep it explicit, audited and off by default, and make the boundary trade-off clear in the docs.
    • Shared PID namespace: keep it (the agent reads the game's /proc for CPU and memory), and document the in-pod trust assumption in docs/security.md.
    • Pod Security version: replace enforce-version: latest with a pinned, tested version that admins can override in values, so a Kubernetes upgrade can't silently start rejecting game pods.

    Please also correct docs/security.md:370-372 in the same PR: it currently tells hostile-module operators to enable enforceRestricted, which breaks game pods until this lands.

  2. Baylem commented on Oct 25, 2026

    @Baylem
    MemberAuthor

    Implemented in #764: compatible Restricted workloads, agent-only token projection, pinned overridable PSA version, and an audited administrator node-capture exception. Shared PID remains for metrics and the remaining in-pod trust assumptions are documented. The latest follow-up revalidates diagnostic namespace authorization throughout the capture lifecycle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions