> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ravenna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Entitlements

> Track and manage active access grants with entitlement lifecycle states, extensions, and revocation.

## Data model

An `AccessEntitlement` record includes:

* `id`, `userId`, `status`, `createdAt`
* `accessRequestId`: the originating request
* `userGroupId`, `applicationId`: the provisioned resource
* `expiresAt`: set when the access policy defines a duration. Ravenna calculates it from the moment the entitlement is provisioned, not from when the request was submitted or approved. A 2-day grant that takes a day to approve still lasts 2 days once access is granted.
* `revokedAt`, `revokedByUserId`, `revokeNote`: populated on revocation
* `provisionedAt`: timestamp when provisioning completed
* `parentEntitlementId`: links an extension to its origin entitlement
* `lineage` (computed): array of related entitlements for extension chains, derived from `parentEntitlementId` relationships

Status transitions follow: Pending → Processing → Active (or Failed Provisioning). On revocation: Active → Deprovisioning → Inactive (or Failed Revocation).

***

## Key operations

* **List**: filterable by application, user, status, and workspace. Returns Ravenna-managed and externally managed entitlements together unless you filter on `unmanagedEntitlements`. The Settings UI adds a default `status in [active]` filter when the user hasn't picked a status; the API and MCP tool don't apply that default.

  To list only Ravenna-managed entitlements, pass `unmanagedEntitlements: false` in `filters`. Pass `true` to list only externally managed ones.

  ```json theme={"system"}
  [
    { "field": "unmanagedEntitlements", "condition": "equals", "value": false },
    { "field": "status", "condition": "in", "value": ["active"] }
  ]
  ```
* **Extend**: creates a child entitlement with `parentEntitlementId` set to the original. Does not modify the original record. Takes an array of entitlement IDs and a duration in milliseconds; only applies to time-limited entitlements.
* **Revoke**: sets `revokedAt`, `revokedByUserId`, and triggers deprovisioning for synced apps. Failure results in `Failed Revocation` status. Takes an array of entitlement IDs and an optional `revokeNote`.
* **Manual provision**: marks a pending manual entitlement as provisioned after a human grants access in the target system. Reachable from the ticket or from the Slack DM sent to the ticket assignee when the entitlement enters `processing`.

Extend and revoke are available in the app, via the REST API, over the [MCP server](/documentation/automate/mcp/tools), and as Ravenna Copilot tools, so an agent or Copilot conversation can revoke or extend access directly.

Copilot and agents can also search entitlements with the `search_access_entitlements` tool. Only organization admins can use it. The tool filters by user, application, free-text query, and status, returns active entitlements unless statuses are passed, and pages results (default 50, maximum 100 per page). Each row reports `managed_by` as `ravenna` or `external`. Only `ravenna` rows work with revoke and extend.

***

## Constraints

* Externally managed entitlements are built from IdP group membership and aren't persisted. Their `id` starts with `synthetic-`, their status is always `active`, and they have no access level or access request. Revoke and extend reject them. A user with a Ravenna-managed entitlement for the same application in `pending`, `processing`, `active`, `deprovisioning`, `failed_revocation`, or `skipped_revocation` isn't also listed as externally managed.
* Filtering by access level or by statuses that exclude `active` returns only Ravenna-managed entitlements. Filtering by `ids` also returns only Ravenna-managed entitlements, unless the list includes a `synthetic-` ID. Externally managed IDs resolve, so you can pass them to downstream workflow steps.
* Entitlement records are immutable; status changes accumulate as audit history rather than overwriting.
* Extension creates a new record and does not modify the original.
* Revocation of a synced app calls the IdP integration. If the call fails, the entitlement status is set to `Failed Revocation`.
* `Skipped Revocation` occurs when another active entitlement grants the same access, preventing unnecessary removal, or when the user no longer holds the mapped group or role in the IdP, so there is nothing to remove. The entitlement carries a reason in both cases.
* When an access request reaches `provisioned` or `partially_provisioned`, the originating ticket is set to the workspace's Done status by the system user. No workflow is involved.
* The Slack manual provisioning prompt requires a published ticket with an assignee who has Slack connected.


## Related topics

- [Manually provision entitlements](/api/access-entitlement/manually-provision-entitlements.md)
- [Extend access entitlements](/api/access-entitlement/extend-access-entitlements.md)
- [List access entitlements](/api/access-entitlement/list-access-entitlements.md)
- [Revoke access entitlements](/api/access-entitlement/revoke-access-entitlements.md)
- [Access provisioning](/documentation/automate/access-provisioning/overview.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.