Skip to main content

Authorization

Introduction

One of the key capabilities of the IBM Application Gateway (IAG) is being able to apply authorization policies to requests, controlling who is able to access your protected resources. 

Policy Definition

The authorization policy is made up of a collection of rules. There are a couple of main elements which are important to understand when constructing the authorization policy:

Rule Matching

A rule will be evaluated for matching resources only. There are three elements which are used to match a resource:

Element Description
Paths A rule is matched on the path, as found in the request line of the resource request. Each path may contain the '*' or '?' pattern matching characters.
Host A rule can be matched on the host header found in the resource request. If no host header is specified the rule will match all hosts.
Methods A rule can be matched on one or more HTTP methods from the resource request. If no method is specified the rule will match any method.

In other words, a rule will be considered a match for a resource request if the path, host header and HTTP method matches the request.

Rule Definition

A rule is a logical expression which is used to compare the user attributes, as obtained during the authentication processing, against required values.

The following operators can be used when constructing the rule:

logical operators:

operator description example
and Performs a logical AND of the two operands. (name = "scott") and (scope = "openid")
or Performs a logical OR of the two operands. (name = "scott") or (name = "alice")
not Performs a logical NOT of the operand. not name = "scott"

multi-valued operators:

operator description example
any The operation must match at least one of the values of the specified user attribute. any groupIds = "admin"
all The operation must match all of the values of the specified user attribute. all groupsIds = "user"

relational operators:

operator description example
= The value of the left operand must equal the value of the right operand. name = "scott"
!= The value of the left operand must not equal the value of the right operand. name != "scott"
matches The value of the left operand must match the regular expression specified in the right operand. name matches "scott.*"
> The value of the left operand must be greater than the value of the right operand. expires_in > "30"
>= The value of the left operand must be greater than or equal to the value of the right operand. expires in >= "30"
< The value of the left operand must be less than the value of the right operand. expires in < "30"
<= The value of the left operand must be less than or equal to the value of the right operand. expires in <= "30"
exists The user attribute, specified by the left operand, must exist. groupIds exists

Simple Rule

A 'simple' rule usually consists of three elements:

  1. A user attribute name;
  2. A relational operator;
  3. A literal value (literal values are always enclosed in double or single quotes).

For example:

name = "alice"

Complex Rules

A 'complex' rule consists of a number of 'simple' rules, separated by logical operators. Parenthesis should be used to control the evaluation order of the simple rules.

For example:

(not ((name = "scott") or (name = "alice"))) and (any groupIds = "admin")

The above rule will evaluate to true if the user is not 'scott' or 'alice', and they are a member of the 'admin' group.

Pre-Defined Rules

The following pre-defined rules can also be used:

Name Description
anyuser Matches any user, whether they are authenticated or not.
anyauth Matches any authenticated user.

Rule Action

A rule will evaluate to either true or false. If a rule evaluates to 'true' the configured rule action will then be used to determine the overall authorization decision. The possible actions include:

Action Description
permit The user is granted access to the resource.
deny The user is denied access to the resource. If the user is not yet authenticated they will be redirected to the identity provider for authentication. If the user is already authenticated they will be denied access to the resource and a 403 Forbidden response will be returned.
obligate The user is redirected to the identity provider for authentication or re-authentication, using the parameters defined in the obligation.

If no action is specified the default is 'permit'.

Obligation

If the rule action is 'obligate', the obligation node defines additional parameters about the authentication or re-authentication that should take place. Depending on the configured identity source, the format of the obligation data can look different.

Obligation for OIDC Scenarios

For OIDC scenarios, the obligation data is a map of string values. The parameter and values are appended to the authorization request when authentication or re-authentication takes place. See Authentication Requirements for further information.

obligation:
  oidc:
    <parameter>: <value>

Authorization Logic

The authorization policy comprises of an ordered sequence of authorization rules. When making an authorization decision each rule will be examined in turn. If the rule matches the request it will be evaluated. If the rule evaluates to 'true' the result of the authorization decision is determined from the corresponding rule action. Each rule will be examined in order until a matching rule evaluates to 'true'. The default rule, which will be used if the end of the list of configured rules is reached, is to grant access to any authenticated user.

The following diagram illustrates the logic which is used:

Authorization Flow

An example authorization policy is defined below:

policies:
  authorization:
  
    # Alice has left the team and is no longer allowed
    # access to any data.
    - name: alice
      paths: 
        - /*
      rule: "(user = 'alice')"
      action: deny
      
    # Allow unauthenticated access to /public.
    - name: unauth
      paths: 
        - /public/*
      methods:
        - GET
      rule: anyuser
      action: permit
      
    # Allow any authenticated user to retrieve their
    # account information.
    - name: account
      paths: 
        - /account/*
      methods:
        - GET
      rule: anyauth
      action: permit

    # Updates to account information can only be completed
    # after the user has completed stronger authentication.
    - name: account_update
      paths: 
        - /account/*
      methods:
        - POST
      rule: "(acr = 'urn:ibm:security:policy:id:2')"
      action: permit
      
    # We can use and obligation to trigger a re-authentication
    # to prompt the client to complete strong authentication.
    - name: account_update_obligation
      paths: 
        - /account/*
      methods:
        - POST
      rule: "(acr != 'urn:ibm:security:policy:id:2')"
      action: obligate
      obligation:
        oidc:
          acr_values: urn:ibm:security:policy:id:2

    # In order to be able to manage accounts you must be
    # an administrator.
    - name: manage
      paths: 
        - /account/*
      rule: (any groupIds = "admin")
      action: permit
      
    # We want to deny access to every other resource.
    - name: deny_all
      paths: 
        - /*
      rule: anyuser
      action: deny

Configuration

The authorization rules are configured as authorization polices on the server. Information on how to define the authorization policy is available in the Defining the Authorization Policy page.

Debugging

It is absolutely critical that the authorization policy is authored correctly for the environment. This can potentially be a complex task, and as such it is relatively easy to make mistakes.

There are two mechanisms which can be used to help validate and debug the authorization policy:

Credential Viewer

The in-built credential viewer application can be used to display the user attributes contained within an active session. This is useful in determining which attributes are available when defining the authorization rules. For information on enabling the in-built credential viewer application refer to the Cred Viewer YAML reference page.

Tracing

Tracing can be enabled within the authorization logic to help debug the actual rules that have been created, and to also debug the logic which was followed to reach a decision. The trace component name for the authorization logic is: 'iag.azn'.

The configured trace level will control the amount of trace information generated. As a general guide:

Level Trace Generated
3 Rule parsing errors are displayed.
7 The authorization decision itself is traced.
8 The authorization decision, along with some of the decision logic is traced.
9 Full tracing, which includes all of the decision logic.

Further information on managing tracing within IAG is available in the Enabling Tracing page.