The AuthZen Protocol
AuthZen is an interoperability protocol to communicate authorization related information between components or multiple systems in an implementation-agnostic way. Enforcer supports the AuthZen protocol, and can provide authorization decisions via ASP.NET Core middleware.
Anatomy of an AuthZen request
A basic AuthZen request, at minimum, must contain three elements. A Subject, an Action and a Resource. A Sample request with the minimum mandatory elements is as follows:
{
"subject": {
"id": "alice@acmecorp.com",
"type": "email"
},
"action": {
"name": "edit"
},
"resource": {
"id": "SecurityPolicy.md",
"type": "document"
}
}
Enforcer will map the elements to the following Oasis attributes:
| AuthZen attribute | Oasis attribute |
|---|---|
| subject.id | Oasis.Attributes.Subject.Identifier |
| action.name | Oasis.Attributes.Action |
| resource.id | Oasis.Attributes.Resource |
| resource.type | Oasis.Attributes.ResourceType |
In addition to the mandatory elements listed above, additional context may be provided in an AuthZen request. The subject, action, resource, or the containing object may have a property named context. Any values provided in a context will be mapped to attributes with a matching identifier in either the Subject, Action, Resource or Environment categories as appropriate.
Responses to AuthZen requests take the following form:
{
"decision": true
}
The decision indicates the result of the policy evaluation, a Permit result will be mapped to true result and any other policy result will be false.
Responses may also contain additional context. See the Handling advice and obligations section for details.
AuthZen also supports bulk evaluation, enabling multiple evaluation requests to be made at once. Enforcer supports this, for details on structuring the requests please refer to the AuthZen spec
Supported AuthZen features in Enforcer
Enforcer currently supports the following
- Discovery / Metadata endpoint (/.well-known/authzen-configuration)
- Evaluation endpoint (/access/v1/evaluation)
- Bulk evaluation endpoint (/access/v1/evaluations)
Currently unsupported features
- Subject search endpoint
- Action search endpoint
- Resource Search endpoint
Enabling AuthZen in Enforcer
To enable AuthZen in Enforcer, make sure to call AddAuthZen to include the necessary services, and UseEnforcerAuthZen to include the AuthZen middleware in the middleware pipeline.
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddEnforcer("AcmeCorp.Global", options =>
{
options.Licensee = <Licensee>;
options.LicenseKey = <License Key>;
})
.AddAuthZen()
.AddFileSystemPolicyStore("policies")
;
var app = builder.Build();
app.UseEnforcerAuthZen();
app.Run();
Handling advice and obligations
Advice and Obligations are a core part of the Oasis authorization model used in Enforcer, allowing actions to happen in response to policies or rules being evaluated. Advice contain attributes indicating things that the policy enforcement point should do, whereas obligations are outcome actions that the policy enforcement point must do.
AuthZen does not have either of these concepts, but does support the notion of additional context. According the AuthZen spec, the contents of the response contexts will be implementation specific, and so in Enforcer we will serialise obligations and advice into the context.
Note: Obligations are disabled by default, as the policy decision point cannot guarantee that the policy enforcement point will handle the obligation. Obligation serialization can be turned on using the EnableObligations flag in the startup .AddAuthZen() call.
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddEnforcer("AcmeCorp.Global", options =>
{
options.Licensee = <Licensee>;
options.LicenseKey = <License Key>;
})
.AddAuthZen(o => {
o.EnableObligations = true;
})
.AddFileSystemPolicyStore("policies")
;
var app = builder.Build();
app.UseEnforcerAuthZen();
app.Run();
Example response with obligations and advice:
{
"decision": true,
"context": {
"advice": [
{
"name": "<AdviceName>",
"arguments": [
{
"name": "<AttributeName>",
"values": [ <AttributeValues> ]
}
]
},
{
... etc
}
],
"obligations": [
{
"name": "<ObligationName>",
"arguments": [
{
"name": "<AttributeName>",
"values": [ <AttributeValues> ]
}
]
},
{
... etc
}
]
}
}
Enforcer also has a built-in AuthZen specific advice named authZenContext which allows outputting values directly into the response context. This is enabled using the AddAuthZenAdvice extension method during startup.
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddEnforcer("AcmeCorp.Global", options =>
{
options.Licensee = <Licensee>;
options.LicenseKey = <License Key>;
})
.AddAuthZen()
.AddAuthZenAdvice()
.AddFileSystemPolicyStore("policies")
;
var app = builder.Build();
app.UseEnforcerAuthZen();
app.Run();
Consider the following policy snippet:
import Enforcer.AuthZen.*
attribute error {
category = authzenCat
id = 'error'
type = string
}
policy example {
rule adviceExample {
deny
on deny authZenContext {
error = "You do not have the required permissions"
}
}
}
Attributes assigned in the authZenContext advice will be output directly into the response context like so:
{
"decision": false,
"context": {
"error": "You do not have the required permissions"
}
}
Error handling
The Enforcer AuthZen middleware will, where possible, report errors through the response context.
In the case of missing or malformed mandatory elements, these will be reported in the response context.
For bulk/boxcar requests, valid requests will be executed normally. Requests with missing or malformed elements will be reported in the response context along with a false decision for the invalid component request.
Client libraries
Client libraries are available to make integrating with the AuthZen protocol easier.