Identity Context
When an Authorizer evaluates a policy, it receives an Identity Context from the calling application.
The Identity Context instructs the Authorizer whether and how to populate the input.user
object
when evaluating the policy. The process of identifying the user referred to by the Identity Context
and loading it into the input.user
object is known as "identity resolution".
An identity context contains two fields: type
and identity
.
The type
of an Identity Context gives callers control over the identity resolution process:
IDENTITY_TYPE_NONE
: the policy is evaluated without a user context (input.user
is empty). This is most commonly used to authorize anonymous requests.IDENTITY_TYPE_SUB
: theidentity
field is a user identity such as email, username, or OAuth2 subject name.IDENTITY_TYPE_JWT
: theidentity
field is a JWT access token. The authorizer extracts thesub
(subject) claim from the token and uses it as the user identity.IDENTITY_TYPE_MANUAL
: disables identity resolution. The identity context is available in the poilcy asinput.identity
butinput.user
is empty.
When using IDENTITY_TYPE_SUB
or IDENTITY_TYPE_JWT
, a user with the given identity must exist in
the authorizer's directory. If no such user exists, the authorizer returns an error.
In a user-facing API (e.g. a back-end REST API that requires a JWT in the Authorization
header),
the token is typically decoded and validated during the authentication phase. The service can then
extract the sub
claim from the JWT and pass it to the authorizer with IDENTITY_TYPE_SUB
.
Alternately, the entire JWT can be forwarded to the authorizer with IDENTITY_TYPE_JWT
but the
authorizer would then decode and validate the token too.
Setting the Identity Context
The is
, query
, and decisiontree
API calls all take an identityContext
map:
POST .../api/v2/authz/is
{
"identityContext": {
"identity": "[topaz-user-guid]",
"type": "IDENTITY_TYPE_SUB"
}, ...
}
To access the properties of the user in a policy, you can use input.user
:
package sample.GET.api.orders
default allowed = false
# only allow salespeople
allowed {
input.user.properties.department == "Sales"
}
Using other JWT claims in a policy
Note that the identityContext
is available as input.identity
. If the policy wants to
extract additional claims out of a JWT and use them in the policy, it can readily do so.
Assuming the following identityContext
:
POST .../api/v2/authz/is
{
"identityContext": {
"identity": "[JWT that could contain a 'manager' claim]",
"type": "IDENTITY_TYPE_JWT"
}, ...
}
The following policy will extract the JWT using the io.jwt.decode()
Rego built-in, make it available
as token.payload
, and use claims in the payload within the policy:
package sample.GET.api.orders
default allowed = false
# Helper to get the token payload
token = {"payload": payload} {
[header, payload, signature] := io.jwt.decode(input.identity.identity)
}
# only allow sales managers
allowed {
input.user.properties.department == "Sales"
token.payload.manager
}