Skip to main content
Redhat Developers  Logo
  • AI

    Get started with AI

    • Red Hat AI
      Accelerate the development and deployment of enterprise AI solutions.
    • AI learning hub
      Explore learning materials and tools, organized by task.
    • AI interactive demos
      Click through scenarios with Red Hat AI, including training LLMs and more.
    • AI/ML learning paths
      Expand your OpenShift AI knowledge using these learning resources.
    • AI quickstarts
      Focused AI use cases designed for fast deployment on Red Hat AI platforms.
    • No-cost AI training
      Foundational Red Hat AI training.

    Featured resources

    • OpenShift AI learning
    • Open source AI for developers
    • AI product application development
    • Open source-powered AI/ML for hybrid cloud
    • AI and Node.js cheat sheet

    Red Hat AI Factory with NVIDIA

    • Red Hat AI Factory with NVIDIA is a co-engineered, enterprise-grade AI solution for building, deploying, and managing AI at scale across hybrid cloud environments.
    • Explore the solution
  • Learn

    Self-guided

    • Documentation
      Find answers, get step-by-step guidance, and learn how to use Red Hat products.
    • Learning paths
      Explore curated walkthroughs for common development tasks.
    • Guided learning
      Receive custom learning paths powered by our AI assistant.
    • See all learning

    Hands-on

    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.
    • Interactive labs
      Learn by doing in these hands-on, browser-based experiences.
    • Interactive demos
      Click through product features in these guided tours.

    Browse by topic

    • AI/ML
    • Automation
    • Java
    • Kubernetes
    • Linux
    • See all topics

    Training & certifications

    • Courses and exams
    • Certifications
    • Skills assessments
    • Red Hat Academy
    • Learning subscription
    • Explore training
  • Build

    Get started

    • Red Hat build of Podman Desktop
      A downloadable, local development hub to experiment with our products and builds.
    • Developer Sandbox
      Spin up Red Hat's products and technologies without setup or configuration.

    Download products

    • Access product downloads to start building and testing right away.
    • Red Hat Enterprise Linux
    • Red Hat AI
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat Developer Toolset

    References

    • E-books
    • Documentation
    • Cheat sheets
    • Architecture center
  • Community

    Get involved

    • Events
    • Live AI events
    • Red Hat Summit
    • Red Hat Accelerators
    • Community discussions

    Follow along

    • Articles & blogs
    • Developer newsletter
    • Videos
    • Github

    Get help

    • Customer service
    • Customer support
    • Regional contacts
    • Find a partner

    Join the Red Hat Developer program

    • Download Red Hat products and project builds, access support documentation, learning content, and more.
    • Explore the benefits

How to deploy Open Policy Agent for API authorization

