Introduction

Open Policy Agent (OPA) is a general-purpose policy engine that includes a high-level declarative language that you can use to define access control policies, enabling fine-grained access control in applications that leverage SMART on FHIR for authorisation and FHIR for data exchange.

SMART on FHIR

Let's take a look at how OPA can be used to support SMART on FHIR authorisation.

Policy Definition

OPA uses a declarative language called Rego to define policies. Rego allows you to specify rules for authorisation and other security aspects of your SMART on FHIR application.

For example, you could define a policy that uses request attributes (e.g., method and path), data elements in a Bearer Token (i.e., JSON Web Token (JWT)) (e.g., scope, roles, etc.) and other constraints:

package organization.read

methods := "GET HEAD"
path := "/fhir/Organization"
scope := "system/Organization.read"

default allow := false

allow if {
    is_method
    is_request_path
    is_scope
}

is_method if contains(methods, input.request.method)
is_request_path if input.request.path == path
is_scope if contains(token.scope, scope)

bearer_token := t if {
    v := input.request.headers.authorization
    startswith(v, "Bearer ")
    t := substring(v, count("Bearer "), -1)
}

token := payload if {
    [_, payload, _] := io.jwt.decode(bearer_token)
}

See: organization-read.rego

Policy Evaluation

When a SMART on FHIR application requests access to a FHIR resource, OPA can act as a policy decision point. The request can be intercepted by an API Gateway and routed to OPA.

For example:

  - name: provider-directory-api-organization-read
    uri: /fhir/Organization*
    methods: [ "GET", "HEAD" ]
    upstream_id: 1
    plugins:
      opa:
        host: "https://opa:8282"
        policy: "organization/read"

  - name: provider-directory-api-organization-write
    uri: /fhir/Organization*
    methods: [ "POST", "PUT", "PATCH", "DELETE" ]
    upstream_id: 1
    plugins:
      opa:
        host: "https://opa:8282"
        policy: "organization/write"

OPA evaluates the (access control) policy and decides if the request should be 'allowed' or 'denied'.

See: apisix-standalone.yml

Benefits of using Open Policy Agent

Fine-grained Access Control

OPA enables granular control over FHIR resource access, allowing you to specify exactly which FHIR resources an application can access and under what conditions.

Centralised Policy Management

OPA provides a central point for managing and enforcing policies, making it easier to maintain a consistent approach to access control across your application portfolio.

Improved Security

By decoupling policy enforcement from application logic, OPA helps reduce the risk of vulnerabilities and improves the overall security posture of your organisation.

Auditability

OPA policies are code, making them version-controlled and auditable.

Flexibility and Extensibility

OPA's Rego language is flexible and extensible, allowing you to define complex access control rules based on your specific needs.

Example Use Case

Imagine a SMART on FHIR application that needs to access a patient's medication information.

Using OPA, you could define a policy that allows access to medication information only if the application is launched by a clinician and if the patient has consented to data sharing.

When the application requests access to medication data, OPA would evaluate the request against the defined policy. If the conditions are met, OPA would grant access; otherwise, access would be denied.

In essence, OPA provides a powerful way to enhance the security and flexibility of SMART on FHIR applications by enabling fine-grained, policy-based access control, making it a valuable tool for organisations looking to leverage the benefits of both SMART on FHIR and a general-purpose policy engine.

Source Code
References
OAuth 2.0
HL7
Keycloak
Keycloak-based Development
Keycloak Support
APISIX
Open Policy Agent
Provider Directory