Attribute Authorization Manager

Attribute Authorization Managers allow fine-grained, per-attribute authorization of:

It does not support authorizing the OAuth userinfo endpoint (unlike other authorization managers). It can authorize attributes defined in ResourceAttributes subclasses. Per-attribute authorization means that with this authorization manager one can configure to allow/deny reading/writing every attribute separately. When an attribute is denied for a write request (create, update or delete) then the whole request is denied. When an attribute is denied for a read request then just this attribute is filtered out from the response but the rest of the response is returned.

Configuration

At the heart of this manager is the option to configure rule lists and rules. The configuration of rule lists and rules defines how an attribute is authorized. First, the Attribute Authorization Manager tries to match a request with a rule list. If a match is found then rules from the matched rule list are used. Second, all the rules (from the first matched rule list) are tried to be matched with each attribute individually. The first rule that is matched is applied. If none of the rules (in the first matched rule list) match the rule list default enforcement restrictions are applied. The second part (where attributes are matched with rules) is done for each attribute individually. When defining rule lists and rules it’s crucial to remember that the order is important because always only the first matching rule list and also only the first matching rule is applied.

Rule Lists

The rule list configuration comprises three settings: select-rule-list-when setting, enforcement restrictions and one or more rules.

The select-rule-list-when Setting

If a request matches the requirements in select-rule-list-when setting of a rule list then all of the attributes are going to be authorized using this rule list. The select-rule-list-when configuration comprises three settings: context requirement, claim requirements, and scope requirement. Only context requirement is mandatory out of the three.

Context requirement is a list of contexts the rule list can be applied to. It can contain these values:

  • user-management-scim: the rule list can be applied for all requests in SCIM endpoints.
  • user-management-graphql: the rule list can be applied for all user management requests in the GraphQL endpoint.
  • dcr-grahpql: the rule list can be applied for all requests in the GraphQL Dynamic Client Registration endpoint.
  • db-clients: the rule list can be applied for all requests in the GraphQL Database Client Management endpoint.

Claim requirements is an optional list of claims and their values an access token must contain in order for a rule list to be matched.

Scope requirement is an optional list of scopes an access token must contain in order for a rule list to be matched.

Enforcement Restrictions

Enforcement restrictions comprise three settings:

  • default-allow-read: a boolean indicating whether an attribute in read requests should be allowed in case none of the rules match the attribute
  • default-allow-write: a boolean indicating whether an attribute in write (create, update, delete) requests should be allowed in case none of the rules match the attribute
  • require-subject-match: a boolean indicating whether subject matching should be applied for each request. Setting this to true effectively means that only ResourceAttributes belonging to the logged in user can be read or updated.

The require-subject-match setting is enforced by using the subject from an access token and comparing it to:

  • userName attribute in AccountAttributes
  • authenticatedUser attribute in DynamicallyRegisteredClientAttributes
  • userName in DelegationAttributes
  • owner in DatabaseClient

DeviceAttributes contain the accountId attribute. When the require-subject-match setting is set to true, it is required to include the account_id claim in an access token. The value of this claim is then compared to the accountId attribute in DeviceAttributes. This is required for /Devices endpoint in SCIM and for addDeviceToAccountByAccountId and updateDeviceFromAccountByAccountId mutations in the user management GraphQL endpoint.

Setting the require-subject-match to true has an important implication: all listing and create operations are denied. These operations include following:

  • SCIM:
    • GET /Users (but not GET /Users/{id})
    • GET /Users/.search
    • GET /Delegations (but not GET /Delegations/{id})
    • GET /Devices (but not GET /Device/{id})
    • POST /Users
  • GraphQL:
    • accounts query and createAccount mutation in the User Management Endpoint.
    • dynamicallyRegisteredClients query in the DCR Endpoint.
    • databaseClients query and setDatabaseClientOwnerById mutation in the Database Clients Endpoint.

Rules

Each rule list must contain at least one rule. A rule configuration comprises three mandatory settings:

  • access-operation - a list of operations the rule applies to (create, read, update, delete)
  • attribute - a list of attributes the rule applies to
  • decision - one of allow or deny. Denotes what decision will be applied for an attribute that is matched to the given rule.

The access-operation setting can contain four values. Each request maps to one of the values:

Operation Maps To
create
  • all POST requests in SCIM endpoints
  • createAccount mutation in the GraphQL user management endpoint
read
  • all GET requests in SCIM endpoints
  • all queries in GraphQL endpoints
  • all mutation responses in GraphQL endpoints
update
  • all PUT and PATCH requests in SCIM endpoints
  • setClientStatus mutation in the dcr GraphQL endpoint
  • updateAccountById, addDeviceToAccountByAccountId, addDeviceToAccountByAccountId mutations in the user management GraphQL endpoint
delete
  • all DELETE requests in SCIM endpoints
  • deleteAccountById, deleteLinkFromAccountByAccountId, deleteDeviceFromAccountByAccountId mutations in the user management GraphQL endpoint

The attribute setting contains a list of attribute names that a rule is applied to. These attribute names are divided into multiple parts separated by a dot (e.g. device.alias or account.name.givenName). The first part is always a prefix which indicates which ResourceAttributes subclass it is intended for. There are five defined prefixes:

  • account. - maps to AccountAttributes
  • device. - maps to DeviceAttributes
  • delegation. - maps to DelegationAttributes
  • linkedAccount. - maps to LinkedAccountAttributes
  • dynamicClient. - maps to DynamicallyRegisteredClientAttributes
  • dbClient. - maps to DatabaseClientAttributes

