Policies

Introduction

We provide a set of policies, which help you enforce operational and security best practices in your clusters. Those policies can be used to give feedback directly on GitHub Pull Requests, so you can conveniently see the validation errors annotated in the source files. Additionally, it is possible to enforce policies with a Kubernetes admission controller that denies any changes to manifests that are not compliant with the activated policies.

Prerequisites

This guide assumes that you already completed the getting started guide, and that you have at least one cluster configured for use with Syncier Security Tower. We are now going to activate a policy for this cluster.

Configuration of the Policy Location

When you activate your first policy, Syncier Security Tower wants to create several files which describe what the policy does. Those files must be stored somewhere in a GitHub repository you and Syncier Security Tower have access to. This could be any repository which you would like to use, for example you could have a central repository with all mandatory policies for your organization. For this guide we will use the GitOps repository of your cluster, which should already exist and contain the manifests you deploy to Kubernetes.

Locate the yaml configuration file of your cluster, which you created in the installation guide. You should find it in the .securitytower directory of your repository. Add the following configuration to the spec field:

# .securitytower/my-cluster.yaml
apiVersion: securitytower.io/v1alpha1
kind: Cluster
[...]
spec:
  policies:
    path: policies

As you can see, we will store the policies in a directory called policies located in the root of the repository. This path is arbitrary but make sure to sync its content to your cluster. You could also use a different repository and revision, see the cluster config reference for details. Please commit the change to the cluster.yaml to your repository.

Configuration of the Namespace Locations

There are different ways to set up GitOps for your Kubernetes clusters. However, often the namespace definitions are put into one place. From there, they are synced into the cluster by a GitOps tool like Argo CD or Flux. In order to make Security Tower aware of these locations

# .securitytower/my-cluster.yaml
apiVersion: securitytower.io/v1alpha1
kind: Cluster
[...]
spec:
  policies:
    path: policies
  namespaces:
    - path: namespace-specs

Define as many locations as you want to. In the example, Security Tower will look into the directory namespace-specs of the default branch in the same repository.

This is especially important as there are policies that have to take namespace annotations into account. This is the case for ImageAllowlist configuration and the risk acceptance annotations on namespace level.

Activating Your First Policy

Now open up Syncier Security Tower and select your cluster from the list. You should see a tab called Policies on the top of the screen. When you open up this tab, Syncier Security Tower will show a list of all available policies. For this guide we will activate the policy EnforceImageVersion. Please locate this policy in the list, and click on its name to open up a screen with details. You can see a basic description of the policy and also some information about how to create a Risk Acceptance, which will be introduced later.

Now it is time to activate the policy. Close the details view and click the Edit policies button on the bottom of the screen. You can change the state of the EnforceImageVersion policy by clicking on the icon in the left column of the table. Set it from Inactive to Active and click Update Policies. A blue box with a message should appear on the bottom of the screen which contains a link to the Pull Request which has been created to activate the policy. Follow the link to merge this PR in otder to take the policy into effect!

Merging the PR

Receiving Pull Request Feedback

Let's run a test to see how the policy validation works. We activated a policy that verifies that all container images specify an explicit version, so let's try to create a container that violates this policy. Create a new branch in your cluster repository, and add the following manifest to it:

# no-image-version.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: no-image-version-deployment
  labels:
    app: no-image-version
spec:
  selector:
    matchLabels:
      app: no-image-version
  template:
    metadata:
      labels:
        app: no-image-version
    spec:
      containers:
        - name: nginx
          # No version specified, which means it would pull the `latest` tag from the registry.
          image: nginx
          ports:
            - containerPort: 80

Commit this file to your branch, and create a new Pull Request on GitHub. Wait for a couple of seconds for Syncier Security Tower to pick up the changes. After the Pull Request Check is completed, you should be able to see the results. You can see that the validation failed because we did not specify an image version. The manifest has also been annotated with the error.

Pull Request feedback

Next Steps

Congratulations, you have successfully activated your first policy, and received feedback on a Pull Request!

There are many topics which you might want to discover from here, for example:

  • Configuring your GitHub repository with branch protection and mandatory PR checks.
  • In addition to getting Pull Request feedback, you can enforce policies with OPA Gatekeeper in your cluster.
  • In case it is not possible to make a manifest complaint with a policy, you can define a Risk Acceptance.

Please see enforcing policies with OPA Gatekeeper for details.