Integrate OPA Gatekeeper with ArgoCD for GitOps policy management

Advanced 45 min Apr 23, 2026 104 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up Open Policy Agent Gatekeeper with ArgoCD to enforce Kubernetes admission policies through GitOps workflows. This tutorial covers installation, policy template creation, and automated policy enforcement with monitoring.

Prerequisites

  • Running Kubernetes cluster with admin access
  • kubectl configured
  • Helm 3 installed
  • Git repository access
  • Basic Kubernetes and RBAC knowledge

What this solves

Open Policy Agent (OPA) Gatekeeper provides Kubernetes admission control through customizable policies, while ArgoCD enables GitOps-based continuous deployment. Integrating these tools creates a comprehensive policy-as-code system where security policies, resource quotas, and compliance rules are version-controlled and automatically enforced across your Kubernetes clusters.

This setup is essential for organizations requiring centralized policy management, compliance automation, and secure multi-tenant Kubernetes environments where policy changes must be auditable and consistently applied.

Prerequisites

  • Running Kubernetes cluster with cluster-admin access
  • kubectl configured and connected to your cluster
  • Helm 3 installed
  • Git repository for storing policy definitions
  • Basic understanding of Kubernetes RBAC and admission controllers

Step-by-step installation

Install OPA Gatekeeper

Deploy Gatekeeper using the official manifest. This creates the admission webhook, constraint templates, and controller components.

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.14/deploy/gatekeeper.yaml

Verify the Gatekeeper pods are running:

kubectl get pods -n gatekeeper-system
kubectl wait --for=condition=Ready pods --all -n gatekeeper-system --timeout=300s

Install ArgoCD

Create the ArgoCD namespace and deploy the controller. This provides the GitOps engine for managing policy deployments.

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Wait for ArgoCD components to be ready:

kubectl wait --for=condition=Ready pods --all -n argocd --timeout=600s

Configure ArgoCD access

Get the initial admin password and set up port forwarding to access the ArgoCD UI.

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo

Start port forwarding in the background:

kubectl port-forward svc/argocd-server -n argocd 8080:443 &

Access ArgoCD at https://localhost:8080 with username admin and the password from the previous command.

Create policy repository structure

Set up a Git repository with the proper directory structure for Gatekeeper policies. This enables version control and GitOps workflows for policy management.

mkdir -p gatekeeper-policies/{templates,constraints,config}
cd gatekeeper-policies

Create constraint template for required labels

Define a reusable policy template that enforces required labels on Kubernetes resources. This template uses Rego language for policy logic.

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        type: object
        properties:
          labels:
            type: array
            items:
              type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels
        
        violation[{"msg": msg}] {
          provided := input.review.object.metadata.labels
          required := input.parameters.labels
          missing := required[_]
          not provided[missing]
          msg := sprintf("Missing required label: %v", [missing])
        }

Create resource quota constraint template

Define a template for enforcing resource limits on containers to prevent resource exhaustion attacks and ensure fair resource allocation.

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8scontainerlimits
spec:
  crd:
    spec:
      names:
        kind: K8sContainerLimits
      validation:
        type: object
        properties:
          cpu:
            type: string
          memory:
            type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8scontainerlimits
        
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.resources.limits.cpu
          msg := "Container must have CPU limits"
        }
        
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.resources.limits.memory
          msg := "Container must have memory limits"
        }
        
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          cpu_limit := container.resources.limits.cpu
          cpu_limit > input.parameters.cpu
          msg := sprintf("CPU limit %v exceeds maximum %v", [cpu_limit, input.parameters.cpu])
        }

Create policy constraints

Define specific constraint instances that apply the templates to namespaces. These constraints enforce the actual policies in your cluster.

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: must-have-app-labels
spec:
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds: ["Deployment", "StatefulSet", "DaemonSet"]
    excludedNamespaces: ["kube-system", "gatekeeper-system", "argocd"]
  parameters:
    labels: ["app", "version", "environment"]
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sContainerLimits
metadata:
  name: container-must-have-limits
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
      - apiGroups: ["apps"]
        kinds: ["Deployment", "StatefulSet", "DaemonSet"]
    excludedNamespaces: ["kube-system", "gatekeeper-system", "argocd"]
  parameters:
    cpu: "2000m"
    memory: "4Gi"

Create Gatekeeper configuration

Configure Gatekeeper to exclude system namespaces from policy enforcement and set up audit intervals for compliance reporting.

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: gatekeeper-system
spec:
  match:
    - excludedNamespaces: ["kube-system", "gatekeeper-system", "argocd"]
      processes: ["*"]
  validation:
    traces:
      - user:
          kind:
            group: "*"
            version: "*"
            kind: "*"
  audit:
    auditInterval: 60s

Initialize Git repository

Initialize the policy repository and commit your policy definitions for GitOps management.

git init
git add .
git commit -m "Initial Gatekeeper policies"
git branch -M main
git remote add origin https://github.com/yourusername/gatekeeper-policies.git
git push -u origin main

Create ArgoCD application for Gatekeeper policies

Define an ArgoCD application that watches your policy repository and automatically deploys changes to the cluster.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: gatekeeper-policies
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/yourusername/gatekeeper-policies.git
    targetRevision: main
    path: .
  destination:
    server: https://kubernetes.default.svc
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Apply the ArgoCD application:

