> 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/governance/certification/review-application-entitlements.md).

# Review entitlements that live inside an application

Onboard an application that is not Active Directory, import its roles and assignments, and certify them — the ordering rule, the Application column, and what nesting will and will not do.

## What this is, and when you need it

This page takes an application whose permissions OpenIAM has never seen — a records system, a finance suite, a timesheet tool — and gets you from that starting point to a running access review over those permissions. The work is one managed system, three imports and one campaign, and almost all of the difficulty is in the **order** rather than in any individual screen.

It exists because certification reviews **roles and groups**, and a role or group is only an entitlement *of an application* when it carries that application's managed system id. Until the application is a managed system with its permissions loaded as associated roles or groups, there is nothing for a campaign to scope onto — however business-critical it is.

## At a glance

|                          |                                                                                                                                                                                |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **You will end up with** | An application represented as a managed system, its roles and assignments imported, and a launched campaign whose reviewers see one row per user and entitlement               |
| **Where**                | **Provisioning → Managed System**, then `/webconsole/synchronizations`, then `/webconsole/access-certification-edit?id=<CERTIFICATION_ID>`                                     |
| **You need first**       | The application's users already in OpenIAM; a CSV or query for its roles and for its user-to-role assignments; a decision on review granularity                                |
| **Takes**                | Half a day to a day for a first application, most of it on the two imports                                                                                                     |
| **Reversible**           | **Partly.** Imports create real roles and memberships you would have to unpick by hand, and the launched campaign mails reviewers. Get the granularity right before you import |

Use something else when:

| If                                                    | Go to                                                                                                                                                           |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| The entitlements already arrive from a managed system | [Create an application campaign](/administration-guide/governance/certification/create-an-application-campaign.md) — the first four steps here are already done |
| The obligation is per person, not per system          | [Create a user campaign](/administration-guide/governance/certification/create-a-user-campaign.md)                                                              |
| You want continuous review rather than a periodic one | [Access certification and risk](/administration-guide/risk/certification.md)                                                                                    |

{% hint style="warning" %}
**Decide the granularity before you import anything.** The reviewer's decision unit is a membership on a role or a group. If you want a reviewer to approve or revoke *individual functions inside* a role, that granularity has to exist as separate roles at import time. A nested tree with a per-node approve and revoke is **not** available as configuration — see [Representing a function hierarchy](#representing-a-function-hierarchy-four-options) before you design the feed, because reworking it later means re-importing every assignment.
{% endhint %}

Throughout, the example is a records application called **Ledger** with roles such as **Debt Management**, alongside two more applications, **Finance Suite** and **Timesheets**.

## The ordering rule

Five stages, and the order is enforced by the product rather than left to convention:

**users → managed system → roles and groups → user-to-role assignments → campaign**

Two dependencies bite hard if you get them backwards, and the steps below say what each failure looks like: the assignment feed does not create users, and it matches an entitlement by **name plus managed system id**, so both the users and the roles have to be in place first.

## From nothing to a running review

{% stepper %}
{% step %}

### Load the users

Route: `/webconsole/synchronizations` (list), `/webconsole/synchronization` (one configuration), `/webconsole/synchronization-history` (results).

Nothing on this page is specific to the application — this is ordinary identity onboarding, covered in [Set up a synchronization](/administration-guide/lifecycle/synchronize-and-import-data.md). What matters is only that **every user who holds a Ledger permission already exists in OpenIAM**, matched by whatever principal the assignment feed will use.

**Verify before moving on:** search for a sample of the users named in your assignment file and confirm each resolves to exactly one identity. If some of the application's accounts belong to people who are not in your authoritative source — contractors, service accounts — decide now whether to create them or to leave those permissions uncertified. A missing user is not a warning at assignment time; it is a dropped row.
{% endstep %}

{% step %}

### Create a managed system for the application

Routes: `/webconsole/mngsystemlist` (list), `/webconsole/mngsystem` (one managed system).

Create **one managed system per application**: `Ledger`, `Finance Suite`, `Timesheets`. This is the object that makes "application" a real scope for a campaign, and it is also the object the reviewer's **Application** column resolves against. If the application has no live connector — you are loading its permissions from a CSV export and revocations will be carried out by hand — configure it as a manual managed system. Connector selection, connection parameters and the manual flag are covered in [Connectors and managed systems](/administration-guide/lifecycle/connectors-and-managed-systems.md).

