> 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/operate-a-live-campaign.md).

# Operate a live campaign

Operate a launched campaign — watch the right run, extend or expire it, understand exactly what a revoke decision does to access, and close it with evidence intact.

## What this is, and when you need it

A launched campaign is a live process with a deadline, run by reviewers who have other jobs. That is what makes this stage its own discipline: the design is fixed once a campaign starts — editing the certification does not change a run already under way — the campaign finishes only if somebody is watching it, and a reviewer's decision is not a recommendation, it changes real access. Expect to extend a window, chase a step that has stopped, expire what nobody answered, and explain one revocation in detail to the person it affected.

The reviewer's own click path is in the **SelfService Guide**; this page covers the context you supply and the outcome you verify. Designing the campaign is [Plan and scope a campaign](/administration-guide/governance/certification/plan-and-scope-a-campaign.md); the evidence pack afterwards is [Campaign history and evidence](/administration-guide/governance/certification/campaign-history-and-evidence.md).

The one thing to know before you start: **remediation is automatic**. A revoke decision dispatches provisioning as soon as the user's review step settles. There is no separate "apply decisions" step to forget, and no undo.

## At a glance

|                          |                                                                                                                                                                  |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **You will end up with** | A campaign in a terminal state, its revocations fulfilled or tracked as manual work items, and its complete report exported                                      |
| **Where**                | `/webconsole/access-certification-edit?id=<CERTIFICATION_ID>` → **Dashboard** and **History** tabs                                                               |
| **You need first**       | The `CAMPAIGN_ID` of the run you mean — a certification has many; the certification's `ON_EXPIRE_ACTION`, because it decides what expiry actually does           |
| **Takes**                | Minutes per check, over the life of the campaign                                                                                                                 |
| **Reversible**           | **No.** Revocations dispatch provisioning; a forced expiry runs the on-expiry action; deleting a campaign destroys its whole evidence trail and cannot be undone |

## Before you begin

The Dashboard's picker is labelled *Select Campaign to View Details* — a certification may have many campaigns, so always confirm which run you are looking at. And read the certification's **Action on expire** before you treat expiry as a remediation lever: at the shipped `DO_NOTHING`, forcing expiry revokes nothing. It is on [Configure the review workflow](/administration-guide/governance/certification/configure-the-review-workflow.md).

## Take it from launched to closed

{% stepper %}
{% step %}

### Watch progress on the run you mean

**Dashboard** tab, with the run you mean chosen in **Select Campaign to View Details**. The chart legend *Completed* / *Under Review* / *Not Started* is drawn from the denormalized `CAMPAIGN.COMPLETED_COUNT`, `TOTAL_COUNT` and `NOT_STARTED_COUNT` columns rather than from a live count of `ACCESS_REVIEW_ITEM`. Those counters are updated with an atomic database-side delta so concurrent completions cannot lose an update — but reconcile before you treat a discrepancy as a stall. The tab also shows **Original campaign duration** and the **Campaign Reviewers** table with its **Approver Name** column.

In the campaign list, `AWAITING_SIGN_OFF` deliberately ranks with `IN_PROGRESS`, because it is a still-open state, so the progression `IN_PROGRESS → AWAITING_SIGN_OFF → COMPLETED` stays monotonic.
{% endstep %}

{% step %}

### Chase a step that has stopped

The **Participants & scope** section on the Dashboard is where you look: **Participated Users**, **Participated Groups** and **Participated Roles** tell you who is in the run at all, and **Access Review Items** lists the items themselves, filterable to one user. If reviewers say they have no task while items exist, the problem is the subsystem rather than the campaign — go to [Diagnose a stalled campaign](/administration-guide/governance/certification/diagnose-a-stalled-campaign.md).

If the reviewers exist and are simply not acting, that is what `REQUEST_REMINDERS` is for, and it ships disabled.

The managers of a campaign **already running** cannot be changed from the console. **Manager of Access Review** on the **Configurations** tab sets them for campaigns launched afterwards; an open run keeps the copy it took at launch. Changing that copy needs a support request; when it happens the change is audited `UPDATE_CAMPAIGN_MANAGERS`, recording the previous and the new managers by name.
{% endstep %}

{% step %}

### Extend, once, if the window is genuinely too short

**Extend campaign expiration** on the Dashboard, audited `EXTEND_CERTIFICATION_CAMPAIGN`. Set **Extend expiration for (days)**, tick **Cascade extension** to push the extension down to later reviewer steps as well as the current one, and fill in **Provide reason to extend expiration of selected campaign**. The confirmation warns that the due date changes for all open requests and cannot be undone.

