← Policy catalog
</> ValidatingAdmissionPolicy · Apache-2.0

Attaches More Than One Image Pull Secret

serviceaccount-imagepullsecrets-scope

severityModerate resourceServiceAccounts productKubernetes bundles1

Attaching several registry credentials to one ServiceAccount hands all of them to every pod that uses it, so one compromised workload exposes registry logins it never needed to pull its own image.

Rejects unless

!has(object.imagePullSecrets) || size(object.imagePullSecrets) <= 1

Limit imagePullSecrets on ServiceAccounts; avoid sharing powerful registry creds broadly.

Remediation

Reduce the ServiceAccount to at most one imagePullSecret and create separate ServiceAccounts for workloads that need a different registry. Field: imagePullSecrets.

Applies to

  • serviceaccounts · v1 · CREATE, UPDATE

Manifest

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: serviceaccount-imagepullsecrets-scope
  annotations:
    kubeapt.io/uuid: "352c743b-54a7-479c-9cf2-71d049ba7fc7"
    security.kubeapt.io/displayName: "Attaches More Than One Image Pull Secret"
    security.kubeapt.io/description: "Attaching several registry credentials to one ServiceAccount hands all of them to every pod that uses it, so one compromised workload exposes registry logins it never needed to pull its own image."
    security.kubeapt.io/resource: "ServiceAccounts"
    security.kubeapt.io/severity: "Moderate"
    security.kubeapt.io/remediation: "Reduce the ServiceAccount to at most one imagePullSecret and create separate ServiceAccounts for workloads that need a different registry. Field: imagePullSecrets."
    security.kubeapt.io/product: "Kubernetes"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:
      - ''
      apiVersions:
      - v1
      operations:
      - CREATE
      - UPDATE
      resources:
      - serviceaccounts
  validations:
  - expression: |
      !has(object.imagePullSecrets) || size(object.imagePullSecrets) <= 1
    message: |
      Limit imagePullSecrets on ServiceAccounts; avoid sharing powerful registry creds broadly.

Save it as serviceaccount-imagepullsecrets-scope.yaml — the commands below assume that name.

Validate with kubeapt

Check a workload against this one policy, before anything is installed on a cluster.

$ kubeapt validate -p ./serviceaccount-imagepullsecrets-scope.yaml -r ./workload.yaml

Or without the file, from the published policy set — -r takes a directory too:

$ kubeapt policies download && kubeapt validate --policy-name serviceaccount-imagepullsecrets-scope -r ./manifests

Or against every namespace in the cluster your kubeconfig points at:

$ kubeapt validate --policy-name serviceaccount-imagepullsecrets-scope -A