Apply Open Policy Agent (OPA) policies

    The Open Policy Agent (OPA) HTTP middleware applys to incoming Dapr HTTP requests. This can be used to apply reusable authorization policies to app endpoints.

    You can prototype and experiment with policies using the official opa playground. For example, .

    Spec metadata fields

    To be applied, the middleware must be referenced in . See middleware pipelines.

    1. apiVersion: dapr.io/v1alpha1
    2. kind: Configuration
    3. metadata:
    4. name: appconfig
    5. spec:
    6. httpPipeline:
    7. handlers:
    8. - name: my-policy
    9. type: middleware.http.opa

    Input

    The HTTPRequest input contains all the relevant information about an incoming HTTP Request except it’s body.

    1. type Input struct {
    2. request HTTPRequest
    3. }
    4. type HTTPRequest struct {
    5. method string
    6. // The raw request path (e.g. "/v2/my-path/")
    7. path string
    8. // The path broken down into parts for easy consumption (e.g. ["v2", "my-path"])
    9. path_parts string[]
    10. // The raw query string (e.g. "?a=1&b=2")
    11. // The query broken down into keys and their values
    12. query map[string][]string
    13. // The request headers
    14. // NOTE: By default, no headers are included. You must specify what headers
    15. // you want to receive via `spec.metadata.includedHeaders` (see above)
    16. headers map[string]string
    17. // The request scheme (e.g. http, https)
    18. scheme string
    19. }

    The policy must set data.http.allow with either a boolean value, or an object value with an allow boolean property. A true allow will allow the request, while a false value will reject the request with the status specified by defaultStatus. The following policy, with defaults, demonstrates a 403 - Forbidden for all requests:

    which is the same as:

    1. package http
    2. default allow = {
    3. "allow": false
    4. }
    1. default allow = {
    2. "allow": false,
    3. }

    To redirect, add headers and set the status_code to the returned result:

    You can also set additional headers on the allowed request:

    1. package http
    2. default allow = false
    3. allow = { "allow": true, "additional_headers": { "X-JWT-Payload": payload } } {
    4. not input.path[0] == "forbidden"
    5. // Where `jwt` is the result of another rule
    6. payload := base64.encode(json.marshal(jwt.payload))
    7. }
    1. type Result bool
    2. // or
    3. type Result struct {
    4. // Whether to allow or deny the incoming request
    5. allow bool
    6. // Overrides denied response status code; Optional
    7. status_code int
    8. // Sets headers on allowed request or denied response; Optional
    9. additional_headers map[string]string
    10. }