The last part of an attribute name can be a star (e.g. device.* or account.name.*). Using a star indicates that a rule should be applied to all sub-attributes.

Important note: Delete operations are always authorized using a star attribute. If one wants to deny deleting devices, the rule must be configured like this (the attribute setting is important to notice):

rule Deny_Device_Deletion {
    access-operation [ delete ];
    attribute        [ device.* ];
    decision         deny;
}

A rule having attribute set to something else e.g. device.id or device.alias would not work and deleting devices would be allowed.

Limitations

Attribute Authorization Manager has a few limitations. This section provides a list of them.

  1. Some attributes cannot be filtered out in read requests.
    1. meta.location field in all SCIM endpoints cannot be filtered out individually. However, this field will be filtered out if all meta fields are filtered out (e.g. using this attribute: account.meta.*).
    2. schemas field in all SCIM endpoints. This field will always be returned in responses as mandated by the SCIM specification.
    3. if primary field is filtered out under account.emails, account.phoneNumbers, account.addresses etc. it will be returned as false in the GraphQL user management endpoint
    4. account.meta.timeZoneId field cannot be filtered out directly in the GraphQL user management endpoint. It will be filtered out if also account.meta.created is filtered out.
  2. Filtering out a mandatory field in any GraphQL endpoint leads to an error returned by the GraphQL engine (NullValueInNonNullableField error) when querying that field. This is required by the GraphQL specification (see GraphQL Error Handling Spec)
  3. Filtering out the id field in all SCIM endpoints leads to a 500 error.

Examples

This section contains examples of Attribute Authorization Manager configurations.

Listing 19 Attribute Authorization Manager that allows self-management of certain Account attributes through GraphQL and SCIM endpoints.
[edit processing authorization-managers authorization-manager attr attribute]
% show
rule-list Self_Account_Authorization {
    select-rule-list-when {
        context-requirement [ user-management-graphql user-management-scim ];
    }
    enforcement-restrictions {
        default-allow-read    false;
        default-allow-write   false;
        require-subject-match true;
    }
    rule Allow_Account_Read {
        access-operation [ read ];
        attribute        [ account.* ];
        decision         allow;
    }
    rule Allow_Account_Write {
        access-operation [ update ];
        attribute        [ account.name.* account.emails.* account.phoneNumbers.* account.title ];
        decision         allow;
    }
}
Listing 20 Attribute Authorization Manager that allows admins to manage all accounts and allows only reading self accounts for other users.
[edit processing authorization-managers authorization-manager attr attribute]
% show
rule-list Admin_Account_Management {
    select-rule-list-when {
        context-requirement [ user-management-graphql user-management-scim ];
        scope-requirement {
            applicability any-of;
            scope         [ admin ];
        }
    }
    enforcement-restrictions {
        default-allow-read    false;
        default-allow-write   false;
        require-subject-match false;
    }
    rule Allow_Account_Management {
        access-operation [ create read update delete ];
        attribute        [ account.* ];
        decision         allow;
    }
}
rule-list User_Self_Account_Reading {
    select-rule-list-when {
        context-requirement [ user-management-scim user-management-graphql ];
        scope-requirement {
            applicability any-of;
            scope         [ user ];
        }
    }
    enforcement-restrictions {
        default-allow-read    false;
        default-allow-write   false;
        require-subject-match true;
    }
    rule Allow_Account_Read {
        access-operation [ read ];
        attribute        [ account.* ];
        decision         allow;
    }
}
Listing 21 Attribute Authorization Manager that allows reading of certain DCR attributes through the DCR GraphQL endpoint
[edit processing authorization-managers authorization-manager attr attribute]
% show
rule-list DCR_Authorization {
    select-rule-list-when {
        context-requirement [ dcr-graphql ];
    }
    enforcement-restrictions {
        default-allow-read    false;
        default-allow-write   false;
        require-subject-match false;
    }
    rule Allow_DCR_Read {
        access-operation [ read ];
        attribute        [ dynamicClient.clientId dynamicClient.scope dynamicClient.redirectUris dynamicClient.grantTypes dynamicClient.authenticatedUser dynamicClient.status ];
        decision         allow;
    }
}
Listing 22 Attribute Authorization Manager that allows deleting of self accounts and devices through the user management GraphQL and SCIM endpoints
[edit processing authorization-managers authorization-manager attr attribute]
% show
rule-list Self_Delete_Authorization {
    select-rule-list-when {
        context-requirement [ user-management-graphql user-management-scim ];
    }
    enforcement-restrictions {
        default-allow-read    false;
        default-allow-write   false;
        require-subject-match true;
    }
    rule Allow_Self_Delete {
        access-operation [ delete ];
        attribute        [ account.* device.* ];
        decision         allow;
    }
}
Listing 23 Incorrectly configured Attribute Authorization Manager. The ‘Deny_Password_Read’ rule is never going to be used as the first (and broader) rule will always be matched first (order matters).
[edit processing authorization-managers authorization-manager attr attribute]
% show
rule-list Admin_Account_Management {
    select-rule-list-when {
        context-requirement [ user-management-graphql user-management-scim ];
        scope-requirement {
            applicability any-of;
            scope         [ admin ];
        }
    }
    enforcement-restrictions {
        default-allow-read    false;
        default-allow-write   false;
        require-subject-match false;
    }
    rule Allow_Account_Management {
        access-operation [ create read update delete ];
        attribute        [ account.* ];
        decision         allow;
    }
    rule Deny_Password_Read {
        access-operation [ read update ];
        attribute        [ account.password ];
        decision         deny;
    }
}