Skip to content

Users, Roles & Permissions

SnapOtter ships three built-in roles, 17 granular permissions, and support for custom roles with optional per-tool access control. This page covers the full authorization model, API key scoping, team management, and audit logging.

Users

Creating users

Admins can create users through the admin panel or the POST /api/auth/users endpoint. Each user has a username, role, team assignment, and an optional email address.

Default admin

On first startup SnapOtter creates a default admin account. The credentials come from environment variables:

VariableDefaultDescription
DEFAULT_USERNAMEadminUsername for the initial admin account
DEFAULT_PASSWORDadminPassword for the initial admin account

The default admin is required to change their password on first login.

Authentication providers

Users can authenticate through several methods:

  • Local -- username and password stored in the SnapOtter database
  • OIDC -- any OpenID Connect provider (see OIDC / SSO)
  • SAML -- SAML 2.0 identity providers (see SAML SSO)
  • SCIM -- automated provisioning from an identity provider (see SCIM Provisioning)

Disabling authentication

Set AUTH_ENABLED=false to disable authentication entirely. In this mode a synthetic anonymous user with the admin role is used for all requests. No login is required.

WARNING

Disabling authentication grants full admin access to anyone who can reach the instance. Only use this in trusted environments.

Built-in roles

SnapOtter includes three built-in roles. They cannot be modified or deleted.

Admin

All 17 permissions. Full control over the instance.

tools:use files:own files:all apikeys:own apikeys:all pipelines:own pipelines:all settings:read settings:write users:manage teams:manage features:manage system:health audit:read compliance:manage webhooks:manage security:manage

Editor

7 permissions. Can use all tools and manage all files and pipelines, but cannot access admin functions.

tools:use files:own files:all apikeys:own pipelines:own pipelines:all settings:read

User

5 permissions. Can use tools and manage their own resources.

tools:use files:own apikeys:own pipelines:own settings:read

Permissions reference

PermissionDescription
tools:useUse any processing tool
files:ownView and manage own files
files:allView and manage all users' files
apikeys:ownCreate and manage own API keys
apikeys:allView all users' API keys
pipelines:ownCreate and manage own pipelines
pipelines:allView and manage all users' pipelines
settings:readView instance settings
settings:writeModify instance settings
users:manageCreate, update, and delete user accounts
teams:manageCreate, update, and delete teams
features:manageInstall and manage AI feature bundles
system:healthAccess health and readiness endpoints
audit:readView the audit log and list roles
compliance:manageManage GDPR lifecycle and compliance features
webhooks:manageConfigure outbound webhooks
security:manageManage security settings (IP allowlist, SSO enforcement)

Custom roles

Admins with the users:manage permission can create custom roles through the admin panel or the roles API.

Creating a custom role

bash
curl -X POST http://localhost:13490/api/v1/roles \
  -H "Authorization: Bearer si_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "reviewer",
    "description": "Can use tools and view all files",
    "permissions": ["tools:use", "files:own", "files:all", "settings:read"]
  }'

Role names must be 2-30 characters, lowercase alphanumeric with hyphens and underscores.

Admin-reserved permissions

Three permissions are reserved for built-in roles and cannot be assigned to custom roles:

  • compliance:manage
  • webhooks:manage
  • security:manage

The roles API rejects any request that includes these permissions. Only the built-in admin role has access to them.

Tool-level permissions

Custom roles can optionally restrict which tools users may access. Two modes are available:

ModeBehaviorLicense requirement
categoryRestrict by modality (image, video, audio, document, file)None (free)
toolRestrict by individual tool IDRequires the per_tool_permissions enterprise feature

When tool mode is set but the enterprise feature is not available, SnapOtter degrades gracefully and allows access to all tools.

json
{
  "name": "image-only",
  "permissions": ["tools:use", "files:own"],
  "toolPermissions": {
    "mode": "category",
    "allowed": ["image"]
  }
}

Deleting a custom role

When a custom role is deleted, all users assigned to it are automatically reassigned to the user role.

Teams

Teams group users for storage and retention management. A Default team is created on first startup.

FieldTypeDescription
namestringUnique team name (1-50 characters)
storageQuotanumberPer-team storage limit in bytes (works without enterprise)
retentionHoursnumberAuto-delete outputs after this many hours (requires team_retention_overrides, enterprise)
legalHoldbooleanPrevent automatic deletion of team members' files (requires legal_hold, enterprise)

