A custom, Kotlin-based Authorization Manager plugin using OPA for authorization decisions.
Note: The plugin requires at least version 7.3 of the Curity Identity Server.
The Curity Identity Server can leverage Authorization Managers to control access to its exposed GraphQL APIs for User Management and DCR. This Authorization Manager leverage Open Policy Agent (OPA) as an external authorization engine to determine fine-grained access. OPA holds a policy and receives an authorization request from the plugin. The plugin handles the authorization response and controls access to the requested resource. The plugin makes use of an obligation filter in order to redact individual fields per the OPA policy.
Build the plugin by issuing the command mvn package
. This will produce a JAR file in the target/opa-authorization-manager
directory, which can be installed.
To install the plugin, copy the compiled JAR from target/opa-authorization-manager
into ${IDSVR_HOME}/usr/share/plugins/${pluginGroup}
on each node, including the admin node.
For more information about installing plugins, refer to the Plugin Installation section of the Documentation.
Name | Type | Description | Example | Default |
---|---|---|---|---|
HttpClient |
HttpClient | The HttpClient that the Authorization Manager will use to call OPA. | opa-http-client |
|
OPA Host |
String | The hostname of OPA. | opa.example.com |
|
OPA Port |
String | The port that OPA is exposing its runtime service on. | 8443 |
8181 |
OPA Path |
String | The path where the appropriate policy of OPA is exposed. Note that by default the plugin adds dcr and um to this path depending on which GraphQL API is accessed. |
/v1/data/mynamespace/ |
/v1/data/curity/ |
Navigate to System
-> Authorization
and click New Authorization
. Give it a name (opa-authz-mngr
for example) and choose the type Opa Authorization Manager
. Then provide the appropriate configurations for HttpClient, host, port, and path. Commit the changes.
In order to protect the DCR GraphQL API, the Authorization Manager needs to be added to the Token Service Profile. Navigate to Token Service
-> General
and select the configured Authorization Manager (opa-authz-mngr) from the drop-down menu.
In order to protect the User Management GraphQL API, the Authorization Manager needs to be added to the User Management Profile. Navigate to User Management
-> General
and select the configured Authorization Manager (opa-authz-mngr) from the drop-down menu.
This repository contains a docker compose file that will run an instance of the Curity Identity Server, a data source with test data and an instance of OPA. Running this environment will provide a fully configured environment that can be used to test the use cases and the plugin.
A script is available that will build and deploy the OPA Authorization Manager Plugin and start the docker containers. Run /deploy.sh
to get everything up and running. Make sure to copy a valid license with the name license.json
into components/idsvr
before deploying. Run ./teardown.sh
to stop and remove all the containers.
- Using for example cURL or OAuth.tools, initiate a code flow using the
opa-demo
client (secret isPassword1
). This guide describes how to run the Code Flow using cURL and this guide how to run with OAuth.tools. For both, remember to change the client ID fromwww
->opa-demo
to match the configuration used in this example. - Log in with a user,
admin
ordemouser
(by default both have the passwordPassword1
). Theadmin
user belongs to the groupadmin
that has full access to the GraphQL APIs. Thedemouser
belongs to thedevops
group that is subject to filtration of certain fields for both DCR and User Management data. Review the policy used by OPA to check which fields are filtered out for the devops group. Note that the group claim is issued by default per the configuration. - The access token that is obtained from running the code flow can be used in a call to either of the GraphQL APIs. Using for example Postman or Insomnia, construct a query and add the token in the
Authorization
header.
query getAccounts
{
accounts(first: 5) {
edges {
node {
id
name {
givenName
middleName
familyName
}
title
active
emails {
value
primary
}
phoneNumbers {
value
primary
}
}
}
}
}
The policies available in components/opa/policies
.
DCR policies are defined in dcr-access.rego
. If the user has group == "admin"
, all access is permitted. If the user instead belongs to the devops
group, an attribute unauthorized_fields
is returned that holds the names of the fields that the Authorization Manager will filter out from the response.
Access to the User Management API is defined in um-access.rego
. The structure is very similar to the DCR policies. Here, the phoneNumbers
and name
fields are filtered for users in the devops
group as indicated by the unauthorized_fields
attribute.
To test OPA alone without the involvement of the Authorization Manager a sample request can be sent using for example Insomnia.
POST /v1/data/curity/um HTTP/1.1
Host: localhost:8181
Content-Type: application/json
{
"input": {
"group": "devops",
"resourceType": "um"
}
}
This should return the response below from OPA that includes the attribute unauthorized_fields
that in this case indicates what fields that the Authorization Manager should filter, i.e., name
and phoneNumbers
.
{
"result": {
"allow": true,
"unauthorized_fields": [
"name",
"phoneNumbers"
]
}
}
- Please visit curity.io for more information about the Curity Identity Server
- Open Policy Agent
- Curity Identity Server GraphQL APIs
- User Management with GraphQL
- Authorizing Access to User Data
Copyright (C) 2023 Curity AB.