Skip to content

AMSDAL Auth Plugin

AMSDAL Auth Plugin provides authentication, authorization, and user management for your AMSDAL REST API.

To enable this plugin, add amsdal.contrib.auth.app.AuthAppConfig to the AMSDAL_CONTRIBS environment variable (enabled by default).

For detailed permission configuration, see Auth & Permissions.

Models

User

Stores user credentials and permission references.

Field Type Description
email str User email
password bytes Password hash
permissions list[Permission] \| None References to Permission records

The User model also supports MFA — see Multi-Factor Authentication below.

Permission

Defines access control rules. When a Permission record exists in the database, users must have that permission assigned to perform the corresponding action.

Field Type Default Description
resource_type str 'models' Resource type (models, transactions)
model str Resource name, or * for all
action str Action name (create, read, update, delete, execute), or * for all

Each record produces a scope string: {resource_type}.{model}:{action}.

LoginSession

Handles user authentication. Create a LoginSession with email and password to authenticate — if credentials are valid, a JWT token is returned.

Field Type Description
email str User email
password str User password
token str \| None JWT token (returned on successful login)
mfa_code str \| None MFA verification code (required if user has an active MFA device)

Use the returned token in the Authorization header for all API requests.

MFA Models

Model Description
MFADevice Base MFA device with fields: user_email, device_type, name, is_active, confirmed
SMSDevice SMS-based MFA device extending MFADevice, adds phone_number

Permissions

The permission system supports two modes, controlled by AMSDAL_REQUIRE_DEFAULT_AUTHORIZATION:

Mode Setting Behavior
Public API False Everything is open by default. Selectively protect resources.
Protected API True (default) Everything requires authentication. Selectively open resources.

Decorators

Use decorators to set permissions on models and transactions:

from amsdal.contrib.auth.decorators import permissions, allow_any, require_auth
from amsdal.contrib.auth.permissions import RequireAuth, RequirePermissions

# Require authentication
@require_auth
class SecretModel(Model):
    data: str

# Make public
@allow_any
class PublicModel(Model):
    data: str

# Per-action permissions
@permissions(
    read=AllowAny,
    create=RequireAuth,
    delete=RequirePermissions('models.Post:delete'),
)
class Post(Model):
    title: str

# Permissions on transactions
@require_auth
@transaction()
def change_password(old_password: str, new_password: str) -> Response:
    ...

Note

Auth decorators must be placed above @transaction().

For full details on permission composition (& / |), object-level permissions, API managers, and role examples, see Auth & Permissions.


Multi-Factor Authentication

When a user has an active MFA device, login requires a two-step process:

  1. Create a LoginSession with email and password — the server returns an MFARequiredError
  2. Re-submit with the mfa_code from the user's device
{
    "email": "user@example.com",
    "password": "secret",
    "mfa_code": "123456"
}

Event Listeners

The auth plugin registers the following event listeners:

Event Listener Description
ServerStartupEvent CheckAndCreateSuperUserListener Creates admin user on startup if not exists
AuthenticateEvent AuthenticateUserListener Decodes JWT token and resolves user
ClassAuthorizeEvent ClassAuthorizeListener Checks class-level permissions
ObjectAuthorizeEvent ObjectAuthorizeListener Checks object-level permissions

Environment Variables

Variable Description
AMSDAL_ADMIN_USER_EMAIL Email of admin user created on startup
AMSDAL_ADMIN_USER_PASSWORD Password of admin user created on startup
AMSDAL_AUTH_JWT_KEY Key for signing JWT tokens
AMSDAL_REQUIRE_DEFAULT_AUTHORIZATION Require permissions by default (true by default)

Usage Example

Create permissions via JSON fixtures:

{
    "Permission": [
        {
            "external_id": "user_create",
            "resource_type": "models",
            "model": "User",
            "action": "create"
        },
        {
            "external_id": "user_update",
            "resource_type": "models",
            "model": "User",
            "action": "update"
        },
        {
            "external_id": "user_delete",
            "resource_type": "models",
            "model": "User",
            "action": "delete"
        }
    ]
}

After adding these fixtures, users without the corresponding permissions will not be able to create, update, or delete users, but will still be able to read them (unless read permission is also defined).