> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/administration-guide/access/access-model.md).

# The access model

How OpenIAM represents access — roles, groups, organizations, resources, access rights, entitlements and the authorization graph — with the real type identifiers.

## What this is, and when you need it

OpenIAM has four container objects that can hold users (role, group, organization, resource), one join object that connects them (the membership, or *entitlement*), and one qualifier on that join (the access right). Everything else in this section — business rules, requests, certification campaigns, risk scoring — reads or writes those same rows.

Read this once before you build anything. When you have, you will be able to decide whether a given piece of access should be a role, a group or an organization affiliation; predict what a role's **Type** field does and does not change; read a membership's tag to see which mechanism granted it; and tell a stale authorization graph apart from a wrong membership row when effective access is not what you expect.

This page is the vocabulary, not a procedure. The form fields are in [Create a role](/administration-guide/access/create-a-role.md); the membership operations are in [Manage roles and groups](/administration-guide/access/manage-roles-and-groups.md).

## The five objects

| Object       | Table           | Use it for                                                                                              | Do not use it for                           |
| ------------ | --------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| Role         | `ROLE`          | An access bundle — a job, a responsibility, or a target permission                                      | Reporting structure                         |
| Group        | `GRP`           | Membership that the managed system itself enforces as a group                                           | Every bundle just because it contains users |
| Organization | `COMPANY`       | Company, subsidiary, division, department, and delegated administrative scope                           | A substitute for a role                     |
| Resource     | `RES`           | The protected thing — an application, a menu, a URI pattern, a managed system, an OAuth scope, a report | Organizational hierarchy                    |
| Access right | `ACCESS_RIGHTS` | Qualifying *how* a membership grants — `READ`, `WRITE`, `ADMIN`, `OWNER`                                | A user population                           |

Only four access rights ship: `READ`, `WRITE`, `ADMIN` and `OWNER`. You can add more at **Access Control → Access Rights** (`/webconsole/accessRights`), but nothing in the product interprets a right you invent — it is a label your own authorization checks and reports must consume.

## Roles versus groups

The distinction is not about size or about business versus technical meaning. It is about who owns the concept.

A **role** is OpenIAM's own aggregation object. It can contain users, groups, resources, organizations and other roles, and it can span managed systems. Use it whenever you need one thing to mean "this collection of access".

A **group** exists because the managed system has a group. Active Directory has `GG-FIN-AP`; OpenIAM represents it as a group associated with the Active Directory managed system so that a membership row in OpenIAM can be provisioned as a real directory membership. If the target has no group concept, you do not need a group.

The practical rule: **compose in roles, mirror in groups.** A role can contain groups; a group cannot contain roles as members in the same way, and a group that exists only to be a container duplicates what a role already does.

## Business roles and technical roles are a design convention

OpenIAM has no "business role" or "technical role" object. The two-layer catalog — a business role named for a responsibility containing technical roles named for target permissions — is a convention you impose, and it is a good one. But do not look for it in the product, and in particular do not read it into the role **Type** field.

### What the role type actually is

The role **Type** is a `METADATA_TYPE` row whose `GROUPING` column is `ROLE_TYPE`. Two ship, and you can see both in the type chooser the role form opens with:

| `TYPE_ID`        | `NAME`         | `SYNC_MANAGED_SYS` | `GROUPING`  |
| ---------------- | -------------- | ------------------ | ----------- |
| `ACCESS_ROLE`    | Access Role    | `N`                | `ROLE_TYPE` |
| `PROVISION_ROLE` | Provision Role | `Y`                | `ROLE_TYPE` |

When the two types were introduced, every role that already existed was set to `ACCESS_ROLE`, so on an upgraded system every pre-existing role is an Access Role whatever it does.

The old documentation called this "classification only". That is very nearly right. Precisely:

* **The `SYNC_MANAGED_SYS` difference between the two rows does nothing.** It is not editable on the metadata type screen and nothing acts on it beyond one search predicate. Do not design around it.
* **The type does not gate provisioning, membership, inheritance or requests.** Nothing in OpenIAM behaves differently because a role is `ACCESS_ROLE` rather than `PROVISION_ROLE`. The only place the value is used inside the product is to label the role in the search grid.
* **Two things do read it.** Creating a managed system auto-creates a role typed `PROVISION_ROLE`. And the SCIM 2 interface publishes `ACCESS_ROLE` and `PROVISION_ROLE` as the allowed values of a membership's `type`, so an external SCIM client can filter on it.

You can confirm the second bullet on your own system in a few minutes, and it is worth doing before you build a design on it: create two disposable roles, one of each type, put the same resource in both, grant each to a test user, and compare the two users' effective access. They will be the same.

So: the role type is a classification you can search and report on, and it is the first thing the role form asks for — `/webconsole/editRole` with no `id` and no `roleTypeId` returns the role-type chooser. It is not a behaviour switch. Design your two-layer catalog with names, descriptions, managed-system association and containment, and use the type consistently so your reports mean something.

## Resource types

A resource is typed, and the type is not decorative: it decides whether the resource can have a parent, whether it appears in resource search, and which screen owns it. Nineteen types ship. The flags are `SUPPORTS_HIERARCHY`, `SEARCHABLE` and `PROVISION_RESOURCE` — see [Resources and organizations](/administration-guide/access/resources-and-organizations.md) for the full table with values, and for the four types that cannot be nested.

The ones you will meet most often:

| `RESOURCE_TYPE_ID`     | What it protects                                                           |
| ---------------------- | -------------------------------------------------------------------------- |
| `MANAGED_SYS`          | A managed system. Every managed system owns a resource of this type        |
| `MAN_MANAGED_SYS`      | A manual (ticket-fulfilled) managed system                                 |
| `MENU_ITEM`            | A Webconsole or SelfService navigation entry                               |
| `URL_PATTERN`          | A URI pattern behind the Access Gateway                                    |
| `URI_PATTERN_METHOD`   | One HTTP method on a URI pattern                                           |
| `CONTENT_PROVIDER`     | A content provider                                                         |
| `ADMIN_RESOURCE`       | The delegated-administration scope object                                  |
| `APPLICATION_CATEGORY` | An application catalog category                                            |
| `OAUTH_SCOPE`          | An OAuth 2.0 scope                                                         |
| `PROFILE`              | An access profile                                                          |
| `SOD_ENTITLEMENT`      | A resource auto-created when a segregation-of-duties rule set is activated |

## Entitlements

An **entitlement** is a row in a membership table joining two objects. Every one of them carries the same four things:

| Field       | Meaning                                                                                   |
| ----------- | ----------------------------------------------------------------------------------------- |
| `startDate` | When the grant becomes effective                                                          |
| `endDate`   | When it expires — enforced only by the `AUTO_REVOCATION` batch task, which ships disabled |
| `rights`    | Which access rights qualify this grant                                                    |
| `tags`      | How the grant happened — the membership tag                                               |

There are exactly five membership tags. They are a fixed list — you cannot add a sixth — and all five are sensitive metadata types that the Webconsole will not let you delete:

`ACCESS_REQUEST_ASSIGNMENT` `ADMIN_ASSIGNMENT` `BUSINESS_RULE_ASSIGNMENT` `SYSTEM_ASSIGNMENT` `PENDING_MANUAL_ASSIGNMENT`

The tag is the answer to "why does this person have this?", and it is what the risk engine's membership-origin factor scores and what an access review uses to tell an automatic grant from a requested one. See [Membership tags](/administration-guide/governance/certification/membership-tags.md).

{% hint style="info" %}
A tag records how the membership was *created*. It is not an ownership claim the removal path honours: a business rule's remove action targets the named role or group, not only memberships carrying `BUSINESS_RULE_ASSIGNMENT`. See [Business rule reference](/administration-guide/access/business-rules/business-rule-reference.md#direct-membership-actions).
{% endhint %}

## How access becomes effective

A user can hold the same role through several independent paths:

* a direct user-to-role membership;
* membership in a group that is itself a member of the role;
* membership in a child role whose parent is the role;
* an organization affiliation that carries the entitlement;
* a business rule that added it;
* an approved access request;
* synchronization from an authoritative source;
* a membership whose `endDate` has passed but which nothing has revoked, because `AUTO_REVOCATION` is disabled.

Effective access is **not** evaluated per request. It is computed from a graph, and no Webconsole screen rebuilds that graph — see [Rebuild the authorization graph](/administration-guide/operations/rebuild-the-authorization-graph.md). That has one important consequence for troubleshooting: if the membership rows are right and effective access is wrong, the graph is stale; if the membership rows are wrong, rebuilding the graph will faithfully rebuild the wrong answer. Always confirm the membership first.

## Inheritance

A role can have parent roles and child roles, and the child inherits the parent's entitlements. The role form offers **Role Parent** only while you are creating the role, so on an existing role you manage the relationship from `/webconsole/roleEntitlements?id=<ROLE_ID>` instead — if the field is missing, that is why.

Two things follow from that. Inheritance is a real access change, not catalog organization: every parent you add grants its whole content to every existing and future member of the child. And a shallow hierarchy with reusable contained roles is easier to reason about, and easier to certify, than a deep chain — a reviewer looking at a three-level chain cannot see what they are approving.

OpenIAM rejects a resource parent-child relationship where either resource's type has `SUPPORTS_HIERARCHY='N'`, with `RESOURCE_TYPE_NOT_SUPPORTS_HIERARCHY`. Roles and groups have no equivalent type restriction, and the only cycle check is `CANT_ADD_YOURSELF_AS_CHILD`, which catches a role added as its own child and not a longer loop such as A→B→A. Nothing will stop you saving that longer loop, and nothing will report it afterwards — so walk the ancestors yourself before you save.

## Menu visibility is not authorization

Webconsole and SelfService navigation entries are resources of type `MENU_ITEM`. Granting a role the menu resource makes the entry appear. It does not authorize the operation behind it — that is a separate resource, typically a `URL_PATTERN` or a `URI_PATTERN_METHOD`, and it is checked independently. Both directions of the mistake are real: a hidden menu whose operation is still reachable, and a visible menu whose action fails.

## Choosing the grant mechanism

Use the highest governed layer that accurately expresses the need, and pick exactly one authoritative mechanism per entitlement.

1. **A role** for anything repeatable.
2. **A business rule** when governed identity data should decide, and should also decide removal.
3. **A request with approval** when a human must decide.
4. **A direct grant** only for a documented exception, with an end date.

Encoding the same policy in a business rule *and* synchronization *and* manual administration is the single most common cause of "access keeps coming back" and "my change was reverted overnight" — and because `PERFORM_BR_REPROVISION` ships disabled, the rule wins only when something evaluates it.

## Now do something with it

| Once you have decided…                                                                 | Go to                                                                                      |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| …that the access is a role, and you want to create it                                  | [Create a role](/administration-guide/access/create-a-role.md)                             |
| …who should hold it, or that someone should stop holding it                            | [Manage roles and groups](/administration-guide/access/manage-roles-and-groups.md)         |
| …that the protected thing is a resource, or that people need an organization hierarchy | [Resources and organizations](/administration-guide/access/resources-and-organizations.md) |
| …that identity data should decide the population rather than a person                  | [Build a business rule](/administration-guide/access/business-rules.md)                    |
| …that the catalog itself is the problem                                                | [Role engineering and maintenance](/administration-guide/access/role-engineering.md)       |

\| …that you need a field on the role or group form, or a drop-down's values | [Role and group field reference](/administration-guide/access/manage-roles-and-groups/role-and-group-reference.md), [Enumerated values](/administration-guide/reference/enums.md) | | …that you need to know how an existing grant happened | [Membership tags](/administration-guide/governance/certification/membership-tags.md) |

*Applies to OpenIAM 2026.8.1. Last reviewed 7 August 2026.*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/administration-guide/access/access-model.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
