Authorization Policies - Heimdall
Policies are the rules that decide whether a request for a resource is allowed. Each resource lists one or more policies, which Heimdall evaluates in order.
Policies are the rules attached to resources to allow or deny access. Each authorizable resource may have one or more policies assigned to it. Policies are evaluated in the order in which they are defined for the resource.
Please note that not all policies support the AuthZEN protocol. Support in this area will gradually improve based on demand and use case discovery. YMMV.
The following policies are supported by CAS:
- Groovy
- Grouper Groups
- Grouper Permissions
- Required Attributes
- Rejected Attributes
- Required ACR
- Required AMR
- Required Audience
- Required Issuer
- Required Scopes
- Rest API
- OpenFGA
- JDBC
-
An authorization policy that can accept an inline or external Groovy script to make decisions:
1 2 3 4 5 6 7 8 9 10 11 12
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.GroovyAuthorizationPolicy", "script" : ''' groovy { def iAllowThis = true return iAllowThis ? AuthorizationResult.granted("OK") : AuthorizationResult.denied("NOPE") } ''' }
The following parameters are passed to the script:
Parameter Description resourceThe matched AuthorizableResourceobject.requestThe supplied AuthorizationRequestobject.applicationContextReference to the Spring ApplicationContextreference.loggerThe object responsible for issuing log messages such as logger.info(...). -
An authorization policy that fetches group memberships for the principal from Grouper and makes decisions based on required groups:
1 2 3 4
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredGrouperGroupsAuthorizationPolicy", "groups" : [ "java.util.HashSet", [ "a:b:c" ] ] }
-
An authorization policy that fetches permissions for the principal from Grouper using attribute definitions or roles and allows or denied access based on whether permissions are found:
1 2 3 4 5
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredGrouperPermissionsAuthorizationPolicy", "attributeDefinition" : "a:b:c", "roleName": "..." }
-
An authorization policy that checks for the presence of required attributes in the authorization principal’s profile:
1 2 3 4 5 6 7
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredAttributesAuthorizationPolicy", "attributes" : { "@class" : "java.util.HashMap", "memberOf" : [ "java.util.HashSet", [ ".*admin.*" ] ] } }
Attribute names refer to the principal’s attributes, except for the following qualified names that read the authorization request:
Name Value subject.id,subject.typeThe AuthZEN subject identifier and type. resource.id,resource.typeThe AuthZEN resource identifier and type. action.nameThe AuthZEN action name. subject.properties.<name>A property of the AuthZEN subject, as supplied by the caller. resource.properties.<name>A property of the AuthZEN resource, as supplied by the caller. action.properties.<name>A property of the AuthZEN action, as supplied by the caller. context.<name>An entry of the request context.For example,
"subject.properties.department" : [ "java.util.HashSet", [ "^Finance$" ] ]requires the caller to describe the subject as a member of the finance department. Properties are never merged into principal attributes, so a caller cannot override attributes that CAS resolves for the subject. -
An authorization policy that checks for the absence of indicated attributes in the authorization principal’s profile, using the same attribute names as the required attributes policy:
1 2 3 4 5 6 7
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RejectedAttributesAuthorizationPolicy", "attributes" : { "@class" : "java.util.HashMap", "memberOf" : [ "java.util.HashSet", [ ".*admin.*" ] ] } }
-
An authorization policy that requires a specific
acrclaim in the principal’s profile:1 2 3 4
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredACRAuthorizationPolicy", "acrs" : [ "java.util.HashSet", [ ".*" ] ] }
-
An authorization policy that requires a specific
amrclaim in the principal’s profile:1 2 3 4
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredAMRAuthorizationPolicy", "amrs" : [ "java.util.HashSet", [ ".*" ] ] }
-
An authorization policy that requires a specific
audclaim in the principal’s profile:1 2 3 4
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredAudienceAuthorizationPolicy", "audience" : [ "java.util.HashSet", [ ".*" ] ] }
-
An authorization policy that requires a specific
issclaim in the principal’s profile:1 2 3 4
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredIssuerAuthorizationPolicy", "issuer" : "^http://.*" }
-
An authorization policy that requires the indicated scopes in the principal’s profile:
1 2 3 4
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RequiredScopesAuthorizationPolicy", "scopes" : [ "java.util.HashSet", [ "profile" ] ] }
-
An authorization policy can be outsources to a REST API that can make decisions based on the request and the resource:
1 2 3 4 5 6 7 8 9
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.RestfulAuthorizationPolicy", "url": "https://api.example.org", "method": "POST", "headers": { "@class": "java.util.LinkedHashMap", "header": "value" } }
- The request body will contain a map to present the
requestand theresourceJSON payloads. Theresourceexcludes its policies. - Authorized requests are expected to receive a
200response code. - The
urland header values can be constructed using the Spring Expression Language
- The request body will contain a map to present the
-
An authorization policy that passes the request to OpenFGA to make decisions:
1 2 3 4 5 6 7 8
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.OpenFGAAuthorizationPolicy", "token": "...", "apiUrl": "...", "storeId": "...", "relation": "...", "userType": "user", }
The following parameters are passed to OpenFGA:
Parameter Description token[1] The bearer authorization token passed via the Authorizationheader.apiUrl[1] OpenFGA base API endpoint that ultimately invokes the checkAPI.storeId[1] The authorization store identifier. relation[1] The relation or the type of access in the authorization tuple; defaults to owner.userTypeIndicates the type of principal. Defaults to user.The
objectfield in the API request is composed of the following elements:1
$REQUEST_NAMESPACE + ':' + $REQUEST_METHOD + ':' + $REQUEST_URI
For AuthZEN requests, the
objectfield is composed of$RESOURCE_TYPE + ':' + $RESOURCE_ID, therelationdefaults to the AuthZEN action name, and theuserTypedefaults to the AuthZEN subject type.[1] This field supports the Spring Expression Language syntax.
-
An authorization policy that executes a SQL query against a relation database. The query is expected to return an
authorizedcolumn of abooleantype.1 2 3 4 5 6 7
{ "@class": "org.apereo.cas.heimdall.authorizer.resource.policy.JdbcAuthorizationPolicy", "query": "...", "username": "...", "password": "...", "url": "..." }
The following settings are available:
Parameter Description queryThe SQL query that is executed. Supports named parameters such as parameter. See below.url[1] The database connection string, i.e. jdbc:mysql://localhost:3306/casusername[1] The username when building a database connection. password[1] The password when building a database connection. dataSourceNameOptional name of the data source bean to use; see below. queryTimeoutMaximum time the query may run, i.e. PT5S(default).0orINFINITEdisables it.[1] This field supports the Spring Expression Language syntax.
The policy looks up its data source as a bean in the application context, named
dataSourceNamewhen defined orheimdallJdbcDataSource-<hash>derived from the URL and username otherwise. When no such bean exists, CAS creates a connection pool with default settings that keeps no idle connections, registers it under that name, and shares it across all policies with the same name until CAS shuts down. A deployment may define its own data source bean with that name to control pooling.
NoteThe connection pool is keyed by the URL and username only. A policy that changes only its
passwordkeeps using the existing pool, and its connections keep the old password until CAS restarts. To rotate a password without a restart, give the policy a newdataSourceName, or define and manage the data source bean yourself.A query that runs longer than
queryTimeoutis cancelled and the policy fails. A request that fails is not authorized: the legacy endpoint returns403and the AuthZEN endpoint returns500. The timeout applies to the query only; waiting for a free pooled connection follows the pool’s own connection timeout.The SQL query is preprocessed to receive the following named parameters:
-
methodfrom the authorization request. -
urifrom the authorization request. -
namespacefrom the authorization request. -
principalfrom the authorization request.
For AuthZEN requests, the query also receives
subjectType,subjectId,resourceType,resourceIdandaction.Furthermore, all context attributes from the authorization request as well as all principal attributes are passed as named parameters and can be used and referenced in the query. Context and principal attributes cannot replace any of the named parameters listed above.
-