Validation runs before anything changes, and the refusal names a specific code:

| Code                        | Meaning                                                             |
| --------------------------- | ------------------------------------------------------------------- |
| `EMPTY_JUSTIFICATION`       | The reason was left blank — it is required                          |
| `EXPIRATION_IS_DISABLED`    | `CERTIFICATION.ALLOW_EXPIRING = 'N'`, so there is nothing to extend |
| `EXPIRATION_DAYS_EXCEEDED`  | The number of days exceeds `CERTIFICATION.MAX_EXTENSION_EXP_DAYS`   |
| `CAMPAIGN_ALREADY_EXTENDED` | `CAMPAIGN.WAS_EXTENDED = 'Y'` — **a campaign may be extended once** |

The audit attribute recording the cascade is `CASCADE_EXTENSION_IN_DAYS`, alongside `EXTEND_REASON`. `CAMPAIGN.EXTENDABLE` records whether extension is permitted for this run at all.
{% endstep %}

{% step %}

### Expire what nobody answered

**Expire selected campaign** on the Dashboard, audited `FORCE_EXPIRE_CERTIFICATION_CAMPAIGN`. It asks for **Provide reason to expire selected campaign** and warns *"Force expiration of the selected campaign? This process will complete all open requests and add appropriate audit entries. This action cannot be undone."*

OpenIAM counts the campaign's open Activiti tasks first. With none, it reports *"No tasks have been found to expire"* and does nothing. With one or more, it starts expiring in the background — *"Expiration has been initiated. This is a background process and depending on the volume of data, this process can take some time."* — and each item then runs the certification's `ON_EXPIRE_ACTION`, so **forcing expiry on a campaign configured `DO_NOTHING` revokes nothing**.
{% endstep %}

{% step %}

### Confirm revocations reached the target

