Open Policy Agent (OPA)

website·Indexed 42 days ago

https://www.openpolicyagent.org/docs

An open-source general-purpose policy engine that uses the Rego declarative language to write policies. It supports installation as a server, interactive mode, or Go library, and provides integrations for Kubernetes Admission Control and the Envoy proxy.

Tokens
4.5K
Snippets
23
Records
32
Agent score
69%

What's inside OPA

  1. Overview of Regal for Rego

    Regal is a linter and language server for Rego. It is designed to identify common mistakes, bugs, and inefficiencies in Rego policies, suggest idiomatic approaches, and enforce coding style and best practices. It can be used as a standalone CLI tool, integrated into editors (via a language server), or incorporated into CI/CD build pipelines.
  2. Overview of OPA-Envoy Plugin

    The OPA-Envoy plugin extends OPA with a gRPC server that implements the Envoy External Authorization API. This allows Envoy (v1.7.0+) to delegate fine-grained, context-aware access control decisions to OPA without modifying the underlying microservices. It is typically deployed as a sidecar container in Kubernetes or as a standalone process running alongside Envoy to minimize network latency and improve performance.
  3. Overview of Open Policy Agent (OPA)

    Open Policy Agent (OPA) is an open-source, general-purpose policy engine that decouples policy decision-making from policy enforcement. It allows developers to specify policy as code using a high-level declarative language called Rego. OPA accepts arbitrary structured data (typically JSON) as input and can generate arbitrary structured data as output, making it suitable for microservices, Kubernetes, CI/CD pipelines, and API gateways.
  4. Use OPA for Kubernetes Admission Control

    OPA can be deployed as a Kubernetes Admission Controller to enforce policies during create, update, and delete operations. It can act as a validating controller (denying requests) or a mutating controller (modifying objects).

    Common use cases include:

    • Requiring specific labels on all resources.
    • Restricting container images to corporate registries.
    • Ensuring Pods specify resource requests and limits.
    • Preventing conflicting Ingress objects.
    • Injecting sidecar containers or setting specific annotations.
  5. Access and query input data in Rego

    In Rego, data provided in a query is bound to a global variable called input. You can access specific fields using the dot (.) operator or square-bracket syntax for array elements or keys containing special characters. If a referenced value does not exist, OPA returns undefined.
    package servers
    
    # Accessing a field
    output := input.servers
    
    # Accessing array elements
    output := input.servers[0].protocols[0]
    
    # Accessing keys with special characters
    output := input["foo~bar"]
  6. Verify conditions for all elements using the `every` keyword

    The every keyword is used to succinctly express that a specific condition must hold for all elements of a domain ('FOR ALL' logic).
    package servers
    
    # True if no server in the input list exposes the telnet protocol
    no_telnet_exposed if {
        every server in input.servers {
            not "telnet" in server.protocols
        }
    }
  7. Iterate over collections in Rego

    Iteration in Rego is implicit. Use the some ... in ... syntax to iterate over a collection. OPA evaluates the rule body for each element; if any element satisfies all expressions in the body, the rule is defined. To collect multiple results into a set, use the contains keyword.
    package servers
    
    # Check if any network is public
    exists_public_network if {
        some network in input.networks
        network.public == true
    }
    
    # Check if any server exposes "http"
    http_server if {
        some server in input.servers
        "http" in server.protocols
    }
    
    # Collect IDs of ports connected to public networks
    exposed_ports contains port.id if {
        some port in input.ports
        some network in input.networks
        port.network == network.id
        network.public == true
    }
  8. Install Open Policy Agent (OPA)

    OPA can be installed on macOS via Homebrew or by downloading the binary directly. After downloading a binary, it must be made executable using chmod 755. It is recommended to move the binary to a directory in your PATH.
    # Install via Homebrew
    brew install opa
    
    # Or download binary directly (example for macOS arm64)
    curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_darwin_arm64
    chmod 755 ./opa
    
    # Verify installation
    opa version
  9. Iterate over collections using the `some` keyword

    The some ... in ... syntax is used to iterate over a collection (the last argument). It binds variables (such as key or value) to the collection items and introduces these bindings to the rest of the rule body. This is the standard way to express 'FOR SOME' logic in Rego.
    package servers
    
    # Returns the ID of networks that are public
    public_network contains net.id if {
        some net in input.networks
        net.public
    }
    
    # Returns the ID of servers that allow telnet
    shell_accessible contains server.id if {
        some server in input.servers
        "telnet" in server.protocols
    }
  10. Implement OPA policy decisions for Envoy

    By default, OPA-Envoy queries the policy path envoy/authz/allow (accessed as data.envoy.authz.allow in Rego).

    • Boolean Response: Return true to allow the request or false to deny it.
    • Object Response: Return an object that MUST contain the allowed key (boolean). You may optionally include:
      • headers: Custom headers to send to the downstream client or upstream.
      • body: Response body data for the downstream client.
      • http_status: An HTTP response status code other than 403 (Forbidden).
  11. Use OPA Gatekeeper for Kubernetes Policy Management

    OPA Gatekeeper is the recommended project for Kubernetes admission control. It extends plain OPA by providing:

    • An extensible, parameterized policy library.
    • Native Kubernetes CRDs for instantiating policies (Constraints).
    • Native Kubernetes CRDs for extending the policy library (Constraint Templates).
    • Built-in audit functionality.

    Plain OPA and kube-mgmt are alternatives for users who specifically need OPA management features like status logs, decision logs, and bundles.

  12. Implement logical OR in Rego

    Logical AND is expressed by joining multiple expressions in a single query. To express logical OR, define multiple rules with the same name. For complete rules, the default keyword can be used to provide a fallback value if all other rules with that name are undefined. For partial rules, each rule definition contributes its values to the resulting set.
    package example.logical_or
    
    # Default value if no rules match
    default shell_accessible := false
    
    # Rule 1: True if telnet is exposed
    shell_accessible if {
        some server in input.servers
        "telnet" in server.protocols
    }
    
    # Rule 2: True if ssh is exposed
    shell_accessible if {
        some server in input.servers
        "ssh" in server.protocols
    }