INFO

The Default team cannot be deleted. Teams that still have members cannot be deleted. Reassign members first.

API keys

Users can generate API keys for programmatic access. Each key uses the si_ prefix and is shown only once at creation time.

Scoped permissions

API keys can optionally carry a permissions array. When set, the effective permissions for a request are the intersection of the user's role permissions and the key's scoped permissions. This means an API key can never escalate beyond the user's own permissions.

bash
curl -X POST http://localhost:13490/api/v1/api-keys \
  -H "Authorization: Bearer si_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CI pipeline key",
    "permissions": ["tools:use", "files:own"],
    "expiresAt": "2027-01-01T00:00:00Z"
  }'

Expiration

Keys accept an optional expiresAt timestamp. Expired keys are rejected at authentication time.

Audit log

SnapOtter records security-relevant events in a structured audit log stored in the audit_log database table.

Viewing the audit log

GET /api/v1/audit-log?page=1&limit=50&action=LOGIN_FAILED&from=2026-01-01T00:00:00Z&to=2026-12-31T23:59:59Z

Requires the audit:read permission. Supports pagination (page, limit) and filters (action, ip, from, to).

Tool operation auditing

WARNING

TOOL_EXECUTED events are not logged by default. They are opt-in through either of two paths:

  1. Set the auditToolOperations admin setting to true.
  2. Hold an active license with the audit_export feature (available on both team and enterprise plans).

Without one of these, individual tool executions are not recorded in the audit log.

Exporting

GET /api/v1/enterprise/audit/export?format=csv&from=2026-01-01T00:00:00Z

Requires the audit:read permission and the audit_export enterprise feature (available on both team and enterprise plans). Supports CSV and JSON formats, filtered by action, actorId, targetType, targetId, from, and to.

Tamper-resistant signing

When enabled, each audit log entry is signed with an HMAC derived from DATA_ENCRYPTION_KEY. This requires:

  1. Setting DATA_ENCRYPTION_KEY in your environment.
  2. Enabling the tamperResistantAudit admin setting.
  3. An enterprise license with the tamper_resistant_audit feature.

Retention

Set AUDIT_RETENTION_DAYS to automatically purge old entries. The default is 0, which means entries are kept indefinitely.

Event reference

EventCategory
LOGIN_SUCCESS, LOGIN_FAILEDAuthentication
OIDC_LOGIN_SUCCESS, OIDC_LOGIN_FAILEDAuthentication
SAML_LOGIN_SUCCESS, SAML_LOGIN_FAILEDAuthentication
LOGOUTAuthentication
USER_CREATED, USER_UPDATED, USER_DELETEDUser management
PASSWORD_CHANGED, PASSWORD_RESETUser management
MFA_ENROLLED, MFA_DISABLED, MFA_VERIFIED, MFA_VERIFY_FAILEDMFA
MFA_CHALLENGE_ISSUED, MFA_RECOVERY_USED, MFA_RESETMFA
ROLE_CREATED, ROLE_UPDATED, ROLE_DELETEDRoles
API_KEY_CREATED, API_KEY_DELETEDAPI keys
SETTINGS_UPDATED, IP_ALLOWLIST_UPDATEDSettings
FILE_UPLOADED, FILE_DELETEDFiles
TOOL_EXECUTEDTools (opt-in)
SCIM_USER_PROVISIONED, SCIM_USER_UPDATED, SCIM_USER_DEPROVISIONEDSCIM
SCIM_GROUP_SYNCEDSCIM
LEGAL_HOLD_APPLIED, LEGAL_HOLD_RELEASEDCompliance
GDPR_EXPORT_INITIATED, GDPR_USER_PURGED, GDPR_TEAM_PURGEDCompliance
CONFIG_EXPORTED, CONFIG_IMPORTEDConfiguration

Session management

Sessions are cookie-based, controlled by SESSION_DURATION_HOURS (default: 168 hours / 7 days).

Role changes invalidate sessions

When an admin changes a user's role, all of that user's active sessions are deleted. The user must log in again to pick up their new permissions.

Safety guards

  • Last-admin protection: the last remaining admin cannot be demoted to a lower role. The API returns an error if you try.
  • Self-delete prevention: admins cannot delete their own account through the API.