Skip to main content

Install

Supports Python 3.9+.

Hello, world

The canonical execution-boundary surface. protect() mints and verifies a Permit end-to-end and returns it on success. There is no permitted=False return path — if protect() returns, the action is authorized.
See Runtime flow for the full lifecycle and the fail-closed matrix.

with_permit() — lexically-scoped form

When the action body is a single scope, bind it to the permit’s lifetime directly. Same wire contract as protect(); same audit-chain entry. The body runs only on a verified permit.
protect() returns the Permit to the caller; with_permit() binds it to the body. Pick the form that fits the call site — both produce identical wire calls, identical audit-chain entries, and identical fail-closed semantics.

require_permit() — descriptor form

For dangerous operations described by a richer ProtectedAction (resource_id, environment). Async-only:

Error model

protect() and with_permit() collapse policy denial, hold, escalate, and verification failure into AtlaSentDeniedError. Inspect exc.decision ("deny" / "hold" / "escalate") if you need to branch.

Inspecting the four-value decision

protect() and with_permit() raise on anything other than allow. If you need to inspect hold / escalate at the call site — for example, to route to an approval queue — drop down to the raw evaluate() primitive:
evaluate() does not verify the permit for you. Callers using the raw primitive must verify before executing — see Verify a permit explicitly.

Async

SCIM provisioning

Manage SCIM 2.0 user and group provisioning via the ScimClient sub-client.
schemas is injected automatically if absent. See SCIM 2.0 provisioning guide for IdP configuration.

Token management

Multi-IdP token refresh via the atlasent.auth module. Use this in programmatic integrations that maintain long-lived access tokens.

Evidence bundles

Create and download compliance evidence bundles.