A `REVOKED` outcome on a review item is a decision, not proof. Two things can leave the managed system untouched: a **manual** managed system raises a work item instead of calling a connector, and a system with provisioning disabled changes only the OpenIAM side. Both are covered under [What a revoke decision actually does](#what-a-revoke-decision-actually-does) below, and both are checks you have to make deliberately.
{% endstep %}

{% step %}

### Read the final state, and export before you delete anything

Once every item is settled, the sign-off policy decides the status:

| Condition                                                 | Resulting campaign status |
| --------------------------------------------------------- | ------------------------- |
| Every request expired without review                      | `EXPIRED`                 |
| At least one request expired without review               | `PARTIALLY_EXPIRED`       |
| Every item auto-certified — **no human decided anything** | `AWAITING_SIGN_OFF`       |
| Anything else — at least one human decision               | `COMPLETED`               |

One human decision anywhere is treated as the attestation, so a normally reviewed campaign closes straight to `COMPLETED`. Only a campaign settled entirely by the automation rules is held, and nothing in the product can release it — see [Operate certification services](/administration-guide/governance/certification/operate-certification-services.md#a-known-issue-the-sign-off-gate-has-no-caller).

The completion handler then generates the complete report and, for campaign managers, sends `UAR_CAMPAIGN_COMPLETED` or `UAR_CAMPAIGN_EXPIRED`. Export that report and the campaign-history views before anybody deletes anything — see [Campaign history and evidence](/administration-guide/governance/certification/campaign-history-and-evidence.md).
{% endstep %}
{% endstepper %}

{% hint style="danger" %}
**In this build nothing exposes sign-off.** There is no Webconsole screen and no SelfService screen that signs a campaign off, and nothing else in the product triggers it either. A fully reviewed campaign therefore reaches `AWAITING_SIGN_OFF` and stays there, because the gate is mandatory and the control that opens it is not exposed anywhere. You cannot confirm this from a screen — the absence of a button is the evidence. Confirm against your release notes before you build a control that depends on `STATUS = 'COMPLETED'`, and support can confirm it for your version.

When sign-off does run, it takes a signer and, optionally, a list of items the signer rejects. Signing off with nothing rejected sets `STATUS = COMPLETED`, `SIGNED_OFF_BY`, `SIGN_OFF_DATE` and `ACTUAL_COMPLETED_DATE`. Rejecting items instead **reopens** them — clearing `REVIEW_OUTCOME`, `AUTO_CERTIFIED`, `HIDDEN_FROM_REVIEWER`, `DECISION_DATE`, `ACCESS_REVOKED` and `ACCESS_REVOKED_BY` — returns the campaign to `IN_PROGRESS` and decrements `COMPLETED_COUNT` by the number reopened. The signer defaults to the first campaign manager, falling back to `CAMPAIGN.LAUNCHED_BY`.

Practical consequences: `AWAITING_SIGN_OFF` is a normal, expected end state to see on a completed campaign; the complete report is still generated and still accurate, because it is produced when the last item settles, not on sign-off; and `SIGNED_OFF_BY` and `SIGN_OFF_DATE` will be `NULL`.
{% endhint %}

## Verification

| Claim                                     | Evidence                                                                                                                                                                                 |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Progress is real                          | The Dashboard chart's counts reconcile against `SELECT REVIEW_OUTCOME, COUNT(*) FROM ACCESS_REVIEW_ITEM WHERE CAMPAIGN_ID = ? GROUP BY REVIEW_OUTCOME`                                   |
| A decision was recorded                   | An `ACCESS_REVIEW_ITEM_AUDIT` row with `REVIEWER_ID`, `REVIEW_DATE`, `AUDIT_SPECIFICATION` and `DECISION_SOURCE`; audit `MAKE_ACCESS_REVIEW_ITEM_DECISION`                               |
| A bulk decision was used                  | `ACCESS_REVIEW_ITEM_AUDIT.DECISION_SOURCE = 'BULK'`; audit `SUBMIT_BULK_ACCESS_REVIEWS`                                                                                                  |
| Revocation reached provisioning           | Audit `COMPLETE_CERTIFICATION_REVIEW`, then `PROVISIONING` for the target user with the same parent audit log id                                                                         |
| Access was actually changed               | The membership on the user: removed if `org.openiam.workflow.termination.access.remove=true`, otherwise present with an end date in the past                                             |
| A manual revocation is outstanding        | `ACCESS_REVIEW_ITEM.ACCESS_COMMENT` matching `Manual task to revoke access: %`, and that request still open                                                                              |
| Expiry did what the policy says           | `ACCESS_REVOKED_BY` = the system user id (`0001`), outcome `REVOKED`, and Campaign History attributes the decision to `EXPIRATION_POLICY`; audit `INITIATE_CANCELING_OF_EXPIRED_REQUEST` |
| The campaign is closed                    | `CAMPAIGN.STATUS` and `ACTUAL_COMPLETED_DATE`; `SIGNED_OFF_BY` and `SIGN_OFF_DATE` only when sign-off ran                                                                                |
| Review finished, whatever the status says | `CAMPAIGN.ACTUAL_COMPLETED_DATE` is set and `COMPLETED_COUNT = TOTAL_COUNT`                                                                                                              |

## When it goes wrong

| Symptom                                                                            | Cause                                                                                                                                | Fix                                                                                                                                                         |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| A fully reviewed campaign sits in `AWAITING_SIGN_OFF`                              | The sign-off gate is mandatory and nothing in this build invokes it                                                                  | Expected. Use the complete report as evidence; do not build controls on `STATUS = 'COMPLETED'`                                                              |
| Dashboard counts disagree with a query over review items                           | The counts are denormalized `CAMPAIGN.*_COUNT` columns                                                                               | Reconcile against `ACCESS_REVIEW_ITEM`; a persistent gap is a counter defect worth reporting                                                                |
| A reviewer's Approve or Revoke-all button is absent                                | `CAMPAIGN.ALLOW_BULK_APPROVAL = 'N'`                                                                                                 | Enable on the definition and launch a new campaign — the flag is a per-run copy                                                                             |
| A reviewer's bulk submission is refused outright                                   | Same flag; the submission is rejected before anything is written                                                                     | As above                                                                                                                                                    |
| A revoked entitlement is still on the user                                         | `org.openiam.workflow.termination.access.remove` is `false` (default) — it was end-dated                                             | Expected. Set `true` if your control requires removal                                                                                                       |
| A revoked entitlement is still in the managed system                               | The managed system is manual, so a `MANUAL_TASK` sub-process was created instead of a connector call                                 | Find the request id in `ACCESS_COMMENT` and close the manual task                                                                                           |
| Nothing was provisioned at all                                                     | Provisioning is disabled, so the change went through an asynchronous user save only and no connector was called                      | Confirm the provisioning configuration; the OpenIAM-side change did happen, so the user's entitlement list has moved even though the managed system has not |
| Extension refused with `CAMPAIGN_ALREADY_EXTENDED`                                 | `CAMPAIGN.WAS_EXTENDED = 'Y'` — one extension per campaign                                                                           | Expire and relaunch, or widen the reviewer window on the definition for next time                                                                           |
| Force-expire reported success but revoked nothing                                  | `ON_EXPIRE_ACTION` is `DO_NOTHING`                                                                                                   | Set `REVOKE_ALL_ACCESS` before relying on expiry as remediation                                                                                             |
| Force-expire reported *"No tasks have been found to expire"*                       | No open Activiti task carries the campaign id                                                                                        | The campaign is already settled                                                                                                                             |
| Items reopened themselves and the campaign went back to `IN_PROGRESS`              | A sign-off was submitted rejecting some items                                                                                        | Expected: rejection reopens those items and decrements `COMPLETED_COUNT`                                                                                    |
| Risk scores did not move after a campaign                                          | Attestation emission is best-effort and skipped when `risk-manager` has no live consumer                                             | Check `risk-manager` is up; the service log records *"Risk Manager Service is not running. Skipping risk attestation …"*                                    |
| A reviewer's comparison shows no difference for a user you know holds extra access | The comparison covers **direct role and group memberships only** — resources, organizations and inherited memberships are not diffed | Expected. See [What a reviewer can compare against](#what-a-reviewer-can-compare-against); read the user's full entitlement list for the rest               |
| A comparison is reported as truncated                                              | A side exceeded the 10,000-entitlement cap and was cut at a deterministic key order                                                  | Expected on very large entitlement sets. Compare against a campaign launch, which is already scoped, rather than against a live user                        |
| The risk-increase filter returns nothing                                           | Risk decoration is applied only when `risk-manager` answers                                                                          | Confirm the service is up — the comparison itself works without it                                                                                          |
| Nothing at all is progressing                                                      | The subsystem rather than the campaign                                                                                               | [Diagnose a stalled campaign](/administration-guide/governance/certification/diagnose-a-stalled-campaign.md)                                                |

## What a reviewer can compare against

A reviewer facing a user with dozens of entitlements has no context for judging any single row. **Entitlement comparison** supplies it: from the reviewer screen, the reviewed user's current access is diffed against a baseline, and the differences are highlighted. It is available in **every** campaign type, and there is nothing to enable.

Two baselines are offered.

| Baseline                       | What it diffs against                                                                    | Use it to answer                                                                    |
| ------------------------------ | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| **Another user**               | That user's **current** access, read live                                                | *Does this person hold more than a peer doing the same job?*                        |
| **A previous campaign launch** | The frozen access review items from an earlier launch — of this certification or another | *What has changed since we last reviewed this person, and what did we decide then?* |

Launches of the current certification are offered first, then launches of other certifications. The campaign being reviewed is never offered as its own baseline.

{% hint style="info" %}
**Why the baseline is a launch and not a date.** OpenIAM keeps no general history of membership changes — once an entitlement is removed, no durable record of the old membership survives. The access review items captured at launch are the platform's only authoritative point-in-time snapshot of what someone held, which is why "compare against last quarter" is expressed as *compare against that quarter's launch*.
{% endhint %}

Against a previous launch, each matched item also shows its **prior outcome** — certified, revoked, not reviewed or excluded — with who decided it. Revocations made automatically by an expiration policy are attributed to the policy rather than to a person, so an unattended revocation is not mistaken for somebody's judgement.

Results are grouped by application and summarised as counts, which is where most reviewers start. Against a peer the counts are **In common**, **Only \<reviewed user>** — the extra access to scrutinise — and **Only \<peer>**. Against a previous launch they are the four an auditor asks for: **Revoked then — held again**, **Certified then — still held**, **New since** and **Revoked and gone**.

On entitlements both sides hold, the diff goes below the membership itself and reports **attribute-level differences** — the access rights carried, and the membership's validity window. A rights escalation on an otherwise-identical membership is therefore not hidden behind an "in common" label.

Two filters narrow the result to the rows that usually matter: entitlements **previously revoked** — the re-granted-after-revocation case, which is the one auditors ask about, surfaced as a banner carrying the affected count and a **Show these** filter, with each row flagged *Re-granted after revocation* — and those whose **risk has increased** since the baseline.

{% hint style="warning" %}
**The comparison covers direct role and group memberships only.** A live side is built from the user's roles and groups; resources and organizations are not diffed, and neither are memberships inherited rather than held directly. A reviewer told that comparison shows "everything this person has" will draw the wrong conclusion from a clean diff.

Tell reviewers what it covers, or they will read absence as evidence.
{% endhint %}

Two more limits worth knowing before you rely on it:

* **Each side is capped at 10,000 entitlements.** Beyond that the side is sorted by key and truncated, and the result is flagged as truncated rather than silently shortened. Paging stays deterministic.
* **The risk-increase filter needs `risk-manager` running.** Risk decoration is applied only when the service answers; with it down the comparison still works and the risk filter has nothing to act on.

Reviewer visibility is preserved rather than bypassed. On a campaign-launch baseline, items hidden from the reviewer stay hidden unless the caller explicitly asks for them, and comparison never widens what a reviewer is already entitled to see.

## What a revoke decision actually does

The workflow only translates the decision; the work that follows is audited `COMPLETE_CERTIFICATION_REVIEW`. Per user, when their step settles:

1. Items are partitioned into revoked roles, revoked groups, approved roles, approved groups.
2. For a normally completed review, **only revoked access changes the user** — approvals are recorded, not re-provisioned.
3. The revoked roles and groups are applied to the user as a provisioning request.
4. Manual work items are built for any revocation whose managed system is manual.
5. Campaign counters are incremented atomically.
6. If anything changed, provisioning is dispatched.
7. Items are saved, and each settled outcome is fed back to risk as an attestation — best-effort, and skipped entirely when `risk-manager` has no live consumer, so a down `risk-manager` never blocks completion.

### Remove versus end-date

{% hint style="warning" %}
Whether a revocation *removes* the membership or merely *end-dates* it is decided by one property:

| Property                                         | Shipped default | Behaviour on revoke                                                                                      |
| ------------------------------------------------ | --------------- | -------------------------------------------------------------------------------------------------------- |
| `org.openiam.workflow.termination.access.remove` | **`false`**     | The membership's end date is set to now and the operation is `REPLACE` — the row stays, with an end date |

Set `true` and the role or group is removed from the user outright. Its Webconsole label is *"Remove access when a user is terminated (if 'No', access will be end-dated instead)"*, and the same flag governs certification revocation. On a default installation, a revoked entitlement is still visible on the user with a past end date. If your control asserts that revoked access was *removed*, verify which behaviour you have before you attest to it.
{% endhint %}

Two related details. If the entitlement had already lapsed in the target and reconciliation had brought that back, the item gets a system comment instead of a second revocation: *"Reviewer made decision, however, this entitlement has already been revoked on from the managed system and changes have been reflected in OpenIAM via reconciliation."* And the change is dispatched to provisioning only when provisioning is enabled; otherwise it goes through an ordinary asynchronous user save — so on a system with provisioning disabled the OpenIAM-side change happens and the managed system is not touched at all. The observable difference is the absence of any connector activity for the revocation, not an error.

### Manual fulfilment

Revocations on a **manual** managed system cannot be pushed by a connector. For each managed system marked manual, OpenIAM resolves its resource and raises one manual work item per resource. The workflow starts a `MANUAL_TASK` sub-process per work item and stamps the resulting request id back onto every affected review item as `ACCESS_COMMENT`, in the form:

{% code overflow="wrap" %}

```
Manual task to revoke access: <REQUEST_ID>
```

{% endcode %}

That string is your bridge from a certification decision to the manual ticket that carries it out. **A campaign is not remediated until those manual tasks are closed** — the certification will report `REVOKED` regardless, so a complete report is not evidence that access left the managed system. Track them through [Manual fulfilment](/administration-guide/requests/fulfilment.md).

## Bulk decisions

Bulk decisions live in SelfService because they are a reviewer action, but an administrator enables them and answers for them. A reviewer can decide in bulk at two grains, both audited as `SUBMIT_BULK_ACCESS_REVIEWS`:

| Grain           | Scope of one decision                              |
| --------------- | -------------------------------------------------- |
| Per user        | Every item the reviewer holds for that user        |
| Per entitlement | Every item the reviewer holds for that entitlement |

OpenIAM resolves the reviewer's items behind each selection, aggregates them into one decision batch, and submits it through the same path as individual decisions — so audit, notification and provisioning behave identically, and a bulk decision is indistinguishable from a series of single ones except for `DECISION_SOURCE = 'BULK'` on the audit rows.

Bulk submission is **refused outright when `CAMPAIGN.ALLOW_BULK_APPROVAL` is `'N'`, with nothing submitted**, and a selection that resolves to no items submits nothing and reports no error. `ALLOW_BULK_APPROVAL` is a per-run copy taken at launch, so revoking it on the definition does not disable it on a running campaign — you cannot close that door mid-flight.

Decisions submitted one at a time are audited `SUBMIT_BULK_ACCESS_REVIEWS` for the submission itself and `MAKE_ACCESS_REVIEW_ITEM_DECISION` per item.

Everything decided in bulk is marked: `ACCESS_REVIEW_ITEM_AUDIT.DECISION_SOURCE = 'BULK'`, and the complete report's `BULK_APPROVAL_RISK` column reads *"YES - reviewed via bulk approval (RISKY: items not reviewed individually)"*. Treat a campaign whose report is mostly that string as evidence of a scoping problem, not of a completed review.

## Deleting a campaign

**Delete campaign** on the Dashboard, audited `DELETE_CERTIFICATION_CAMPAIGN`. The confirmation reads *"Delete the selected campaign? This process will delete all open requests and related data objects (campaign, reviewer data, participating users, etc.). This action cannot be undone."*

{% hint style="danger" %}
Deleting a campaign deletes its generated tasks **whether or not they have already been completed**. `ACCESS_REVIEW_ITEM`, `ACCESS_REVIEW_ITEM_AUDIT`, `ACCESS_REVIEW_ITEM_SOD_VIOLATION`, `CAMPAIGN_STEP` and `CAMPAIGN_PREVIEW_EXCLUSION` all cascade from `CAMPAIGN` with `ON DELETE CASCADE`. You are destroying the evidence that the review happened, and it does not come back. Export the complete report first — see [Campaign history and evidence](/administration-guide/governance/certification/campaign-history-and-evidence.md). A `UAR_CAMPAIGN_DELETED` notification is sent, and the related bulk actions are audited `DELETE_CERTIFICATION_REQUESTS_IN_BULK` and `DELETE_CAMPAIGN_REQUESTS_IN_BULK` — those audit rows are all that is left afterwards.
{% endhint %}

**Deletion is background work.** The button returns as soon as the purge is dispatched, so on a large campaign the rows disappear progressively rather than all at once — a campaign still visible to a query a few moments after you deleted it is mid-purge, not stuck.

## Where to watch

| View                                              | Route                                                                                                                                                                                                      |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Campaign dashboard, charts and reports            | `/webconsole/access-certification-edit?id=<CERTIFICATION_ID>` → **Dashboard** tab                                                                                                                          |
| Launch history and per-campaign outcomes          | same screen → **History** tab                                                                                                                                                                              |
| One user's certification history across campaigns | `/webconsole/user-certification-history?id=<USER_ID>`                                                                                                                                                      |
| A reviewer's own queue                            | `/selfservice-v2/uar/campaigns`, detail `/selfservice-v2/uar/campaigns/{id}` — what they see there is [What your reviewers see](/administration-guide/governance/certification/the-reviewer-experience.md) |

### Reading a finished campaign

The **History** tab shows a different, richer view — the union of the exclusion slice and the reviewed slice described on [The certification model](/administration-guide/governance/certification/certification-model.md). **Launch history** lists every previous launch of the certification; clicking a row opens **Campaign outcome**, whose tiles each drill into the rows behind them:

| Section       | Tiles                                                                                   |
| ------------- | --------------------------------------------------------------------------------------- |
| **Scope**     | **Users included**, **Users excluded by scope**, **Items included**, **Items excluded** |
| **Reviewers** | **Reviewers participated**, **Accesses delegated**                                      |
| **Decisions** | **Accesses certified**, **Accesses revoked**                                            |

Each row carries an outcome — `EXCLUDED`, `CERTIFIED`, `REVOKED` or `NOT_REVIEWED` — and, for the last two, what produced it: `REVIEWER`, `EXPIRATION_POLICY` or `NONE`. That attribution is derived from the revoking actor when the view is read, not stored as a column, so it cannot be queried directly. Both tables are frozen once the campaign ends, which is what makes the view reproducible.

## Related

* [Campaign history and evidence](/administration-guide/governance/certification/campaign-history-and-evidence.md) — export the evidence before you delete anything
* [Configure the review workflow](/administration-guide/governance/certification/configure-the-review-workflow.md) — the on-expiry action and the two batch tasks
* [Diagnose a stalled campaign](/administration-guide/governance/certification/diagnose-a-stalled-campaign.md) — when the subsystem rather than the reviewers has stopped
* [Manual fulfilment](/administration-guide/requests/fulfilment.md) — closing the manual tasks a revocation creates
* [Audit actions and retention](/administration-guide/reference/audit-actions-and-retention.md) — the constants named above

*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/operate-a-live-campaign.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.
