> ## 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.

# Applications

> Build and manage your application catalog with access levels, provisioning methods, and identity provider integrations.

Applications represent the external tools and services your organization uses. By defining applications in Ravenna with their corresponding access levels and provisioning methods, you create a structured catalog that supports automated access requests.

## Mental model

The application is the core primitive of the access catalog. It answers the question: what can users request access to, and at what permission level?

Key relationships:

* An organization has many applications.
* An application has many access levels.
* Each access level has a provisioning method and can optionally map to an IdP group.
* Each access level has an assignment strategy that controls how approvers are assigned.
* Applications are organization-scoped but can be made visible in specific workspaces.

**Synced vs manual:** Applications with `integrationApplicationId != null` are synced from an access provider (Okta, Microsoft Entra ID, JumpCloud, OneLogin, or Cloudflare). `isSynced` is the relevant check for enforcing edit restrictions: synced applications cannot be deleted, and their name and image are controlled by the IdP. All other fields (display name, owners, approvers, workspaces, post provisioning message) can be set regardless of sync status.

**Google Workspace never produces synced applications.** Google-federated applications are always manual entries. Group provisioning still works: it resolves the access level's mapped group to a Google Group and adds the user there, without consulting the application record.

**Access levels** are scoped to a single application. There is no shared or global access level concept across applications.

***

## Provisioning method selection

| Method | When to use |
| - | - |
| **Group** | IdP manages application access through group membership. After approval, add the user to the mapped IdP group. Supported by Okta, Microsoft Entra ID, Google Workspace, JumpCloud, Cloudflare, and OneLogin. |
| **Application** | Direct application assignment is preferred over group membership in the IdP. After approval, add the user to the application directly. Supported by Okta only. |
| **Manual** | No IdP connection or automated provisioning path exists. A human must provision access and mark the entitlement complete. |
| **Workflow** | Custom provisioning logic is required, such as calling external APIs or chaining multiple steps beyond what standard IdP actions support. |

If no IdP integration is active, use **Manual** or **Workflow**. Group and Application methods require a connected integration; provisioning actions will fail if the integration is disconnected even if the mapping is configured.

***

## Assignment strategy selection

Assignment strategies are configured per access level, not per application. Different levels within the same application can use different strategies.

| Strategy | Approvers assigned | Approval required from | Best for |
| - | - | - | - |
| **Auto** | System bot | None, approved immediately | Low-risk apps, dev/test environments, self-service tools |
| **All** | All configured approvers | Any one approver | Multiple qualified approvers, fastest response time needed |
| **Round Robin** | One approver (rotated) | The assigned approver | Balancing workload across a team, avoiding bottlenecks |

Common pattern: use Auto for basic access levels (such as Member) and All or Round Robin for elevated access levels (such as Admin).

***

## Constraints and gotchas

* Applications are organization-scoped. All workspaces share the same catalog, but workspace visibility is configurable per application.
* Synced applications (`integrationApplicationId != null`) cannot be deleted and do not allow name or image edits. Custom display names are cosmetic only and do not affect integration behavior.
* Archived applications reject new access requests and modifications to their access levels with an `APPLICATION_NOT_ACTIVE` error. Unarchive before resuming activity.
* Archiving and deletion do not revoke previously provisioned access. Revocation must be handled in the IdP.
* Access level IdP group mappings require an active integration. If the integration is disconnected, mappings persist but provisioning actions will fail.
* **Group** provisioning is supported by Okta, Microsoft Entra ID, Google Workspace, JumpCloud, Cloudflare, and OneLogin. **Application** provisioning is supported by Okta only. Setting either method on an access level mapped to a provider that does not support it fails at provisioning time, not at configuration time.
* **OneLogin group mappings can hold only one grant per user.** A OneLogin user has a single group but many roles. A group-mapped grant for a user who already has a group fails with `USER_BELONGS_TO_DIFFERENT_PRIMARY_GROUP` and writes nothing to OneLogin, so the existing group is never displaced. Role-mapped access levels are additive and do not have this limit. Recommend roles when a user needs concurrent grants.
* Owners and approvers each accept any mix of users and user groups.
* The post provisioning message is sent only after successful provisioning (full or partial). It is not sent on rejection or failed provisioning.
* An access level's post provisioning message takes priority over the application's. When the access level has no message, the application's message is sent. When neither is set, Ravenna sends its default confirmation.
* Post provisioning messages can reference the request's ticket fields, stored in `postProvisioningMessage` as `{{jp:$.postProvisioning.input.ticket.<field>}}`, the same path form workflows use, for example `{{jp:$.postProvisioning.input.ticket.requester.firstName}}`. A reference can also be a link target, as in `[View ticket]({{jp:$.postProvisioning.input.ticket.link}})`. Ravenna resolves them only in the message it posts on the ticket after provisioning. The **Post provisioning message** workflow variable returns the message with its references unresolved.
* Access levels with `provisioningMethod: external` are written by an integration sync and can't be created with that method. Their name, description, provisioning method, and group mapping are provider-owned. An update to an external level sends only `accessPolicyId`. When access policies aren't enabled for the organization, the access level modal for an external level is read-only.
* Exports are capped at 10,000 applications per file.
* Application status is derived, not stored (`getApplicationConfigurationStatus` in `packages/types/src/validators/application.ts`). In order: `archivedAt` set, or IdP status `INACTIVE` or `DELETED`, is **Archived**. No access levels with `archivedAt: null` is **Needs Setup** (`needs_configuration`). Live access levels but no workspaces is **Configured**. Otherwise **Available**. Archived access levels never count, in the badge or in the Status filter.
* Saved Status filters that hold the retired `active` value still work. A scalar `active` resolves to Available or Configured, and inside `in` and `not_in` lists it expands to both.


## Related topics

- [Delete an application](/api/application/delete-an-application.md)
- [List applications](/api/application/list-applications.md)
- [Update an application](/api/application/update-an-application.md)
- [Bulk delete applications](/api/application/bulk-delete-applications.md)
- [Export applications to CSV](/api/application/export-applications-to-csv.md)


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