> For the complete documentation index, see [llms.txt](https://docs.siit.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.siit.io/data-management/app-access-policies.md).

# App access policies

Govern app access end to end: who can ask, what they must provide, who signs off, and how access lands in the target system. Available on the Pro plan

{% hint style="info" %}
App Access Policies are available on the Pro plan.
{% endhint %}

App Access Policies are how Siit governs access to your apps end to end: who can ask, what they have to provide, who signs off, and how the access actually lands in the target system. Every workspace and every app start with safe defaults so the feature works on day one, then earns its keep as you configure Roles per app.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2FJIOdPi9NCghEHUuF2XRV%2FApplications.png?alt=media&amp;token=7903a34d-a2d0-4e19-8d36-bbedb3fe6d65" alt=""><figcaption></figcaption></figure>

### Why App Access Policies matter

* **Central governance**: define an approval cycle once and reuse it across every app, instead of recreating the same `Manager + App owner` chain in 30 different workflows.
* **Right-sized requests**: ask for a business reason or an access duration only where it matters, and skip them everywhere else. Less friction for employees, cleaner audit for sensitive apps.
* **Multiple provisioning paths**: manual app owner action, automatic add-to-group on the connected IdP, direct add-to-app-instance, or a mixed two-step that combines a group call with a follow-up manual task.
* **Day-one defaults**: every workspace ships with an `App owner approval` policy and every app ships with a `Default role`, so any new app accepts access requests as soon as it lands in your inventory.
* **Built-in audit**: every App Access record carries its own state machine, visible at any time on the application activity feed, even after the parent Request closes. The feed reads as an event log of only the events that moved the status: request creation, every approval, manual and automatic provisioning, provisioning failures, cancellations, expirations, and planned deprovisioning.

### Common use cases

* **Self-service Figma access for the marketing team.** Twelve hires join over a month. The marketing-segmented Role on Figma adds each new starter to the `Marketing` group in Okta automatically as soon as Manager and App owner sign off. No IT touch.
* **Time-bounded contractor access.** A freelancer needs the CMS for 30 days. The Role asks for a duration, the App Access record gets a 30-day expiration, and Siit schedules the deprovisioning for the exact time it expires.
* **Sensitive-app approvals.** Salesforce admin access goes through Finance, Security, then App owner. One `Sensitive admin access` Approval Policy carries the chain, and every Admin Role on Salesforce, Workday, and your HR systems reuses it.
* **Partial-SCIM apps.** Your IdP can put a user in the right Notion group, but the editor seat assignment still needs a click in Notion. The mixed two-step provisioning runs the group call automatically and pings the app owner for the seat.
* **Multi-instance apps without confusion.** Zoom EU and Zoom US share a brand but live as separate instances. The Role for the EU team adds users to the EU instance and the Role for the US team adds users to the US instance. The requester never sees the routing.
* **Quarterly access reviews.** Access records expire on schedule and create deprovisioning tasks, so quarterly reviews start from a clean list instead of a sprawling "who has what" spreadsheet.
* **Bulk Role creation from an existing IdP.** Your Okta tenant already has 40 groups mapped to apps. **Set up app access** scans the whole tenant in the background, groups its suggestions per app, and creates every Role you keep in one action, no manual Role creation per group.
* **Frictionless default apps.** Everyone gets Slack and the internal wiki on day one. Their Default role is set to `Skip approval`, so Siit provisions access the moment the request comes in, no approval round for an app nobody would ever reject.

### How an access request flows

A request follows the same shape end to end whether it comes from Slack, Microsoft Teams, or the portal. The employee picks the app, the Role configuration takes over, and the access lands once approvers sign off.

* **Pick the app(s)**: the employee selects one or more applications inside any service form. One request can cover several apps in one go.
* **Pick a Role (or auto-route)**: if the app has Roles configured, the employee picks from the list. If only one Role applies, the request routes automatically. Apps without custom Roles use the Default role and ping the app owner manually.
* **Answer the Role's form questions, one step per app**: business reason and access duration only appear when the Role asks for them, and each selected application now gets its own step inside the same modal, in sequence. A step with a single available Role and no duration or business reason to collect is skipped automatically.
* **Sit through approval**: the Role's Approval Policy fires the cycle and routes the request to the right approvers in the right order, unless the Role is set to `Skip approval`. In that case Siit skips this step entirely and provisions the access right away.
* **Get provisioned**: once approvers sign off, Siit provisions the access. Manual app owner task, add-to-group on the connected IdP, add-to-app-instance, or the mixed two-step, depending on the Role.

> **Notes:**
>
> * When a Role is set to `Skip approval`, the App Access card doesn't show an approval cycle section, since none ran. The card only reflects what actually happened.
> * On the portal, this step-per-app flow now runs inline: after submitting the request, the employee stays in the same modal instead of receiving a second form afterward. Slack has behaved this way already; the portal now matches it.
> * When provisioning combines more than one action, for example a group add plus a manual task, Siit resolves the App Access on what is actually left to do. An action that finds the employee already holds the target access does not fail the record on its own: the App Access lands on `Provisioned` once every remaining action clears, or on `Waiting provisioning` while a manual action is still open.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2FSzrwgrqCYJxsVNqZGFNE%2FCleanShot%202026-05-29%20at%2011.09.07%402x.png?alt=media&amp;token=ef750fbf-7707-4070-9191-eed0a34d9cae" alt=""><figcaption></figcaption></figure>

#### When access expires

A Role that asks for a duration produces an App Access record carrying an expiration timestamp, and Siit schedules the deprovisioning against that exact timestamp. An access granted for ten days at 15:47 is scheduled for deprovisioning ten days later at 15:47, not at the start of that day.

What happens at that moment depends on the deprovisioning action configured on the Role.

* **Automatic deprovisioning** (remove from group, remove from app instance) runs without human input. These actions go through a queue rather than executing inline, so the effective revocation can land a few minutes after the scheduled time.
* **Manual deprovisioning** (app owner task) opens a task at the scheduled time. The access is revoked when the person in charge executes the task, so the gap between expiry and effect is however long that takes.
* **Mixed two-step** behaves as both: the automatic half fires on schedule, the manual half waits on its owner.

By default the deprovisioning action mirrors the provisioning action, so a Role that provisions by adding to a group deprovisions by removing from it. Roles provisioned by a manual app owner task deprovision manually too.

> **Note** - Siit does not re-run the Approval Policy before deprovisioning. Expiration is automatic and no one signs off on it.

#### Revoking access before it expires

You no longer have to wait for the expiration, or edit the record, to take an access back. Any admin who can open the request, or who can revoke access on the application, gets a **Deprovision now** action on a `Provisioned` App Access card, both in the request conversation and in the application's Activity feed.

* Open the **⋯** menu on the card and pick **Deprovision now**.
* A confirmation names the person and the app. Deprovisioning starts immediately, but it still runs the Role's configured deprovisioning action, so an access that revokes through a manual app owner task is only gone once that task is done. The action cannot be undone.
* The card moves to `Waiting deprovisioning` and the timeline records who started it, so a manual revocation reads the same way as a scheduled one in the audit trail.

This works on any provisioned access, whether or not the Role asked for a duration. An access with no planned expiry would otherwise have stayed until someone edited the record by hand.

### What you control as an admin

The configuration sits in two surfaces: workspace-level Approval Policies that define how requests get signed off, and per-app Roles that bind a policy to an audience, a form shape, and a provisioning action.

* **Approval Policies**: reusable approval cycles defined once in `Settings → Requests → Approval policies` and reused across many Roles. The default `App owner approval` policy ships ready to use; edit it once and every Default role inherits the change.
* **Skip approval**: a fourth option on the Role's approval step, alongside an Approval Policy, auto-accept, and auto-reject. Pick it for the apps everyone gets by default, where an approval round would only add a step, not a decision. Siit moves straight to provisioning: no approver is notified and no approval round opens.
* **Roles per app**: each app carries a `Roles` tab where you bind audience, Approval Policy, form questions, and provisioning action together. One app can carry as many Roles as the access pattern needs (`Editor`, `Admin`, `Read-only`, role-by-team, role-by-region).
  * When an IdP is connected, you can also create Roles in bulk from the groups it already holds. See [Suggesting Roles from your IdP](#suggesting-roles-from-your-idp) below.
* **Form questions on the Role**: business reason and duration toggle independently per Role. Duration accepts a free-form value or a fixed cap.
* **Provisioning per Role**: pick manual app owner action for full human control, add-to-group for hands-off IdP provisioning, add-to-app-instance when the integration exposes a direct action, or the mixed two-step when the IdP handles part of the access and a human handles the rest.
* **Team or inbox owners**: an app's Owner or Backup owner can be a team or an inbox. An approval that targets that owner goes to the group, and the first member's decision settles it for the group. **App owner** and **App owner backup** are separate targets. Manual app owner tasks are assigned to all of the group's members. See [Apps](/data-management/apps.md).
* **Permission scopes**: `Manage policies` controls workspace-level governance; `Define access rules` controls per-app Roles. Separate the two so App owners can build their own Roles without touching the policy library.

#### Suggesting Roles from your IdP

**Set up app access** turns the groups your identity provider already holds into Roles, instead of writing them one by one. It works with Okta, JumpCloud, and Microsoft Entra ID, and needs the `Define access rules` permission.

Start it from the **⋯** menu on the integration's card in **Settings → Workspace → Integrations**. Siit scans every application that integration covers, with no application picker to fill in first.

{% stepper %}
{% step %}

### Let the scan run

The scan runs in the background and counts the applications as it processes them. **Minimize** it and it becomes a small panel in the bottom-right corner that survives navigating elsewhere and reloading the page, so you can keep working while it finishes. **Cancel** stops it and drops what it had gathered, after a confirmation.

One scan runs at a time per workspace. Asking for another while one is live reopens the live one rather than starting a second.
{% endstep %}

{% step %}

### Review the suggestions, application by application

The panel reads **Recommendations ready** when the scan lands. Open **View results** for the table, grouped per application and ordered approved, then discovered, then restricted. Each group collapses, counts its suggested roles, carries the application's status, and has its own select-all.

Groups you already turned into a Role are left out, so the table only holds what is new. On any row, adjust the **Suggested role** name, audience, business reason, access length, and approval policy before you create it.
{% endstep %}

{% step %}

### Create the Roles

Keep the rows you want and create them in one action. Each becomes a Role on its application, ready to take access requests.

Rows flip to their result one by one as Siit works through them. **Cancel** stops the run, and the rows it never reached are marked **Cancelled**. Closing the modal partway leaves the run going: reopen the flow and those Roles are already there.
{% endstep %}
{% endstepper %}

Results stay available for seven days, and the page URL carries the scan, so reopening it from that link brings the table back within the window. After that, run the scan again.

Setting up a single application is unchanged: open its **Roles** tab, pick **Set up app access**, and the suggestions for that one application come back right away.

{% hint style="info" %}
If the scan stops before it finishes, the message tells you what to do: reconnect the integration when its connection expired, or start it again when it stalled.
{% endhint %}

#### Sequential approval rounds

An Approval Policy can chain more than one round of approval. Add as many rounds as the policy needs, for example manager first, then security, then finance, and Siit walks through them one at a time.

* **Order matters.** Round 2 only starts once every approver in Round 1 has signed off.
* **A rejection stops the chain.** If any round is rejected, every round still waiting behind it is cancelled automatically. No approver downstream ever sees a request that already failed upstream.
* **Provisioning waits for the last signature.** App Access provisioning fires only once every round in the policy is approved, so nothing gets granted partway through the chain.

Configure rounds from `Settings → Requests → Approval policies → [policy] → Add another round of approval`.

Use rounds when a single approval step is not enough for the risk level of an app. A policy for admin level access might need the App owner, then Security, then Finance, each involved only once the previous group has cleared it.

**Approvers as followers**

Each round can add its approvers as followers on the request once they sign off. Toggle **Add approvers as followers** under **Select approvers** in any round. Workflow approval steps already carry this option; an Approval Policy now behaves the same way, so approvers stay on the request regardless of which route created the approval.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2FtBzDhMFETvKH0QLuuMw7%2Fimage.png?alt=media&amp;token=64d711c5-e505-4a13-b220-b22685a9522f" alt=""><figcaption></figcaption></figure>

#### **Reviewing past approval rounds**

The App Access card shows the round currently in progress by default. Step back through any round that already closed with the arrows next to the round counter to see who approved and when, without leaving the card or opening the activity feed. Rounds that have not started yet stay out of the card until it is their turn.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2F0nn1vyRgp5iWK7K6T9x5%2FCleanShot%202026-08-19%20at%2009.42.21.gif?alt=media&amp;token=7c577fa6-b1d8-4141-adde-528f0a084b19" alt=""><figcaption></figcaption></figure>

### Where App Access lives

Each granted access becomes an App Access record with its own lifecycle, independent of the Request that produced it. The record outlives the Request and stays auditable in two places.

* **Application activity feed**: every event that changed an App Access status for that app, in chronological order, from request creation through approvals, provisioning, failures, cancellations, expirations, and deprovisioning — both the scheduled kind and a manual **Deprovision now**, which names the admin who started it. App Access records that predate this event log were backfilled, so older history reads the same way as new. The feed is the source of truth for who has access to what, and why.
* **App Access filter on the Request list**: surfaces every Request currently carrying at least one App Access record, helpful for triaging requests still in flight.
* **Independent lifecycle**: closing the parent Request after provisioning runs does not interrupt the App Access. Scheduled deprovisioning still fires when the expiration timestamp arrives.
* **Expired on close**: if the Request is closed while an App Access is still waiting on a manual provisioning task, Siit marks that App Access `Expired` instead of leaving it open. Provisioning it before closing the Request, or reopening the Request to finish the task, avoids the expiration.
* **One Request, many App Accesses**: an employee can ask for access to several apps in a single Request. Each app produces its own App Access record with its own state machine.
* **Active Users tab**: the app's live roster, reconciled in real time from every source IdP, App Access, and direct adds with each person's access origin shown, so admins can tell why someone has access before revoking it.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2FJygfCYELIDjSsSRkW76A%2FCleanShot%202026-07-29%20at%2017.03.22%402x.png?alt=media&amp;token=5badb861-7419-43ca-908a-6557f6d273d8" alt=""><figcaption></figcaption></figure>

### Transparent to your requesters

From the requester side, it's a normal access request. They pick the app, optionally a Role, answer the questions the Role asks (often none), and wait. The governance chain, the multi-instance routing, the provisioning method, the audit trail: all admin-side. The requester just gets the access.

If they already hold the access they asked for, they see a plain message naming the app and the Role, not a technical error about groups or the identity provider.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2Fn2bWIW2sO0QAwqp1kJcp%2Fimage.png?alt=media&amp;token=b08168a8-dd76-4e40-8a04-a4132638b1f8" alt=""><figcaption></figcaption></figure>

### Where App Access Policies fit

App Access Policies extend the inventory in [Apps](https://docs.siit.io/data-management/apps) with a governance and provisioning layer on top. Automatic provisioning rides on the IdP integration covered in [IAM](https://docs.siit.io/integrations/iam), with add-to-group calling the connected Identity Provider directly. The approval cycle inside every Approval Policy reuses the mechanics from [Branching and approvals](https://docs.siit.io/workflow/branching-and-approvals), and the per-Role permission scopes (`Manage policies`, `Define access rules`) extend the model in [Roles and permissions](https://docs.siit.io/workspace/roles-and-permissions).

### Canceling or following up on a pending approval

The manual actions you already use on standard approvals now extend to App Access approvals too.

* **Cancel app access approval**: mark a pending app access approval as expired. A confirmation step prevents accidental cancellations.
* **Send reminder**: nudge the pending approver with a one‑click reminder. Siit logs the reminder as an event on the request timeline.

Open any request with a pending app access approval and click the **⋯** menu next to the **Waiting approval** status to trigger either action.

<figure><img src="https://451675063-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz9xmM8V3atukfr2XaElR%2Fuploads%2Foc1MVNcA7HWjErfJQKmt%2Fimage.png?alt=media&amp;token=0156643c-67e8-4f4d-a1a6-3efff5588bfd" alt=""><figcaption></figcaption></figure>

> **Note** : Both actions are available to any admin who can access the request, and every cancellation or reminder is recorded so the audit trail stays complete even when a request needed a manual push.


---

# 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.siit.io/data-management/app-access-policies.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.
