Traits

Unified
Decouple policy decisions from your services to achieve unified control across the entire stack with any language or service.
Declarative
Express policies in a high-level declarative language that promotes safe, fine-grained logic and enables powerful features such as impact analysis, hot reloading, query optimization, and more.
Context-Aware
Leverage arbitrary external document-oriented data (JSON) in policies to ensure that important requirements are enforced throughout the organization.

Use Cases

Open Policy Agent (OPA) is a general-purpose policy engine with uses ranging from authorization and admission control to data filtering. OPA provides greater flexibility and expressiveness than hard-coded service logic or ad-hoc domain-specific languages. And it comes with powerful tooling to help you get started.

Examples

Scroll back

Kubernetes Admission Control

invariants.rego — ~/src/policies/admission-control/kubernetes
# Kubernetes Admission Control Invariants

package kubernetes.invariants

import data.kubernetes.ingresses
import data.kubernetes.namespaces

# ---------------------------------------------------------------------
# Ingress Invariants

# Generates a list of non-compliant ingresses identified by `namespace`
# and ingress specification `name`.
violations[{
    "namespace": namespace,
    "name": name,
    "message": "ingress hostname must match whitelist"
}] {
    ingress := ingresses[namespace][name]
    host := ingress.spec.rules[_].host
    not contains(whitelist[namespace], host)
}

# Generates a list of allowed hostnames per namespace.
whitelist[namespace] = hosts {
    obj := namespaces[namespace]
    annotations := obj.metadata.annotations
    annotation := annotations["acmecorp.com/hostname-whitelist"]
    hosts := json.unmarshal(annotation)
}

# ---------------------------------------------------------------------
# Helpers

# Checks if `list` includes an element matching `item`.
contains(list, item) {
    list[_] = item
}
Scroll back

HTTP API Authorization

authz.rego — ~/src/policies/httpapi/acmecorp
# HTTP API Authorization

package acmecorp.authz

default allow = false

# Allow people to read their own salaries.
allow {
    input.method = "GET"
    input.path = ["salaries", employee_id]
    input.user = employee_id
}

# Also allow managers to read the salaries of people they manage.
allow {
    input.method = "GET"
    input.path = ["salaries", employee_id]
    input.user = data.manager_of[employee_id]
}
Scroll back

Remote Access Authorization

invariants.rego — ~/src/policies/admission-control/kubernetes
# Fine-Grained SSH Authorization

package ssh.fine_grained

# Allow users in the "dev" organization to SSH into hosts if they
# possess a certificate proving they are assigned to an application
# running on the host.
allow {
    # Extract the X.509 certificate provided in the policy query.
    certs := crypto.x509.parse_certificates(input.certificates)

    # Check that the user is part of the "dev" organization for an app
    # running on this host.
    certs[i].Subject.Organization[j] == data.host_info.apps[_]
    certs[i].Subject.OrganizationalUnit[j] == "dev"

    # Check the certificate's validity period at the time of login.
    time.now_ns() >= certs[i].NotBefore
    time.now_ns() <= certs[i].NotAfter
}
Scroll back

Data Filtering and Partial Evaluation

filtering.rego — ~/src/policies/partial-evaluation/app
# Partial Evaluation

package app.filtering

# ---------------------------------------------------------------------
# Data Filtering

# Allow users to see their own posts.
posts[post] {
    post := data.posts[_]
    post.owner = input.subject.name
}

# Allow users to see posts from their own department
# that they have sufficient clearance for.
posts[post] {
    post := data.posts[_]
    post.department = input.subject.department
    post.security_level <= input.subject.clearance_level
}

# Example Output:
#
#  Conditions (1)
#  --------------
#  data.posts[x].owner = "bob"
#
#  Conditions (2)
#  --------------
#  data.posts[x].department = "ops"
#  data.posts[x].clearance_level <= 3