Leveraging Service Accounts for Label-based Security

One of the key Kubernetes security concepts is that workload identity is tied back to information that the orchestrator has. The orchestrator is actually the authoritative entity for what the actual workloads are in the platform.

Kubernetes uses labels to select objects and to identify collections of objects that satisfy certain conditions. We, and others in the Kubernetes networking space, often talk about using Kubernetes ‘labels’ as identity bearers.  Label selectors are the primary thing that native Kubernetes network policy uses to identify the pods which a policy matches on. (Tigera Secure and Tigera’s Project Calico follow the same paradigm and provide even richer network policy capabilities using labels to identify collections of workloads.) Here is an example of a pod definition:

apiVersion: v1
kind: Pod
metadata:
  Labels:
    name: nginx
    frontend: server
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Kubernetes Role-Based Authentication (RBAC) allows for the ability to control who can manipulate individual API objects, some examples of which include Pods, Services, Deployments, and Service Accounts.  This means that it is possible to grant (or deny) a user or group of users the ability to manipulate given API objects (such as launch pods, destroy services, etc.)

It should be noted that labels are not an API object, but part of other API objects.  That means that if you grant a developer the permissions to create pods (create permissions on the Pod API object) they can add any labels that they want to that pod).

In many organizations, this is sufficient as there has to be a level of trust in the people actually creating and launching the workloads.  However, in some organizations, especially ones with multiple groups with their own security responsibilities, or organizations with specific requirements, such as compliance or regulatory concerns, not having the ability to control who can attach certain labels on workloads is a problem.

It would seem that it would be easy, from a network policy implementation perspective, to control what labels are honored, labels are used for many things in Kubernetes, not just network policy.  It could lead to confusion and chaos if certain parts of Kubernetes ‘honored’ a given label, and other parts of the platform did not.

A solution to this requirement comes in the form of another API object that can be attached to workloads in  Kubernetes is the service account. Below is an example of a service account API object, and pod with that service account:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-robot
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: build-robot
  Label: automation == “build”


Service accounts (since they are an API object) are discretely RBAC controlled which means that each service account can have its own RBAC permissions.  Furthermore, service accounts, like all other Kubernetes objects, can themselves have labels. This means that there is a fairly fine-grained RBAC controlled label artifact that is available in Kubernetes.

It happens that we at Tigera have extended our network policy implementation to use Service Accounts, and labels in service accounts as another ‘selector’ in our policy definition.

The following is an example of a Calico network policy, first matching a label, and next matching a service account can be seen below:

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-frontend
spec:
  selector: custDB == ‘server’
  types:
  - Ingress
  ingress:
  - action: Allow
    protocol: TCP
    source:
      selector: frontend == ‘server’
    destination:
      ports:
      - 8080
  

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-frontend
spec:
  selector: custDB == ‘server’
  types:
  - Ingress
  ingress:
  - action: Allow
    protocol: TCP
    source:
      serviceAccounts:
        selector: automation == ‘build’
    destination:
      ports:
      - 8080

There are some things to be aware of, when using service accounts, however.  Each pod can only have a single service account bound to it. You can think of a service account as being a unique pod identifier.
However, since service accounts can also be labeled (like any other Kubernetes API object).  This means that those labels can be used to create ‘groups’ of service accounts, just like label selectors for pods, services, network policies which follow standard Kubernetes practice.

Since Service Accounts are a separate API object, you can use RBAC to restrict which users can manipulate the service account and its labels.  This allows the designation of specific trusted entities (code and/or people) who can grant the necessary and required selectors (service account labels) to a given service account, and make that service account available in a given namespace.  This capability, available in both Tigera Secure and Tigra’s Project Calico, provides a tighter level of control over how policies are applied in your cluster.

————————————————-

Free Online Training
Access Live and On-Demand Kubernetes Tutorials

Calico Enterprise – Free Trial
Solve Common Kubernetes Roadblocks and Advance Your Enterprise Adoption

Join our mailing list

Get updates on blog posts, workshops, certification programs, new releases, and more!

X