Skip to content

API Server (Authn/Authz)

Authentication

Component Description
Anonymous Auth By default, anonymous auth is enabled
  • Enabling anonymous access to discovery endpoints could increase the likelihood of leaking information about the software that's running
  • It is not reckless to allow anonymous access if using RBAC, which by default permit only limited API access for anonymous users
  • Explicitly grant RBAC privileges to system:anonymous user and system:unauthenticated group
Disable anonymous authentication (restrict API access to known, authenticated users)
  • kube-apiserver ... --anonymous-auth=false
  • --authorization-mode=RBAC (enable RBAC authorization module)
Authentication Strategies Prefer OpenID Connect or X509 Client Certificate-based auth
  • Use at least two methods:
    • service account tokens for service accounts
    • OpenID/x509 for user authentication
$ kube-apiserver
  --oidc-issuer-url="https://domain/.well-known/openid-configuration" \
  --oidc-client-id="example"
$ kube-apiserver
  --client-ca-file=/path/to/ca.crt           \
  --tls-cert-file=/path/to/server.crt        \
  --tls-private-key-file=/path/to/server.key

Authorization

Component Description
Verify roles
  • 🗒️ Check what roles are predefined and available: $ kubectl get clusterroles
  • 🗒️ Describe the default cluster role: $ kubectl describe clusterrole view
  • 🗒️ Verify granted permissions:
    • $ kubectl --namespace=coolapp auth can-i --as=system:serviceaccount:coolapp:myappid list pods (yes)
    • $ kubectl --namespace=coolapp auth can-i --as=system:serviceaccount:coolapp:myappid list services (no)
RBAC By default, auth mode is to always authorize all requests to kube-apiserver
  • Not recommended: $ kube-apiserver ... --authorization-mode=AlwaysAllow
Enable RBAC
  • Recommended: kube-apiserver ... --authorization-mode=RBAC
Default Service Account By default, the default service account is automatically mounted in the file system of all containers
Disable auto-mounting of the default service account token
  • The default service account token can be used to query the Kubernetes API
  • Without RBAC, this token can be used to do virtually anything in the cluster
  • You can specify automountServiceAccountToken: false in the PodSpec, or you can patch the default service account so that its credentials are not automatically mounted into pods
  • Recommended: $ kubectl patch serviceaccount default -p "automountServiceAccountToken: false"
Use dedicated service accounts
  • If an application needs access to the API server, create a dedicated service account per application and configure RBAC to be specifically limited to the needs of that application
  • If a pod is compromised, the attacker will have access to the service account associated with that pod, and its corresponding permissions
Impersonation Kubernetes has a feature that allows any user to impersonate any other user on the cluster
Limit who can impersonate and what they can do as impersonated users

$ kubectl drain test-node
Error from server (Forbidden): User "foo" cannot get nodes at the cluster scope

$ kubectl drain test-node --as=admin --as-group=system:admins
node "test-node" cordoned
node "test-node" drained
Not recommended:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: impersonator
rules:
# allows users to impersonate any "users", "groups", and "serviceaccounts"
- apiGroups: [""]
  resources: ["users", "groups", "serviceaccounts"]
  verbs: ["impersonate"]

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: limited-impersonator
rules:
# Can impersonate the group "developers"
- apiGroups: [""]
  resources: ["groups"]
  verbs: ["impersonate"]
  resourceNames: ["developers"]

Admission Controls

Component Description
Attaching If pods are scheduled with the following, it is possible to escalate via attach/exec
  • privileged: true
  • hostPID: true
  • hostIPC: true
Deny privilege escalation via interactive shells or attaching to privileged containers
  • There are some cases when you need to run privileged containers to interact with the host, but users can potentially kubectl attach or kubectl exec into those privileged containers
  • Recommended: $ kube-apiserver ... --admission-control=...,DenyEscalatingExec
Pull Images Always pull images
  • Kubernetes will cache container images that have been pulled from any registry
  • Any cached container images can be re-used by any pod on the cluster, meaning pods could gain unauthorized access to potentially sensitive information
  • Forcing Kubernetes to always pull images will require that the credentials needed to pull down images from private registries are provided by each requesting resource
  • Recommended: $ kube-apiserver ... --admission-control=...,AlwaysPullImages
Pod Security Policies Enable Pod Security Policies
  • Pod Security Policies are security rules that pods have to abide by in order to be scheduled
    • A pod security policy is a cluster-wide resource that allows you to enforce the usage of security contexts. The API server automatically enforces those policies for you, using admission controllers
    • If a pod’s specification doesn’t meet the requirements of the pod security policy, it won’t be run
  • Note that for pod security policies to take effect, the PodSecurityPolicy admission plugin must be enabled, and permission must be grated to use that policy for the appropriate users
  • Recommended: $ kube-apiserver ... --admission-control=...,PodSecurityPolicy

Types of Pod Security Policies

Disallow privileged containers
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  privileged: false
Disallow sharing of the host process ID namespace
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  hostPID: false
Disallow sharing of the host IPC namespace (memory)
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  hostIPC: false
Disallow sharing of the host network stack
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  hostNetwork: false
Whitelist allowable volume types
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  # It's recommended to allow the core volume types.
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    # Assume that persistentVolumes set up by the cluster admin are safe to use.
    - 'persistentVolumeClaim'
Require containers to run as non-root user
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  runAsUser:
    # Require the container to run without root privileges.
    rule: 'MustRunAsNonRoot'
  supplementalGroups:
    rule: 'MustRunAs'
    ranges:
      # Forbid adding the root group.
      - min: 1
        max: 65535
Set defaultAllowPrivilegeEscalation to false
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  defautlAllowPrivilegeEscalation: false
Apply selinux, seccomp, or apparmor profiles
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
  annotations:
    # applying default seccomp and apparmor profiles
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'
    apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
    seccomp.security.alpha.kubernetes.io/defaultProfileName:  'docker/default'
    apparmor.security.beta.kubernetes.io/defaultProfileName:  'runtime/default'