Shoulder.dev Logo Shoulder.dev

Implementing Security Policies with FluxCD

Scenario: A developer wants to implement security policies using FluxCD in a real-world application. In this example, we will use FluxCD’s GitOps workflow to manage Kubernetes manifests and enforce security policies by syncing desired state from a Git repository.

First, let’s set up the environment:

  1. Create a new Git repository for managing Kubernetes manifests and security policies.
$ mkdir flux-security
$ cd flux-security
$ git init
  1. Create a new directory for the kustomization.yaml file and initialize it with a basic configuration.
$ mkdir manifests
$ cd manifests
$ touch kustomization.yaml
$ kubectl init --kustomize=../ > ../flux-manifests.yaml
  1. Add the FluxCD repository as a remote to your Git repository.
$ git remote add fluxcd https://github.com/fluxcd/flux.git

Now, let’s create a security policy using FluxCD:

  1. Create a new directory for the security policy and initialize it with a basic configuration.
$ mkdir policies
$ cd policies
$ touch allow-egress.yaml
  1. Define the security policy in the allow-egress.yaml file.
apiVersion: security.fluxcd.io/v1beta1
kind: PodSecurityPolicy
metadata:
name: allow-egress
spec:
allowPrivilegeEscalation: false
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
seccompProfile:
rule: RunAsAny
volumes:
- hostPath:
path: /var/run/docker.sock
readOnly: false
- hostPath:
path: /etc/resolv.conf
readOnly: true
- secret:
secretName: my-secret
readOnlyRootFilesystem: false
  1. Commit the changes to the Git repository.
$ git add .
$ git commit -m "Add allow-egress PodSecurityPolicy"
  1. Create a kustomization.yaml file in the policies directory to include the security policy in the FluxCD sync.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../manifests/kustomization.yaml
- policies/
  1. Commit the changes to the Git repository.
$ git add .
$ git commit -m "Add policies directory and kustomization.yaml"
  1. Create a FluxCD flux.yaml configuration file in the root directory of your Git repository.
apiVersion: flux.tools/v1beta1
kind: Flux
controllers:
- name: git
source:
git:
url: https://github.com/<your-username>/flux-security.git
branch: main
directory:
path: manifests
recursive: true
sync:
interval: 30s
git:
path: kustomization.yaml
prune: true
commitStrategy: OnCreate

Replace <your-username> with your GitHub username.

  1. Commit the changes to the Git repository.
$ git add .
$ git commit -m "Add FluxCD configuration"

Now, let’s test the FluxCD sync and security policy:

  1. Initialize FluxCD in your Git repository.
$ flux init --repo=https://github.com/<your-username>/flux-security.git --path=.

Replace <your-username> with your GitHub username.

  1. Verify that the FluxCD sync is working.
$ flux status sync
  1. Verify that the security policy has been applied to your Kubernetes cluster.
$ kubectl get podsecuritypolicies
NAME                AGE
allow-egress         1m
default             1m

Tests:

  1. Verify that the FluxCD sync is working by checking the logs.
$ journalctl -u fluxd
  1. Verify that the security policy is applied to new pods by creating a new pod and checking its security context.
$ kubectl create deployment test --image=nginx
$ kubectl get pod test -o yaml
  1. Verify that the security policy is enforced by attempting to create a pod with an invalid security context.
$ kubectl create deployment test2 --image=nginx --security-context='runAsUser:0'

This will fail with an error message indicating that the security policy is not allowing the specified security context.

  1. Verify that the security policy can be updated by committing changes to the Git repository and syncing the FluxCD configuration.
$ git checkout policies/allow-egress.yaml
$ # Make some changes to the security policy
$ git add .
$ git commit -m "Update allow-egress PodSecurityPolicy"
$ flux status sync
  1. Verify that the updated security policy is applied to new pods by creating a new pod and checking its security context.
$ kubectl create deployment test3 --image=nginx
$ kubectl get pod test3 -o yaml

The new pod should have the updated security context defined in the allow-egress.yaml file.