Open Policy Agent¶
36 cards — 🟢 9 easy | 🟡 15 medium | 🔴 6 hard
🟢 Easy (9)¶
1. What is Open Policy Agent (OPA)?
Show answer
OPA is a general-purpose, open-source policy engine that decouples policy from application code. Applications query OPA over HTTP, passing structured JSON input; OPA evaluates the query against loaded Rego policies and returns a decision.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
2. What language is used to write OPA policies?
Show answer
Rego — a declarative query language purpose-built for policy. Rego is not imperative; you define what is true and OPA derives all consequences. Policy rules are evaluated simultaneously, not sequentially.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
3. What are the two JSON documents available inside a Rego policy at evaluation time?
Show answer
`input` — the structured query document sent by the calling application; `data` — background data loaded into OPA (allow-lists, user directories, configuration). Policy rules can reference both.Remember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`
4. What are the three deployment patterns for OPA?
Show answer
Sidecar (runs alongside each service in the same pod — low latency, localhost calls), centralized service (shared OPA cluster — easier to manage, network hop required), and library/embedded (OPA SDK or WASM compiled in-process — no network dependency).Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
5. In Rego, what happens when multiple rule bodies share the same rule name (e.g., multiple allow blocks)?
Show answer
They are implicitly OR'd — if any single rule body evaluates to true, the overall rule is true. All conditions inside a single body are AND'd.Remember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`
6. What naming convention does OPA use to identify test rules?
Show answer
Test rules must have names starting with `test_`. OPA's built-in test runner (`opa test`) discovers and runs all rules matching this prefix, reporting pass/fail per rule.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
7. What command runs all OPA unit tests in a directory?
Show answer
`opa test ./policies/` — runs all test rules (prefixed `test_`) found recursively. Add `-v` for verbose output showing individual test names and results.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
8. What are the two Kubernetes CRD types introduced by OPA Gatekeeper?
Show answer
`ConstraintTemplate` — defines a new constraint kind and embeds the Rego logic; `Constraint` — an instance of a ConstraintTemplate that specifies parameters and the scope of resources to apply it to.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
9. What is Conftest and what is it used for?
Show answer
Conftest is a CLI tool that wraps OPA for testing configuration files (Kubernetes manifests, Terraform plans, Dockerfiles, HCL). Write Rego policies in a `policy/` directory and run `conftest testRemember: Conftest = OPA/Rego for config files. Dockerfile, K8s YAML, Terraform. CI checks.
🟡 Medium (15)¶
1. What is a partial rule in Rego, and how does it differ from a complete rule?
Show answer
A partial rule builds a set or object by accumulating elements from all matching rule bodies (e.g., `violations[msg] { ... }`). A complete rule assigns exactly one value — only one body can be true. Mixing them up causes OPA to raise a conflict error.Remember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`
2. What does not mean in Rego, and what is this pattern called?
Show answer
`not expr` is negation-as-failure: the condition is considered false if `expr` cannot be proven true given the current data. It does not mean logical NOT in the classical sense — it means "OPA could not derive a proof for this."Remember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`
3. What is Gatekeeper audit mode and how do you check violations?
Show answer
Audit mode continuously evaluates existing cluster resources against active constraints (not just new admissions). Violations are recorded in `.status.violations` on the Constraint object. Check with: `kubectl get constraintRemember: Gatekeeper = OPA for K8s. ConstraintTemplates(logic) + Constraints(where).
Example: Template=policy, Constraint=application. "Namespace X must have label Y."
4. What is an OPA bundle?
Show answer
A tarball containing Rego policy files and JSON data files, served from a bundle server (S3, GCS, nginx, OCI registry). OPA polls the bundle server and hot-reloads policy without restarting. The bundle manifest pins a revision string for staleness detection.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
5. How can you verify that a running OPA instance has loaded the latest bundle?
Show answer
Use the health endpoint: `curl http://localhost:8181/health?bundles=true` — returns 200 only if bundles loaded successfully. Also check: `curl http://localhost:8181/v1/data/system/bundle | jq '.result.manifest.revision'` to see the loaded revision string.Remember: Bundles = policy packages via HTTP. OPA pulls periodically. "GitOps for policies."
6. What is the opa eval command and give an example of evaluating a policy against inline input?
Show answer
`opa eval` evaluates a Rego query against loaded policy and data. Example: `opa eval --data ./policies/ --input '{"user":{"role":"admin"}}' 'data.authz.allow'` — loads policies from the directory, provides JSON input inline, and returns the query result.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
7. What does enforcementAction: dryrun do in a Gatekeeper Constraint?
Show answer
It puts the constraint in audit-only mode — violations are recorded in `.status.violations` but no admission requests are blocked. This is the safe migration path: deploy as dryrun, monitor violations, remediate, then switch to `enforcementAction: deny`.Remember: Gatekeeper = OPA for K8s. ConstraintTemplates(logic) + Constraints(where).
Example: Template=policy, Constraint=application. "Namespace X must have label Y."
8. What does opa check --strict do?
Show answer
Performs syntax checking and type checking of Rego files. `--strict` enables additional checks: catches unresolved references, unused imports, and deprecated built-in usage. Run in CI before merging policy changes.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
9. What fields should OPA decision logs contain at minimum?
Show answer
At minimum: `input` (the query document), `result` (the policy decision), `query` (what was evaluated), and `timestamp`. Decision logs are the audit trail for policy decisions — ship them to a SIEM or object storage from day one.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
10. How do you check if a ConstraintTemplate has a Rego error after deploying it to Gatekeeper?
Show answer
`kubectl get constrainttemplateRemember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`
11. What is the difference between input and data in OPA?
Show answer
`input` is the per-request document sent by the calling application — it changes with every query. `data` is background state loaded into OPA ahead of time (user lists, config, allow-lists) — it persists across queries and is updated via bundles or the Data API.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
12. Write a Rego comprehension that builds the set of all container image names from a pod spec.
Show answer
`images := {img \| img := input.pod.spec.containers[_].image}` — the `[_]` iterates over all elements of the containers array; the set comprehension collects each unique image value.Remember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`
13. Why should you always exclude kube-system from Gatekeeper Constraints?
Show answer
If a constraint applies to `kube-system`, it can block re-scheduling of critical cluster components (kube-dns, metrics-server) if those pods don't satisfy the constraint. This can break cluster DNS and monitoring. Use `excludedNamespaces: ["kube-system", "gatekeeper-system"]` in every Constraint.Remember: Gatekeeper = OPA for K8s. ConstraintTemplates(logic) + Constraints(where).
Example: Template=policy, Constraint=application. "Namespace X must have label Y."
14. Why is default allow = true considered a security anti-pattern in OPA?
Show answer
It creates an allowlist-by-exception model: everything is permitted unless explicitly denied. Missing a deny rule opens an unintended access path. Best practice is `default allow = false` (deny by default) and enumerate conditions under which allow is true — a missed case blocks rather than exposes.Remember: deny[msg] collects violations. Empty deny = allowed. Any message = denied.
15. What is the purpose of opa build -t wasm?
Show answer
It compiles a Rego policy to a WebAssembly (WASM) module. The WASM module can be embedded in any environment with a WASM runtime (browsers, Cloudflare Workers, Go/Rust apps) and evaluates policy in-process with no network dependency, enabling edge policy enforcement with sub-millisecond latency.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
🔴 Hard (6)¶
1. You have a policy that iterates over a list of 10,000 approved users for every admission request. OPA latency is climbing. What is the fix?
Show answer
Replace list iteration with set membership lookup. Instead of `data.users[i].name == input.user` (O(n) scan), key the data object by the lookup field: `data.users[input.user].active == true` (O(1) hash lookup). Profile the policy with `opa bench` before deploying.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
2. What is the risk of failurePolicy: Fail on the Gatekeeper webhook, and how do you mitigate it?
Show answer
If Gatekeeper becomes unreachable (pod crash, network issue), all admission requests matching the webhook scope are rejected — the cluster becomes unmanageable. Mitigate: run multiple Gatekeeper replicas with a PodDisruptionBudget, exclude critical namespaces with `namespaceSelector`, and consider `failurePolicy: Ignore` for non-security-critical clusters with compensating audit monitoring.Remember: Gatekeeper = OPA for K8s. ConstraintTemplates(logic) + Constraints(where).
Example: Template=policy, Constraint=application. "Namespace X must have label Y."
3. What Prometheus metric should you alert on to detect OPA bundle staleness, and what liveness probe detects bundle failure?
Show answer
Alert on `opa_bundle_last_success_time_seconds` — fire when the time since last successful bundle download exceeds your acceptable policy lag. For liveness, use `GET /health?bundles=true` — this endpoint returns 500 if the bundle has not loaded successfully, triggering pod restart.Remember: OPA = general-purpose policy engine. Decouples policy from code.
Fun fact: CNCF graduated. Uses Rego ("ray-go") language.
4. How does OPA integrate with SPIFFE/SPIRE for workload identity-based authorization?
Show answer
SPIRE issues SVIDs (SPIFFE Verifiable Identity Documents — X.509 certs or JWTs) to workloads. OPA policies can consume the SPIFFE ID from the mTLS certificate or JWT presented by a calling service, using it as `input.principal`. This enables cryptographically-attested workload identity in OPA policy without relying on IP or service account names.Remember: OPA = one language (Rego), many enforcement points (K8s, API, CI).
Example: Enforce: no root containers, required labels, approved registries.
5. Explain Rego unification and how it differs from assignment in imperative languages.
Show answer
In Rego, `x := 1` succeeds only if `x` is unbound or already equals 1 — it is unification (pattern matching), not assignment. If `x` is already bound to a different value, the expression fails (the rule body containing it is false). This means variable values cannot be mutated mid-rule; a variable has at most one value within a rule body.Remember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`
6. What happens to admission requests when a Gatekeeper ConstraintTemplate has a Rego compile error, and how do you detect this in CI?
Show answer
Gatekeeper marks the template as errored and may pass all requests that would have been evaluated by the broken template — a silent enforcement gap. Detect in CI using `gator test -f ./constraints/` (runs ConstraintTemplate tests locally) and check `.status.byPod[*].errors` after every deploy. Never deploy ConstraintTemplates without running `gator test` in the pipeline.Remember: Rego = declarative policy language. Rules return true/false or sets/objects.
Example: `deny[msg] { input.kind=="Pod"; not input.spec.securityContext.runAsNonRoot; msg:="No root" }`