Open Policy Agent (OPA) est un moteur de policies généraliste, projet CNCF Graduated depuis février 2021. Son principe est de découpler la prise de décision de policies de son application : OPA expose une API REST qui évalue des règles écrites en Rego (langage déclaratif propre à OPA) et retourne une décision. Il n'est pas limité à Kubernetes - OPA est utilisé pour l'autorisation d'APIs REST, l'accès aux données, la validation d'infrastructure Terraform, ou comme moteur de policies dans les service meshes (Envoy/Istio).
Dans Kubernetes, OPA s'utilise le plus souvent via Gatekeeper (admission controller), mais peut aussi être déployé en sidecar ou service autonome.
Informations essentielles
Origine : Styra → CNCF · Licence : Apache 2.0 · Architectures : x86_64, ARM64
Liens : Site officiel · Documentation · GitHub · Releases
Support : CNCF Graduated depuis février 2021. Releases fréquentes.
Stack par défaut
| Composant | Valeur |
|---|---|
| Langage | Rego (déclaratif, inspiré de Datalog) |
| Interface | API REST (/v1/data, /v1/query) ou bibliothèque embarquée |
| Deployment | Binaire standalone, sidecar, ou bibliothèque Go |
| Bundles | Policies et données distribuées en bundle OCI/HTTP |
| Decision log | Audit de toutes les décisions prises |
Concepts clés
| Concept | Description |
|---|---|
| Policy | Fichier .rego définissant des règles avec allow/deny/violation |
| Data | Données contextuelles (JSON) chargées pour évaluer les policies |
| Input | Données de la requête courante (ex: token JWT, manifest K8s) |
| Bundle | Archive de policies + data distribuée via HTTP ou OCI |
| Decision Log | Journal de toutes les décisions OPA (audit trail) |
| Rego Playground | Interface web pour tester les policies en ligne |
Prérequis
| Ressource | Valeur |
|---|---|
| OS | Linux, macOS, Windows |
| Mémoire | 128 Mi minimum (selon la taille des policies/data) |
| Réseau | Accès HTTP pour charger les bundles (si utilisé) |
Installation
CLI OPA (pour développement et tests)
# Linux amd64
curl -Lo opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64_static
chmod +x opa
sudo mv opa /usr/local/bin/
opa version
OPA comme service REST
# Démarrer OPA en mode serveur avec une policy
opa run --server \
--addr 0.0.0.0:8181 \
--log-level info \
my-policies/
# Tester
curl http://localhost:8181/v1/data/
OPA dans Kubernetes (sidecar ou Deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-with-opa
spec:
template:
spec:
containers:
- name: my-app
image: my-app:latest
# OPA comme sidecar d'autorisation
- name: opa
image: openpolicyagent/opa:latest-static
args:
- run
- --server
- --addr=localhost:8181
- --config-file=/etc/opa/config.yaml
volumeMounts:
- name: opa-policies
mountPath: /etc/opa/policies
volumes:
- name: opa-policies
configMap:
name: opa-policies
Vérification de l'installation
# 1. Version
opa version
# OPA x.y.z (et Go version)
# 2. Évaluer une policy simple
echo '{"input": {"user": "alice", "action": "read"}}' | \
opa eval -d - 'data.example.allow' --format pretty
# 3. Démarrer le serveur et tester le health check
opa run --server &
curl http://localhost:8181/health
# {"status": "ok"}
# 4. Test d'une policy via API REST
curl -s http://localhost:8181/v1/data/system/main \
-H "Content-Type: application/json" \
-d '{"input": {"method": "GET", "path": "/api/data"}}'
Écrire des policies en Rego
Structure de base
# authz.rego
package authz
# Par défaut, refuser
default allow := false
# Autoriser si l'utilisateur a le bon rôle
allow if {
some role in input.user.roles
role == "admin"
}
# Autoriser la lecture pour les viewers
allow if {
input.action == "read"
some role in input.user.roles
role in {"viewer", "editor", "admin"}
}
Tester une policy
# Évaluer avec un input JSON
opa eval \
--data authz.rego \
--input '{"user": {"roles": ["viewer"]}, "action": "read"}' \
'data.authz.allow'
# true
opa eval \
--data authz.rego \
--input '{"user": {"roles": ["viewer"]}, "action": "write"}' \
'data.authz.allow'
# false
Policy pour API REST (exemple Express/Envoy)
package api.authz
default allow := false
allow if {
is_authenticated
has_permission
}
is_authenticated if {
input.token != ""
# Décoder et vérifier le JWT ici
}
has_permission if {
permission := sprintf("%s:%s", [input.method, input.path])
permission in data.roles[input.user.role].permissions
}
Utiliser les bundles OPA
Les bundles permettent de distribuer policies et données sans redémarrer OPA :
# opa-config.yaml
services:
- name: bundle-server
url: https://my-bundle-server.example.com
bundles:
main:
service: bundle-server
resource: /bundles/policies.tar.gz
polling:
min_delay_seconds: 60
max_delay_seconds: 120
decision_logs:
console: true
opa run --server --config-file=opa-config.yaml
OPA pour Kubernetes avec Conftest
Conftest permet d'utiliser OPA pour valider des manifests K8s dans les pipelines CI/CD, sans Gatekeeper :
# Installer Conftest
curl -Lo conftest.tar.gz \
https://github.com/open-policy-agent/conftest/releases/latest/download/conftest_Linux_x86_64.tar.gz
tar xzf conftest.tar.gz && sudo mv conftest /usr/local/bin/
# Policy de validation (policy/k8s.rego)
cat > policy/k8s.rego <<'EOF'
package main
deny[msg] {
input.kind == "Deployment"
not input.spec.template.spec.securityContext.runAsNonRoot
msg := sprintf("Deployment '%s' doit avoir runAsNonRoot=true", [input.metadata.name])
}
EOF
# Valider un manifest
conftest test deployment.yaml
# FAIL - Deployment 'my-app' doit avoir runAsNonRoot=true
Mise à jour
# Mettre à jour le binaire
curl -Lo opa https://openpolicyagent.org/downloads/latest/opa_linux_amd64_static
chmod +x opa && sudo mv opa /usr/local/bin/
# Mettre à jour l'image Docker
docker pull openpolicyagent/opa:latest-static
# Dans K8s
kubectl set image deployment/opa opa=openpolicyagent/opa:latest-static -n <namespace>
Troubleshooting
# Mode REPL interactif pour déboguer
opa run --stdin-input -d authz.rego
> data.authz.allow with input as {"user": {"roles": ["admin"]}, "action": "write"}
# Tracer l'évaluation d'une règle
opa eval --data authz.rego --input input.json 'data.authz.allow' --explain notes
# Vérifier la syntaxe d'une policy
opa check authz.rego
# Profiler les performances
opa eval --data authz.rego --input input.json 'data.authz.allow' --profile
Policy qui retourne toujours false
# Utiliser explain pour voir pourquoi une règle ne matche pas
opa eval --data authz.rego --input input.json 'data.authz.allow' \
--explain full 2>&1 | head -50
Commandes utiles
opa version # Version OPA
opa check <fichier.rego> # Vérifier la syntaxe
opa eval -d <policy.rego> '<query>' # Évaluer une règle
opa test <policy.rego> <test.rego> # Exécuter les tests unitaires
opa run --server # Démarrer en mode serveur REST
opa build <policy.rego> # Compiler en bundle OCI
opa bench <policy.rego> # Benchmarker une policy
Ressources
- Documentation officielle : https://www.openpolicyagent.org/docs/latest/
- Rego Playground (tester en ligne) : https://play.openpolicyagent.org/
- OPA pour Kubernetes (Gatekeeper) : https://www.openpolicyagent.org/docs/latest/kubernetes-introduction/
- Conftest (CI/CD validation) : https://www.conftest.dev/
- GitHub : https://github.com/open-policy-agent/opa
- Releases : https://github.com/open-policy-agent/opa/releases