Class: Kube::Cluster::Middleware::SecurityContext

Inherits:
Kube::Cluster::Middleware show all
Defined in:
lib/kube/cluster/middleware/security_context.rb

Overview

Injects pod and container security contexts on pod-bearing resources.

Reads the app.kubernetes.io/security label. When the label is absent, the middleware applies the default profile.

Kube::Cluster["Deployment"].new {
  metadata.labels = { "app.kubernetes.io/security": "restricted" }
  ...
}

Available profiles: restricted (default), baseline.

stack do
  use Middleware::SecurityContext                      # default: restricted
  use Middleware::SecurityContext, default: :baseline  # change default
end

Constant Summary collapse

LABEL =
:"app.kubernetes.io/security"
PROFILES =
{
  "restricted" => {
    pod: {
      runAsNonRoot: true,
      runAsUser:    1000,
      runAsGroup:   1000,
      fsGroup:      1000,
      seccompProfile: { type: "RuntimeDefault" },
    },
    container: {
      allowPrivilegeEscalation: false,
      readOnlyRootFilesystem:   true,
      capabilities:             { drop: ["ALL"] },
    },
  },
  "baseline" => {
    pod: {
      runAsNonRoot: true,
      runAsUser:    1000,
      runAsGroup:   1000,
      fsGroup:      1000,
    },
    container: {
      allowPrivilegeEscalation: false,
    },
  },
}.freeze

Constants inherited from Kube::Cluster::Middleware

DEFAULT_FILTER

Instance Method Summary collapse

Methods inherited from Kube::Cluster::Middleware

build, #filter, #initialize

Constructor Details

This class inherits a constructor from Kube::Cluster::Middleware

Instance Method Details

#call(manifest) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/kube/cluster/middleware/security_context.rb', line 57

def call(manifest)
  default = @opts.fetch(:default, :restricted).to_s

  manifest.resources.map! do |resource|
    filter(resource) do
      next resource unless resource.pod_bearing?

      profile_name = resource.label(LABEL) || default
      profile = PROFILES.fetch(profile_name.to_s) do
        raise ArgumentError, "Unknown security profile: #{profile_name.inspect}. " \
          "Valid profiles: #{PROFILES.keys.join(', ')}"
      end

      h = resource.to_h
      pod_spec = resource.pod_template(h)
      next resource unless pod_spec

      pod_spec[:securityContext] = deep_merge(profile[:pod], pod_spec[:securityContext] || {})

      resource.each_container(pod_spec) do |container|
        container[:securityContext] = deep_merge(profile[:container], container[:securityContext] || {})
      end

      resource.rebuild(h)
    end
  end
end