Saving a managed system **creates a resource automatically** and records the link on `MANAGED_SYS.RESOURCE_ID`. That link is written once, when the managed system is first saved, and is never rewritten or cleared. The resource type is `MANAGED_SYS`, or `MAN_MANAGED_SYS` when the managed system is flagged manual.

{% hint style="info" %}
**The generated resource is not named after the application.** OpenIAM names it with the managed system's name, an underscore, and the epoch milliseconds at the moment of the save — so a managed system called `Ledger` produces a resource called something like `Ledger_1780000000000`. The readable name is kept separately in the resource's `COORELATED_NAME`. Searching the resource list for `Ledger` and finding a timestamped name — or nothing at all, if your search is an exact match — is expected, not a fault.

Two related behaviours: **cloning** a managed system creates a *fresh* resource rather than sharing the original's, so a cloned system is a genuinely separate scope; and an associated **role** is created only when the save explicitly asks for one. That is opt-in and the managed system screen does not offer it, so do not expect a role to appear alongside the resource.
{% endhint %}

**Verify before moving on:** the managed system appears on `/webconsole/mngsystemlist`, and a resource exists whose `COORELATED_NAME` is the managed system's name. If you configured a live connector, run the connectivity test described in [Connectors and managed systems](/administration-guide/lifecycle/connectors-and-managed-systems.md) now — a broken connection is far cheaper to find here than after two imports.
{% endstep %}

{% step %}

### Import the application's roles and groups

Route: `/webconsole/synchronizations`.

Load Ledger's permissions as roles (or groups) **associated with the Ledger managed system**. The shipped starting point is `sync/role/csv/BulkRoleEntitlementsUpload_1.0.groovy`, which reads `NAME`, `DESCRIPTION`, `METADATA TYPE NAME`, up to three `CUSTOM_ATTRIBUTE_n_NAME` / `CUSTOM_ATTRIBUTE_n_VALUE` pairs, and `PARENT ENTITLEMENT`. Set the managed system on the synchronization configuration so every imported role carries it. Details of the script contract are in [Edit a synchronization transformation script](/administration-guide/automation/synchronization-scripts.md).