kubectl apply -f argocd-gatekeeper-app.yaml

Configure policy monitoring

Set up monitoring for policy violations using Prometheus and Grafana. Gatekeeper exports metrics about constraint violations and audit results.

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: gatekeeper-controller-manager
  namespace: gatekeeper-system
spec:
  endpoints:
  - interval: 30s
    path: /metrics
    port: http
  selector:
    matchLabels:
      control-plane: controller-manager
      gatekeeper.sh/operation: webhook

Apply the service monitor if you have Prometheus Operator installed:

kubectl apply -f gatekeeper-servicemonitor.yaml

Set up policy violation alerts

Create Prometheus alerting rules for policy violations to ensure compliance issues are immediately visible to your team.

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: gatekeeper-violations
  namespace: gatekeeper-system
spec:
  groups:
  - name: gatekeeper.rules
    rules:
    - alert: GatekeeperViolations
      expr: gatekeeper_violations > 0
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "Gatekeeper policy violations detected"
        description: "{{ $labels.violation_kind }} has {{ $value }} policy violations"
    
    - alert: GatekeeperAuditDuration
      expr: gatekeeper_audit_duration_seconds > 300
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "Gatekeeper audit taking too long"
        description: "Audit cycle is taking {{ $value }} seconds"

Apply the alerting rules:

kubectl apply -f gatekeeper-alerts.yaml

Configure GitOps workflow

Set up policy review process

Create a branch protection rule and review process for policy changes. This ensures all policy modifications are reviewed before deployment.

name: Validate Gatekeeper Policies

on:
  pull_request:
    paths:
      - 'templates/**'
      - 'constraints/**'
      - 'config/**'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup kubectl
      uses: azure/setup-kubectl@v3
      with:
        version: 'v1.28.0'
    
    - name: Validate constraint templates
      run: |
        for template in templates/*.yaml; do
          kubectl --dry-run=server apply -f "$template" || exit 1
        done
    
    - name: Validate constraints
      run: |
        for constraint in constraints/*.yaml; do
          kubectl --dry-run=server apply -f "$constraint" || exit 1
        done

Create policy testing framework

Set up automated testing for your policies using conftest to validate that policies work as expected before deployment.

curl -L https://github.com/open-policy-agent/conftest/releases/latest/download/conftest_Linux_x86_64.tar.gz | tar xz
sudo mv conftest /usr/local/bin
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-app
  labels:
    app: test-app
    version: v1.0.0
    environment: testing
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-app
  template:
    metadata:
      labels:
        app: test-app
    spec:
      containers:
      - name: app
        image: nginx:1.21
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 100m
            memory: 128Mi
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bad-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bad-app
  template:
    metadata:
      labels:
        app: bad-app
    spec:
      containers:
      - name: app
        image: nginx:1.21

Verify your setup

Test that your OPA Gatekeeper and ArgoCD integration is working by deploying test applications and verifying policy enforcement.

# Check Gatekeeper status
kubectl get constrainttemplates
kubectl get k8srequiredlabels
kubectl get k8scontainerlimits

Check ArgoCD application status

kubectl get applications -n argocd

Test policy enforcement with a non-compliant deployment

kubectl apply -f tests/deployment-invalid.yaml

Check constraint violations

kubectl get k8srequiredlabels must-have-app-labels -o yaml kubectl get events --field-selector reason=ConstraintViolation

Monitor policy violations through the Gatekeeper audit system:

# Check audit results
kubectl logs -n gatekeeper-system -l control-plane=audit-controller

View policy violation metrics

kubectl port-forward -n gatekeeper-system svc/gatekeeper-controller-manager-metrics-service 8443:8443 & curl -k https://localhost:8443/metrics | grep gatekeeper_violations

Common issues

SymptomCauseFix
Constraint template not found Template not applied or invalid Rego kubectl logs -n gatekeeper-system -l control-plane=controller-manager for errors
ArgoCD sync fails Invalid YAML or RBAC issues Check ArgoCD logs: kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller
Policies not enforcing Webhook not configured or namespace excluded Verify webhook: kubectl get validatingwebhookconfiguration gatekeeper-validating-webhook-configuration
High audit duration Too many resources to audit Increase audit interval in config or exclude more namespaces
Policy conflicts Multiple constraints affecting same resources Review constraint match criteria and use enforcementAction: dryrun for testing

Production considerations

For production deployments, consider implementing these additional security and operational measures:

Important: Start with enforcementAction: dryrun on new policies to identify violations without blocking deployments. Monitor audit logs for a week before switching to deny mode.
  • Use separate Git repositories for different environments (dev/staging/prod policies)
  • Implement policy signing and verification for supply chain security
  • Set up automated backup of Gatekeeper configurations
  • Configure resource limits for Gatekeeper controllers to prevent resource exhaustion
  • Use external data sources for dynamic policy parameters

For enhanced monitoring, integrate with your existing observability stack by configuring Prometheus monitoring for ArgoCD and setting up comprehensive alerting rules for both policy violations and system health.

Consider implementing advanced Kubernetes security by combining Gatekeeper with Pod Security Standards for defense-in-depth protection.

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. Our managed platform covers monitoring, backups and 24/7 response by default.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.