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

# Admin Overrides

> Deliberate, reason-required, fully-audited admin elevation for private apps — lifecycle, SDK signals, and audit events.

Org admins have baseline read access to every app in their organization (see [Roles](/app-builder/reference/roles)), but writes on apps where they have no explicit membership require an **Admin Override** session: a deliberate, reason-required, fully-audited elevation.

This page documents what developers integrating with HASP can observe about override behavior via the SDK and audit log.

## When overrides apply

An override is required when all three conditions are true:

1. The user is an org admin or owner
2. The app's access mode is `private` or `invite_only`
3. The user has no explicit per-user or group editor/admin grant on the app

In that scenario, `sdk.getBootstrap().role` returns `'org_admin_viewer'` (read-only) until the admin explicitly opens an override session.

## Override lifecycle

1. **Open** — Admin clicks "Enable Admin Edit Mode" in the app header, types a reason (minimum 10 characters), submits. Server creates an `admin_override_session` row, sets a session cookie, and emits `org_admin.override_enabled` to the audit log.
2. **Refresh on every write** — Each write request the admin makes under override refreshes the session's `last_activity_at`, extending the inactivity window. Every such write also emits `org_admin.override_action` with the route and HTTP method.
3. **End** — One of:
   * Admin clicks "Exit Admin Edit Mode" → `exited_at = now()`, audit `org_admin.override_exited` with `exit_reason = manual`
   * 60 minutes of inactivity → `exited_at = now()`, audit with `exit_reason = inactivity`
   * Admin logs out → `exited_at = now()`, audit with `exit_reason = session_ended`

## Audit events

The override lifecycle produces the following entries in your organization's audit log (available to admins at `/settings/audit-log`):

| Action                       | When emitted                      | Key metadata                      |
| ---------------------------- | --------------------------------- | --------------------------------- |
| `org_admin.override_enabled` | Override session opened           | `reason`, `inactivity_expires_at` |
| `org_admin.override_action`  | Each write request under override | `route`, `method`                 |
| `org_admin.override_exited`  | Override session ended            | `exit_reason`, `duration_seconds` |

Related meta-audit events that may appear alongside override activity:

| Action                        | When emitted                                                                         | Key metadata                                            |
| ----------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------- |
| `org_admin.app_viewed`        | Org admin loads an app's management page via baseline visibility (no explicit grant) | `role_at_view`, `access_mode`                           |
| `org_admin.orphan_inherited`  | An app transitions to "orphaned" state (last live editor/admin removed)              | `access_mode`, `detected_via`                           |
| `org_admin.orphan_reassigned` | Org admin reassigns an orphaned app to a new admin                                   | `target_user_id`, `reassigned_by`, `was_orphaned_since` |

All seven event types write to the same chain-verified audit log used for domain events. Customers on the Compliance add-on see cryptographic hash chaining across the full event stream.

## Observing override state from your app

HASP apps running inside the runtime iframe do not receive override session details — the override is a platform-level mechanism, not an app-level context. If your app needs to know whether the current user is acting under override authority, compare `sdk.getBootstrap().role`:

* `'org_admin_viewer'` → admin is viewing via baseline; no override active; writes will fail
* `'editor'` or `'admin'` on an app where the user has no explicit grant → override is active (platform has elevated their role server-side)

The SDK intentionally does not expose an "override active" boolean — the role string is the authoritative signal.

## What's NOT audited

Reads by org admins with naturally-granted access (explicit editor/admin grant) are NOT audited under the `org_admin.*` namespace. Those are regular member activities. Only the "admin-acting-via-baseline-visibility" path produces meta-audit entries.