Decide here how many roles you are creating — one per coarse job function (`Debt Management`), or one per individually reviewable function. That is the decision described in [Representing a function hierarchy](#representing-a-function-hierarchy-four-options).

{% hint style="danger" %}
**A role with a null `MANAGED_SYS_ID` will never appear in an application campaign.** It is not an entitlement of any application, so the campaign's entitlement lookup cannot see it, and any review item it did produce would show a blank **Application** cell. This is the single most common cause of "the role I imported is missing from my campaign" — check the association before you check the campaign.
{% endhint %}

**Verify before moving on:** search roles filtered by the Ledger managed system and confirm the count matches your file. The authoritative check is the campaign's own entitlement picker — if a role is absent there, the assignment import in the next step will not find it either.
{% endstep %}

{% step %}

### Import the user-to-role assignments

Route: `/webconsole/synchronizations`.

This is the feed that says *who holds what*. The shipped transform is `sync/user/csv/CsvUserEntitlementsTransformationScript_1.0.groovy`, and it reads three columns:

{% code overflow="wrap" %}

```
APPLICATION,TYPE,ENTITLEMENT_NAME
Ledger,ROLE,Debt Management
Ledger,GROUP,Ledger Read Only
Finance Suite,ROLE,Accounts Payable Clerk
```

{% endcode %}

`APPLICATION` is the **managed system name**, which the script resolves to a managed system id; `TYPE` is `ROLE` or `GROUP`; `ENTITLEMENT_NAME` is matched exactly against role or group names *within that managed system*. Both prior stages are load-bearing here, and each failure has a distinct signature:

* **An unmatched user creates nothing.** The transform returns `TransformScript.SKIP`, whose value is `-1`, and the synchronization records an error carrying `TRANSFORMATION_RETURN_SKIP`, a failed audit entry and a record status of `FAILURE`. The row is dropped and no user is created — visibly, as an error record on `/webconsole/synchronization-history`.
* **An unmatched entitlement name is skipped.** Matching is by name **plus managed system id**, so an assignment row naming a role that does not yet exist under that managed system resolves to nothing and prints *"Role with name … was not found"* in the job log.

If you intend to use the membership-description option described below, add a fourth column to this feed and write it into the per-membership description — that is the field the reviewer sees as **Assignment details**.

**Verify before moving on:** open two or three users and confirm the Ledger roles appear on their access; then read `/webconsole/synchronization-history` for the run and confirm the error count is zero, or that every error is one you accept. Do not proceed with a non-zero error count you have not explained — those users will simply be absent from the campaign, with no exclusion reason to point at.
{% endstep %}

{% step %}

### Create and scope the campaign

Routes: `/webconsole/access-certifications` (list), `/webconsole/access-certification-edit?id=<CERTIFICATION_ID>` (edit).

Set **Type of Certification** to `APPLICATION_CERTIFICATION`, labelled **Application certification** in the UI. There are exactly two campaign types — `APPLICATION_CERTIFICATION` and `USER_CERTIFICATION` — and the **Type of Certification** dropdown offers those two and nothing else. There is no separate "application entitlement" type; certifying entitlements inside an application *is* the application campaign.

On the **Applications** tab, pick `Ledger`. The picker is a managed system picker, so what you are choosing is a managed system rather than a free-standing "application" object, and the selected ids persist to `CERTIFICATION_APPLICATION.APPLICATION_ID`. When the campaign generates, those ids become the scope filter directly: OpenIAM searches for roles and groups whose managed system is one of the ones you picked. The role and group include/exclude lists **refine** that scope; they do not define it.

**Run one campaign per application.** Ledger, Finance Suite and Timesheets each get their own campaign, because the reviewer population, the owner who signs off and the completion window are all per-application concerns. The remaining fields — selection mode, reviewer steps, expiration, email template — are on [Create an application campaign](/administration-guide/governance/certification/create-an-application-campaign.md) and [Plan and scope a campaign](/administration-guide/governance/certification/plan-and-scope-a-campaign.md).

**Verify before moving on:** save, then run a preview and read `includedUserCount` and `includedItemCount`. `includedItemCount` should be close to the number of assignment rows you imported for this application; a large shortfall means roles are missing their managed system association or the assignment rows were dropped.
{% endstep %}

{% step %}

### Launch, then confirm it actually ran

Launch from the preview, and confirm in the audit log rather than in the UI. Generation runs asynchronously, so the campaign list can look unchanged for a while after a launch that is in fact progressing; the audit trail is where you see it move. Generation is audited as `EXECUTE_CERTIFICATION`, each batch as `EXECUTE_CERTIFICATION_BATCH`, each user's workflow as `INITIATE_CERTIFICATION_WORKFLOW`, and every reviewer decision as `COMPLETE_CERTIFICATION_REVIEW`. Later lifecycle actions are `FORCE_EXPIRE_CERTIFICATION_CAMPAIGN`, `EXTEND_CERTIFICATION_CAMPAIGN` and `UPDATE_CAMPAIGN_MANAGERS`. A launch that produced `EXECUTE_CERTIFICATION` but no `INITIATE_CERTIFICATION_WORKFLOW` generated nothing for anyone to review, whatever the campaign status says.

{% hint style="info" %}
OpenIAM ships **no example campaign** — campaigns are created in the Webconsole, so there is no fixture to copy. Build the first one by hand, then clone it for Finance Suite and Timesheets.
{% endhint %}
{% endstep %}
{% endstepper %}

## What the reviewer sees

### The Application column: the answer to the question everyone asks

**The reviewer does see which application each entitlement belongs to, and no custom attribute is needed to make that happen.** The managed system is carried on the role or group *definition*, not on the membership. When the campaign generates a review item, OpenIAM copies the role's or group's managed system onto the item, stores it as `ACCESS_REVIEW_ITEM.ACCESS_MANAGED_SYS_ID`, and renders it as an **Application** column in the reviewer's user view and entitlement view, and as a header field on the entitlement detail screen.

**Confirm it:** open any campaign as a reviewer and look at the **Application** column. It should be populated on every row; a blank cell means the underlying role or group has no managed system.

Two limits worth knowing before someone reports them as bugs:

* The column is **filterable but not sortable**. It holds the managed system's id resolved to a name for display only, so the grid can filter on the value but the header will not order by it.
* A role with a null `MANAGED_SYS_ID` shows a **blank Application cell** — and in practice never reaches a reviewer at all, because it is not in scope for an application campaign in the first place.

{% hint style="warning" %}
**Break-glass: counting review items per application.** The reviewer's grid filters but does not aggregate, and no shipped screen gives you "how many items per application". Read-only SQL against the OpenIAM schema will:

{% code overflow="wrap" %}

```sql
SELECT ACCESS_MANAGED_SYS_ID, COUNT(*)
FROM ACCESS_REVIEW_ITEM
GROUP BY ACCESS_MANAGED_SYS_ID;
```

{% endcode %}

This is outside the supported change path. It is a read, so it risks no data, but it bypasses the product's access controls and audit — nobody will see that you ran it — and the counts span every campaign in the deployment unless you narrow them by campaign id. The supported alternative is slower: export the campaign from the certification reports and count in the spreadsheet.
{% endhint %}

### The metadata that reaches the reviewer

Per review item, the reviewer sees the role or group description, its metadata type, its access rights and its membership tags as chips, and the **per-membership** description under the label **Assignment details**. That last one is read from `USER_ROLE.DESCRIPTION` — the description on the membership itself, not on the role — which is why it is the cheapest place to give a reviewer context that varies from person to person. Nothing else on the role reaches the reviewer's screen.

{% hint style="warning" %}
Roles can carry custom attributes — `ROLE_ATTRIBUTE` rows — and the shipped `BulkRoleEntitlementsUpload_1.0.groovy` will happily load them from `CUSTOM_ATTRIBUTE_n_NAME` / `CUSTOM_ATTRIBUTE_n_VALUE` pairs. **No certification screen renders them.** Loading a function list into a role attribute puts it where a report can read it and a reviewer cannot; check by loading one and opening the item as a reviewer before you build a feed around it.
{% endhint %}

### Only direct memberships become review items

When a campaign generates, OpenIAM collects exactly two things per user — the roles they hold and the groups they hold — and builds review items from those two collections and nothing else. Consequences:

* **A resource entitlement never becomes a review item.** A review item can point at a role or at a group; there is no resource review item, so no reviewer will ever be asked about a resource. Resources only widen the in-scope *user population* of an application campaign; they are not reviewable objects.
* **"Direct" is literal.** The memberships OpenIAM reads are the rows recorded directly against the user in `USER_GRP`, `USER_ROLE`, `RESOURCE_USER` and `USER_AFFILIATION`. There is no graph traversal at this point, so access a user holds only by inheritance is not in the list the campaign reviews.

**Confirm it:** give a test user a role that inherits a child role, generate a campaign over that application, and count the reviewer's rows — you will see one, for the parent membership.

### Nesting exists in the model, but it is not certified

Role-to-role nesting is real, recorded in `ROLE_TO_ROLE_MEMBERSHIP`, as is resource-to-resource nesting in `RES_TO_RES_MEMBERSHIP`. The authorization graph traverses both to unlimited depth — a role nested five levels down does grant its access. But only a depth-1 membership counts as *direct*, and only direct memberships are certified.

The depth of that traversal is not something the Webconsole reports; you can see its *effect* by checking that a deeply nested role still grants access, but there is no screen that shows the traversal itself. If you need the depth confirmed for an audit, that is a question for your deployment owner or OpenIAM support, not something this page can point you at.

{% hint style="danger" %}
**If a parent role has child roles, the children produce no review items.** They are not shown as inherited, they cannot be approved or revoked independently, and a revoke decision on the parent acts on the **parent membership only**. Nesting is invisible to the reviewer and to the decision.
{% endhint %}

### The one place a reviewer sees below the role

Clicking an entitlement name opens a modal showing the role's full **transitive resource closure**, with a per-row indicator of whether the resource is held directly or by inheritance. It renders as a **flat, read-only, two-column node diagram** — not a tree, no indentation, no per-node decision. It is the one place a reviewer can see what a role contains, and it is informational only: nothing in that modal can be approved or revoked.

{% hint style="danger" %}
**This view is filtered by resource type.** It shows five types and only five: `AUTH_PROVIDER`, `CONTENT_PROVIDER`, `MANAGED_SYS`, `MAN_MANAGED_SYS` and `URL_PATTERN`. A custom resource type — `APP_FUNCTION`, or whatever you named yours — is **silently dropped**: no row, no message, no indication that anything was omitted. If you model an application's function tree as custom resources, the reviewer sees an empty or misleadingly short diagram and has no way to know it is incomplete.
{% endhint %}

## Representing a function hierarchy: four options

Applications rarely have flat permissions. Ledger has `Debt Management`, and inside it *Write off*, *Adjust balance* and *View history*. Four ways to express that, and what each actually gives a reviewer:

| Option                                                                            | What the reviewer gets                                                                                                                 | Cost                                                                                                                                                                                                                                                                | Verdict                                            |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| **Child roles under the parent role**                                             | Nothing. Children produce no review items, are not shown as inherited, and cannot be decided independently                             | The shipped `BulkRoleEntitlementsUpload_1.0.groovy` does support a `PARENT ENTITLEMENT` column, but it only links the parent for a role that already has an id — which is not the case on first insert, so the hierarchy needs a **second pass** over the same file | Not useful for review                              |
| **Child resources under the application resource**                                | Rows in the read-only modal diagram only — flat, no indentation, no decision, and only if the resource type is one of the five allowed | One resource object per function, plus the second-pass problem in reverse                                                                                                                                                                                           | Documentation, not review                          |
| **Flatten: one role per reviewable function**                                     | A first-class review item per function, each with its own **Application** column, access rights and revoke toggle                      | Roughly one role object per function, and it multiplies reviewer rows — a role with eight functions turns one decision into eight                                                                                                                                   | The only option that yields per-function decisions |
| **Keep the coarse role, write the function list into the membership description** | The function list as **Assignment details** on the item, next to the one decision the reviewer makes                                   | Near zero — one extra column in the assignment feed                                                                                                                                                                                                                 | Best default                                       |

### Recommendation

Model **each application as its own managed system**, run **one application campaign per application**, and use the **membership-description** approach as your baseline: the reviewer gets the context of what the role actually permits, without being asked eight questions where the organisation only has one answer. Then **promote a function to its own role only where the organisation would genuinely revoke it individually** — the one dangerous permission in Ledger that some holders of `Debt Management` should not have. That keeps the reviewer's row count proportional to the number of real decisions.

{% hint style="danger" %}
**A nested tree with per-node approve and revoke is a customization, not configuration.** It requires a new review item type and new reviewer screens — item generation that walks the hierarchy, a persisted decision per node, and a UI to render and collect it. No combination of settings, metadata, role attributes or resource nesting produces it. Plan around the flat decision unit, or scope a development project against the Developer Guide; there is no third path.
{% endhint %}

## Verification

| Check                                    | How                                                                                                 | What passing looks like                                                                                              |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Users exist before assignments           | Search a sample of the principals in the assignment file                                            | Each resolves to exactly one identity                                                                                |
| Managed system created, resource linked  | `/webconsole/mngsystemlist`; look for a resource whose `COORELATED_NAME` is the managed system name | The resource exists under a generated `<Name>_<millis>` name — that is correct, not a fault                          |
| Roles carry the managed system           | Role search filtered by the Ledger managed system                                                   | Count matches the role import file; every role you expect is present                                                 |
| Roles are visible to a campaign          | Open the campaign's entitlement picker for that application                                         | The same roles appear there; absence here predicts absence from the campaign                                         |
| Assignments landed                       | `/webconsole/synchronization-history` for the assignment run, plus two or three user records        | Zero error records, or only errors you have explained; the roles show on the users                                   |
| Scope resolves                           | Save the campaign and run a preview                                                                 | `includedItemCount` is close to the number of assignment rows for that application                                   |
| Campaign generated                       | Audit log                                                                                           | `EXECUTE_CERTIFICATION`, then `EXECUTE_CERTIFICATION_BATCH` per batch and `INITIATE_CERTIFICATION_WORKFLOW` per user |
| Reviewer can tell the applications apart | Open a reviewer's campaign view                                                                     | The **Application** column is populated on every row — no blanks                                                     |
| Decisions are being recorded             | Audit log                                                                                           | `COMPLETE_CERTIFICATION_REVIEW` per decision                                                                         |

## When it goes wrong

| Symptom                                                                                                     | Cause                                                                                                                                                                          | Fix                                                                                                                                    |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| An imported role never appears in the campaign, and its **Application** cell is blank anywhere it does show | The role's `MANAGED_SYS_ID` is null, so it is not an entitlement of any application and the campaign's scope filter cannot see it                                              | Set the managed system on the role, or set it on the synchronization configuration and re-import                                       |
| Assignment rows silently do nothing and the run reports failures                                            | The user did not exist: the transform returned `TransformScript.SKIP` (`-1`) and the run recorded `TRANSFORMATION_RETURN_SKIP` with a status of `FAILURE` — no user is created | Load the users first, then re-run the assignment import; read `/webconsole/synchronization-history` for the exact rows                 |
| The job log says *"Role with name … was not found"*                                                         | The role does not exist under that managed system — the script matches on **name plus managed system id**                                                                      | Run the role import first; check for a name mismatch, including case and trailing spaces                                               |
| Searching the resource list for `Ledger` finds nothing                                                      | The generated resource is named `<managed system name>_<epoch millis>`; the readable name is in `COORELATED_NAME`                                                              | Search on `COORELATED_NAME`, or use a partial-match search on the prefix                                                               |
| A custom resource type such as `APP_FUNCTION` is missing from the entitlement diagram                       | The diagram renders only `AUTH_PROVIDER`, `CONTENT_PROVIDER`, `MANAGED_SYS`, `MAN_MANAGED_SYS` and `URL_PATTERN` — anything else is dropped with no message                    | Do not model reviewable functions as custom resources; flatten them to roles, or put the list in the membership description            |
| Child roles do not appear under their parent for the reviewer                                               | Only direct memberships generate review items; nesting is not certified                                                                                                        | Flatten the functions you need decided, and accept that a revoke on the parent acts on the parent membership only                      |
| A resource assigned directly to a user is never reviewed                                                    | A review item can only point at a role or a group; resources only widen the in-scope user population                                                                           | Represent anything that must be reviewed as a role or a group                                                                          |
| Custom attributes loaded onto roles never appear to the reviewer                                            | `ROLE_ATTRIBUTE` rows are stored but no certification screen renders them                                                                                                      | Use the per-membership description (**Assignment details**) or the role description instead                                            |
| The **Application** column cannot be sorted                                                                 | The column holds a display-only name, so it is filterable but not sortable                                                                                                     | Filter instead of sorting, export the campaign from the certification reports and sort there, or use the break-glass count query above |
| There is no campaign fixture to copy                                                                        | OpenIAM ships no example campaign                                                                                                                                              | Build the first campaign in the Webconsole, then clone it per application                                                              |

## Related

* [Connectors and managed systems](/administration-guide/lifecycle/connectors-and-managed-systems.md) — creating the managed system that makes an application a scope
* [Import roles, groups, organizations and entitlement memberships](/administration-guide/lifecycle/synchronize-and-import-data/import-roles-groups-and-memberships.md) — the import mechanics for users, roles and assignments
* [Edit a synchronization transformation script](/administration-guide/automation/synchronization-scripts.md) — the shipped transform scripts and their column contracts
* [Plan and scope a campaign](/administration-guide/governance/certification/plan-and-scope-a-campaign.md) — the three types, preview and launch
* [Create an application campaign](/administration-guide/governance/certification/create-an-application-campaign.md) — the Applications tab, selection modes and reviewer types
* [Membership tags](/administration-guide/governance/certification/membership-tags.md) — excluding specific memberships from a campaign

*Applies to OpenIAM 2026.9.1. Last reviewed 14 September 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/governance/certification/review-application-entitlements.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.
