Rules and Conditions
For Access Control to automate the provisioning and deprovisioning of users for a Resource (ex. Google Group or Okta Group), we need to have a pre-calculated list of users that have been pre-approved based on a policy with definitions of which user metadata qualifies a user to be added to the list.
This is defined using a Ruleset, which is our term for a membership criteria policy.
A Ruleset has a pre-calculated list of users based on the rules and conditions that you configure that use one or more of each users’ profile attributes.
Rulesets and Rules
In most cases, a Ruleset will only have one Rule with one Condition, however you have flexibility for complex logic with multiple conditions.
- Each Rule has one or more Conditions.
- All Conditions for a Rule must evaluate as true (
{this}
and{that}
) for a user to match. - A Ruleset can have one Rule or a set of multiple Rules that are evaluated together.
- Any Rule can be true for a user to match (
{this}
or{that}
).
Each Ruleset has a calculated list of users called a Manifest (a.k.a. Ruleset Users) that have matched the criteria in the rules and conditions. This manifest is recalculated on a recurring schedule so new users with matching conditions are added and users that no longer match are removed. Behind the scenes, a Manifest is the Ruleset Users model that has many-to-many database records in the ruleset_users
table.
Condition Types
A condition is similar to an equation where we evaluate the left and right side with an operator and determine if the result is true (matched) or false (not matched).
With traditional group rules that use string matching, it probably looks like division = sales
. In other words, if {this} {equals} {that}
then evaluate as true.
Attributes
All Users with This Dimension Attribute
directory_user_attributes.attribute_id={ulid}
Manager
All Users with Same Manager
directory_users.manager_id={ulid}
Specific User
Specific User
directory_users.id={ulid}
Inherited Ruleset
Manifest from Existing Ruleset in Catalog
directory_rulesets.id={ulid}
Custom
String Matching
directory_users.email (suffix) example.com
Condition Operators
We support several condition operators for string evaluation.
equals
not
(equal to)empty
(null)exists
(not null)greater
(than or equal to)less
(than)prefix
(starts with)suffix
(ends with)contains
(keyword)
You’re probably familiar with using equals
and several others.
Here are a few other useful ways you can use these operators for calculations.
- You may find
greater
orless
helpful for dates (ex.created_at {greater} 2023-01-01
). - You can use
suffix
for email domains (email {suffix} @example.com
) or types of emails (email {suffix} -admin@example.com
). - If you don’t have a management level attribute, you can extract from job titles with
title {contains} Vice President
ortitle {prefix} VP
.
Example
Single Condition Rules
Each Controlled Resource requires at least one Ruleset. Let’s create a ruleset named Sales Division
.
Each ruleset needs at least one rule so let’s create a new rule. A rule is just a group of conditions and doesn’t have any metadata itself.
Each rule needs at least one condition. You can choose between two different types of conditions.
Attribute Condition
The Directory Sync has imported a database record for all of the values that exist across all users so we can simply choose the Sales
Attribute from the Division
Dimension list of attributes.
The benefit to using Attribute Conditions is that any changes detected as your organization renames or restructures your teams automatically handle policy updates gracefully. Each attribute has a database record with an ID and the lifecycle of the attribute and its relationships are managed. Attributes have successor and predecessor relationships so we can easily handle remappings as the names of your attributes change over time.
Custom Condition
If you prefer to use string matching, you can create a Custom Condition where you choose the Dimension Division
and specify that the operator is equals
and the value is Sales
.
The disadvantage to custom rules is that if the value is renamed in the Directory Source, you have less visibility to breaking changes and long term policy management becomes harder that does not have as easy of an admin and end user experience. In other words, it’s simply a string evaluation during sync jobs and has no lifecycle management or relationship benefits.
Best Practice for Condition Types
If you are using the equals
operator (most common), use an Attribute type instead. If you are using any other operator, use Custom Type for one off logic.
If you will use the same custom logic multiple times, you should create a custom dimension and/or attribute(s) so that you can simply choose it from a menu of available choices and have a single source of truth (SSOT) upstream so you don’t repeat yourself (DRY).
Custom dimensions are helpful for configuring catch all attributes so if none of your rules match, a default attribute is assigned to the user, and that default attribute is assignable in rulesets like this one. This allows you to use an Attribute type as an alternative to the not
and null
operator logic. For example, an Unknown
attribute is automatically created as a catch-all for many dimensions by default.
Rulesets with Multiple Rules
Let’s create a Google Group for Go To Market
that has all team members in the marketing
or sales
division.
In this case, we create a ruleset and create two different rules, each with a single condition.
In other words, our Ruleset with two Rules is evaluated as {this} or {that}
.
Multiple Condition Rules
Now let’s create a group that has members from the Sales division in the EMEA region (Europe, Middle East, and Asia) and everyone in Marketing globally. This is an example of ({this} and {that}) or {that}
.
We start with a Rule and create a Condition for division {equals} sales
, just like we did for our single condition rule
In the same rule, we are going to add a second condition for region {equals} emea
.
When evaluating a rule, all conditions must be true for each user.
Let’s add a second rule. This rule has a single condition where division equals marketing
. We are not adding any additional conditions to this rule, so any user in Marketing regardless of region (aka global) would be added to the group.
Additional Use Cases
If your organization has a specific attribute value for region that designates a user as global, then you could add a region {equals} global
condition to not include users that have any other region values (ex. amer
, emea
, apac
).
If you have that global
region attribute and wanted to include your global
users (ex. sales leadership) in addition to the emea
users, you could add a third rule with two conditions for division equals sales
and region equals global
.
Reusable Ruleset Catalog
You can create a custom Ruleset for each resource (ex. Google group) or attach existing Rulesets that you’ve published to the catalog.
For most use cases, you’ll only use a single custom Ruleset per Resource. It is up to you wherher you want to handle team lifecycle changes in upstream Directory Attributes or by using a shared Ruleset that is attached to multiple resources.
As you spend more time with Access Control, you will start to see patterns and reuse opportunities and can switch from custom Ruleset to a catalog Ruleset as needed.
For example, you may have a Support Engineers ruleset that you reuse with GitLab Groups and Projects, a Google Group, Okta Apps, an Okta Group, and a few Slack Channels.
Simply set the catalog_enabled
boolean flag to true to reuse the Ruleset for multiple resources, otherwise it is privately owned by the specific Controlled Resource that it was created for.
You can enable or disable the catalog for a Ruleset at any time. Disabling the catalog will automatically fork the shared ruleset and create a separate ruleset for each resource it was previously attached to.
Multiple Rulesets
For more advanced resource membership rules, you can attach multiple Rulesets to a resource.
The user manifests for each of the rulesets that you attach to the resource are combined together to create a dynamic list of all of the users that should have access to or be a member of the resource.
You typically only use multiple rulesets if you are attaching rulesets from the catalog for different teams (a.k.a. sets of users with their own criteria) that should have access.
Design and Change Management
Staged Preview
When you attach a Ruleset to a resource, it is in a staged
state initially. This allows you to see the expected users that are included in the Ruleset, compare it to the existing vendor resource users (from the vendor API), and show you which users will be provisioning and deprovisioned before making changes prematurely.
This is the opportunity to refine your Rulesets, Rules, and Conditions to get the users that you want.
This also provides an opportunity for your internal change management processes to preview/test the policy before going live.
Activating Resource Rulesets
When the state of the Resource Ruleset changes from staged
to active
, it will now be included in recurring sync jobs as part of the manifest calculation, and users will start being provisioned and/or deprovisioned.
When you activate the Resource Ruleset, you have three scheduling options.
- Immediately (sync is manually dispatched)
- Next Scheduled Sync (usually within the hour)
- Scheduled Time (ex. first sync after next Tuesday at 10:00am)
If you have a change window, you can schedule when the Ruleset goes live by setting the activate_at
timestamp. The Resource Ruleset will be activated (state change from staged
to active
) during the next sync job after this timestamp (ex. within the hour).
Resource User Sync
During scheduled sync jobs, the ruleset manifest users are kept in sync with Controlled Resources using vendor API calls to add/grant or remove/revoke user access.
In other words, when the Ruleset manifest for a Controlled Resource changes, Access Control will automatically provision or deprovision the user’s access during the next sync job.
Custom Attributes with Rulesets
You are seeing the power of using custom calculations for strings, more than just this {equals} that
that you typically start with when using group rules. What if you want to save those calculations and reuse them?
Let’s assume that you don’t have a management level attribute in Okta, and you want to create policies based on whether the user in an executive, vice president, director, manager, or individual contributor.
Let’s use the following logic for this example:
- Executive
- title {equals} CEO
- (or) title {equals} COO
- (or) title {equals} CFO
- (or) title {equals} CTO
- (or) title {equals} CIO
- (or) title {prefix} Executive Assistant
- Vice President
- title {contains} Vice President
- (or) title {prefix} VP
- (or) title {prefix} Senior VP
- Director
- title {prefix} Director
- (or) title {prefix} Sr Director
- (or) title {prefix} Senior Director
- (or) title {suffix} Director
- Manager
- title {prefix} Manager
- (or) title {prefix} Sr Manager
- (or) title {prefix} Senior Manager
- (or) title {suffix} Helpdesk Manager
- Note: We use {suffix} instead of {equals} to capture Helpdesk Manager and Senior Helpdesk Manager so we don’t need conditions for each seniority level.
- (or) title {suffix} Support Manager
- Note: We do not use a generic suffix for
Manager
in this example since this would capture Account Manager on our Sales team that is an Individual Contributor.
Remember that any rule can match for a ruleset to be true (a.k.a. “or”) but all conditions must match for a rule to be true (a.k.a. “and”). We can handle the logic above by creating a ruleset for each of the management level top level bullets, and a rule with a single condition for each of the child bullets.
We do not have logic above for Individual Contributors. These will be covered with a catch all attribute for this dimension if no other rules matched.