April 13, 2023
Jorge Balderas
Related topics:
APIsCI/CDKubernetes
Related products:
Red Hat OpenShift

    In this article, we will demonstrate how to deploy Open Policy Agent in server mode into a Red Hat OpenShift cluster. We will then set up simple Rego policies to validate a JWT token and provide authorization to specific APIs.

    About Open Policy Agent

    Open Policy Agent (OPA) is a Cloud Native Computing Foundation (CNCF) graduated project. OPA is an open source policy agent ideal for decoupling authorization from cloud-native applications, APIs, Kubernetes resources, and CI/CD pipelines, along with other artifacts. OPA uses Rego, a declarative language, to define policies as code. Applications and services can use OPA to query, provide an input evaluated against predefined policies, and provide a policy decision, as shown in the Figure 1 diagram.

    A diagram depicting the flow for evaluating policies by Open Policy Agent.
    Figure 1: The flow for evaluating policies by Open Policy Agent.

    How to deploy OPA using REST API

    OPA provides 3 primary options of deploying OPA to evaluate policies:

    1. REST API: Deployed separate from your application or service.
    2. Go library: Requires Go to deploy as a side car alongside your application.
    3. WebAssembly (WASM): Deployed alongside your application regardless of the language.

    In this article, we will demonstrate the REST API option and focus on the use cases for leveraging OPA for API authorization. We will describe each step for deploying OPA, creating simple policies, and then evaluating the using the OPA REST API.

    Prerequisites

    To complete this demo you will need the following prerequisites:

    • Red Hat OpenShift cluster: For this demo, we use OCP 4.12. However, any 4.x version should work. Alternatively, you can use any Kubernetes cluster. The instructions in this demo are specific to OpenShift.
    • OpenShift CLI: You can download the OpenShift CLI (oc) from your cluster as specified in the OpenShift documentation.
    • Git bash or shell/bash terminal: Although not required, the commands presented in this article assume a Linux shell syntax.

    Deploying OPA in 2 steps

    To deploy OPA as a REST API, first create three Kubernetes resources.

    Step 1: Create Kubernetes definition files

    Create a file named deployment.yaml with the following content:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: opa
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: opa
      template:
        metadata:
          labels:
            app: opa
        spec:
          containers:
            - name: opa
              securityContext:
                capabilities:
                  drop: ["ALL"]
                runAsNonRoot: true
                allowPrivilegeEscalation: false
                seccompProfile:
                  type: "RuntimeDefault"
              image: openpolicyagent/opa:0.50.1-debug
              args:
                - "run"
                - "--watch"
                - "--ignore=.*"
                - "--server"
                - "--skip-version-check"
                - "--log-level"
                - "debug"
                - "--set=status.console=true"
                - "--set=decision_logs.console=true"
    

    Most of these parameters are optional, but we included them for higher verbosity level which is helpful for troubleshooting. You can view the purpose of these parameters in the documentation for the opa run command.

    Important observations:

    • We are using OPA version 0.50.1, the latest available at the time of writing. We are using the -debug version of the OPA image which includes a CLI that can be useful for inspecting the deployed files. However for a production release it is recommended that you use the -rootless version of this image.
    • The --server parameter is what tells OPA to run in server mode so that it can listen for REST API requests.

    Next, create a file named service.yaml which will expose OPA as a service within the cluster as follows:

    kind: Service
    apiVersion: v1
    metadata:
      labels:
        app: opa
      name: opa
    spec:
      selector:
        app: opa
      ports:
      - name: http
        protocol: TCP
        port: 80
        targetPort: 8181

    Finally, create a file named route.yaml which will expose OPA service as follows:

    kind: Route
    apiVersion: route.openshift.io/v1
    metadata:
      labels:
        app: opa
      name: opa
    spec:
      selector:
        matchLabels:
          app: opa
      to:
        kind: Service
        name: opa
      port:
        targetPort: http

    Note: We are using http for demo purposes. In a production environment, ensure that you are using https.

    Step 2: Deploy Kubernetes resources to OpenShift cluster

    First, log in to your OpenShift cluster by obtaining a token from your cluster using the OC CLI as follows:

    oc login --token=<sha256~token> --server=<your-openshift-cluster-api-url>

    Next, create a new project for this cluster. We export the NAMESPACE name as a variable so that it can be used in subsequent steps.

    NAMESPACE=opa
    oc new-project $NAMESPACE

    Then, create the resources using the files created previously as follows:

    oc apply -f deployment.yaml -n $NAMESPACE
    oc apply -f service.yaml -n $NAMESPACE
    oc apply -f route.yaml -n $NAMESPACE

    To get the route that was created, issue the following command:

    echo http://$(oc get route $NAMESPACE -o jsonpath='{.spec.host}')

    Navigate to the route in your browser to view the OPA home screen (Figure 2), which allows you to evaluate a policy.

    A screenshot of the OPA home screen.
    Figure 2: The OPA home screen.

    Policy evaluation 3-step demo

    Now, we need to define and load policies for demo purposes.

    Step 1: Create common JWT policy

    One of the nice features about Rego is that it provides several built-in functions. One set of functions that is particularly helpful is the one for JWT (JSON Web Token) token validation. The policy will decode a JWT token, and then validate it against the secret used to sign the token.

    We will use a shared secret for demo purposes. However, the JWT function can verify the token using JWKS (JSON Web Key Sets). Anybody familiar with the JWKS verification flow knows that it is not a trivial implementation. The built-in verify token functions will take care of retrieving KIDs (key ids) from the corresponding well known URL, and it even provides caching capabilities to speed up that process.

    First, create a file named jwt.regoas follows:

    package com.redhat.common.jwt
    
    import input
    import future.keywords.in
    
    valid_token(jwt) = token {
        [header, payload, sig]:= io.jwt.decode(jwt)
    
        valid := io.jwt.verify_hs256(jwt, 'secret')
        token := {"valid": valid,
                    "name": payload.name}
    }

    As you can see from this Rego file, it is primarily JSON, except for the import/package headers. Again, we are using a shared secret, which is done only for demo purposes.

    Next, load this policy using the create policy REST API from the OPA as follows:

    OPA_URL=http://$(oc get route $NAMESPACE -o jsonpath='{.spec.host}')
    cat jwt.rego | curl --location --request PUT "${OPA_URL}/v1/policies/com/redhat/common/jwt" --header 'Content-Type: text/plain' --data-binary '@-'

    Deconstructing this URL:

    • ${OPA_URL}: The base OPA URL.
    • v1/policies: The default location for policies.
    • com/redhat/common/jwt: This is how policies are retrieved. Notice that it matches the package name (i.e., com.redhat.common.jwt), but using a different character separator. There is no hard rule that these should match, but I have found it a good practice to follow to make it easier to organize policies.

    Step 2: Create API authorization policy

    In this step, we will create a policy that uses the common JWT policy loaded in step 1. Create a file named api.rego with the following content:

    package com.redhat.myapi
    
    import data.com.redhat.common.jwt.valid_token
    
    default allow := { #disallow requests by default
        "allowed": false,
        "reason": "unauthorized resource access"
    }
    
    allow := { "allowed": true } { #allow GET requests to viewer user
        input.method == "GET"
        input.path[1] == "policy"
        token := valid_token(input.identity)
        token.name == "viewer"
        token.valid
    }
    
    allow := { "allowed": true } { #allow POST requests to admin user 
        input.method == "POST"
        input.path[1] == "policy"
        token := valid_token(input.identity)
        token.name == "admin"
        token.valid
    }

    Notice the import to the valid_token function. It matches the package used previously, but it is prepended with data.

    Next, load this policy with a similar curl command as follows:

    cat api.rego | curl --location --request PUT "${OPA_URL}/v1/policies/com/redhat/myapi" --header 'Content-Type: text/plain' --data-binary '@-'

    Step 3: Evaluate the policy

    To evaluate the policy, we will need to get a valid JWT token. You can get one from jwt.io, the only requirement is that you enter the same secret from the jwt policy into the <your-256-bit-secret> in the Verify Signature section.

    Additionally, change the name in the Payload section to viewer and copy the generated token.

    Repeat these steps and enter admin as the name, and then save both tokens in a file from where you can copy values.

    Next, create a request to test a successful viewer request named viewer-allowed.json:

    {
        "input": {
            "identity": "<viewer token>",
            "path": "policy",
            "method": "GET"
        }
    }

    Execute the curl command (notice the url changes from policy to data):

    cat viewer-not-allowed.json | curl --location --request POST "${OPA_URL}/v1/data/com/redhat/myapi" --header 'Content-Type: application/json' --data-binary '@-'

    Expect an allowed true output similar to the following:

    {
        "result": {
            "allow": {
                "allowed": true
            }
        }
    }

    Next, create a request to test a not allowed viewer request named viewer-not-allowed.json by changing the method to POST.

    {
        "input": {
            "identity": "<viewer token>",
            "path": "policy",
            "method": "POST"
        }
    }

    Execute the following curl command and expect the output to include allowed false.

    cat viewer-not-allowed.json | curl --location --request POST "${OPA_URL}/v1/data/com/redhat/myapi" --header 'Content-Type: application/json' --data-binary '@-'
    
    {"result":{"allow":{"allowed":false,"reason":"unauthorized resource access"}}

    Next, create an admin-allowed.json file with the following request:

    {
        "input": {
            "identity": "<admin jwt token>",
            "path": "policy",
            "method": "POST"
        }
    }

    Execute the curl command and expect the output to include allowed true as follows:

    cat admin-allowed.json | curl --location --request POST "${OPA_URL}/v1/data/com/redhat/myapi" --header 'Content-Type: application/json' --data-binary '@-'

    Open Policy Agent easily deployed

    This article demonstrated how to easily deploy the Open Policy Agent into an OpenShift cluster and load a common JWT policy with an API policy. We also described how policy evaluation works within OPA. This demo showcased a small set of the capabilities and potential that OPA offers, providing an introduction to OPA and Rego policies.

    Last updated: September 19, 2023

    Related Posts

    • Create an Azure Red Hat OpenShift cluster in less than 5 minutes

    • Set up an OpenShift cluster to deploy an application in odo CLI

    • API login and JWT token generation using Keycloak

    • Authentication and authorization using the Keycloak REST API

    Recent Posts

    • Debugging image mode with Red Hat OpenShift 4.20: A practical guide

    • EvalHub: Because "looks good to me" isn't a benchmark

    • SQL Server HA on RHEL: Meet Pacemaker HA Agent v2 (tech preview)

    • Deploy with confidence: Continuous integration and continuous delivery for agentic AI

    • Every layer counts: Defense in depth for AI agents with Red Hat AI

    What’s up next?

    Learn how to deploy an application on a cluster using Red Hat OpenShift Service on AWS. This learning path uses a pre-built application that will let you become more familiar with features of OpenShift and Kubernetes.

    Start learning
    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Platforms

    • Red Hat AI
    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform
    • See all products

    Build

    • Developer Sandbox
    • Developer tools
    • Interactive tutorials
    • API catalog

    Quicklinks

    • Learning resources
    • E-books
    • Cheat sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site status dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2026 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Chat Support

    Please log in with your Red Hat account to access chat support.