Security Settings
Status: Complete
The Security tab provides powerful content moderation tools: purge operations for permanent content deletion, message quarantine, and a file hash blocklist to prevent re-uploads of prohibited content.
Permission Required: Instance Admin or Instance Owner
Purge Tools
The Purge Tools section allows you to permanently hard-delete messages and files from the database and disk. This section is visually highlighted with a red border to indicate its destructive nature.
Warning: Purge operations are irreversible. Messages are hard-deleted from the database and files are removed from disk. This cannot be undone.
Purge Targets
Select the target type from the dropdown:
| Target Type | Description |
|---|---|
| Single Message | Delete one specific message by its UUID |
| All from User | Delete ALL messages and ALL uploaded files for a given user |
| All in Channel | Delete ALL messages and ALL files associated with a given channel |
How to Purge
- Select the Target Type from the dropdown.
- Enter the UUID of the target (message, user, or channel) in the ID field.
- Optionally check Block file hashes to automatically add the SHA-256 hashes of any associated files to the blocklist, preventing the same file content from being re-uploaded.
- Click Purge.
- A confirmation dialog will appear describing exactly what will be deleted. Confirm to proceed.
Purge Results
After a purge completes, a toast notification displays the results:
- Messages deleted -- Number of messages permanently removed
- Files deleted -- Number of files removed from disk
- Hashes blocked -- Number of file hashes added to the blocklist (if the option was checked)
Notes on Single Message Purge
When purging a single message, files are not automatically deleted. This is because message content is end-to-end encrypted and the server cannot determine which files a message references. Use the File Management tab to delete specific files separately.
Audit Logging
All purge operations are recorded in the Audit Log:
| Action | Metadata |
|---|---|
admin_purge_message |
message_id, channel_id, block_hashes |
admin_purge_user_messages |
target_user_id, messages_deleted, files_deleted, hashes_blocked |
admin_purge_channel |
channel_id, messages_deleted, files_deleted, hashes_blocked |
Quick Quarantine
The Quick Quarantine section provides a fast way to hide a message from view without deleting it. Quarantined messages are preserved in the database but are not visible to users. This is useful for preserving evidence while removing offensive content from view.
How to Quarantine a Message
- Enter the message UUID in the Message ID field.
- Click Quarantine to hide the message, or Unquarantine to restore a previously quarantined message.
Tip: For file quarantine, use the File Management tab instead.
Quarantine actions are recorded in the audit log as admin_quarantine_message and admin_unquarantine_message.
Blocked File Hashes
The Blocked File Hashes section maintains a list of SHA-256 file hashes that are rejected on upload. If any user attempts to upload a file whose checksum matches a blocked hash, the upload is denied.
Viewing Blocked Hashes
The hash list displays a table with:
| Column | Description |
|---|---|
| Hash | Truncated SHA-256 hash (click to copy the full 64-character hex string) |
| Reason | Optional reason for blocking (up to 500 characters) |
| Added | Date the hash was added |
| Actions | Remove button |
Adding a Hash Manually
- Enter the 64-character hex SHA-256 hash in the SHA256 Hash field.
- Optionally enter a Reason describing why the hash is blocked.
- Click Block.
The hash must be exactly 64 hexadecimal characters. If a hash is already blocked, the reason will be updated.
Automatic Hash Blocking
Hashes can also be blocked automatically during:
- File deletion -- When deleting a file from the Files tab, you can opt to block its hash.
- Purge operations -- When running a purge with the "Block file hashes" option checked, all associated file hashes are added to the blocklist.
Automatic blocks are labeled with the reason "auto-blocked via admin purge" or "blocked via admin file delete".
Removing a Hash
Click Remove next to any blocked hash to unblock it. A confirmation dialog is shown before removal. After unblocking, users can upload files matching that hash again.
Audit Logging
Hash operations are recorded in the audit log as admin_block_hash and admin_unblock_hash.
OIDC / Single Sign-On
Chatalot supports external authentication through any OpenID Connect provider (Authentik, Keycloak, Authelia, Zitadel, etc.). When OIDC is configured, users see a Log in with SSO button on the login page.
Enabling OIDC
Set the following environment variables (see Configuration for full details):
| Variable | Description |
|---|---|
OIDC_ISSUER_URL |
Provider discovery URL (must expose /.well-known/openid-configuration) |
OIDC_CLIENT_ID |
Client ID from your identity provider |
OIDC_CLIENT_SECRET |
Client secret from your identity provider |
OIDC_REDIRECT_URI |
Callback URL (e.g. https://chat.example.com/auth/oidc/callback) |
OIDC_DISABLE_PASSWORD_LOGIN |
Set to true to enforce SSO-only login (default: false) |
SSO is active when all three of OIDC_ISSUER_URL, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET are set.
User Accounts
- First-time SSO users get a local account created automatically from the provider's
emailandpreferred_usernameclaims. - OIDC users appear in the admin Users list like any other user. You can suspend, promote, or delete them normally.
- If
OIDC_DISABLE_PASSWORD_LOGIN=true, the email/password login form is hidden and all users must authenticate through the identity provider. - Invite-only mode still applies: first-time SSO users need a valid invite code unless their account was pre-created by an admin.
Security Considerations
- OIDC login is subject to the same rate limiting and account lockout rules as password login.
- The OIDC client secret should be treated with the same care as any other credential. Store it in
.envor Docker secrets, never in version control. - Disabling password login (
OIDC_DISABLE_PASSWORD_LOGIN=true) is recommended for instances where all users are managed through a central identity provider.
Instance-Wide Security Features
Beyond the Security tab, Chatalot enforces several security measures at the infrastructure level:
Rate Limiting
All API requests are rate-limited using a token-bucket algorithm per IP address:
| Scope | Rate | Burst |
|---|---|---|
| General API | 20 requests/second | 50 burst |
| Auth endpoints (login/register) | 5 requests/second | 10 burst |
When the rate limit is exceeded, the server returns HTTP 429 with the message "too many requests, please slow down."
Account Lockout
After 10 consecutive failed login attempts, the account is locked for 15 minutes. The lockout is tracked in-memory per username and resets on server restart.
Security Headers
The server automatically applies the following HTTP security headers to all responses:
| Header | Value |
|---|---|
X-Content-Type-Options |
nosniff |
X-Frame-Options |
DENY |
X-XSS-Protection |
1; mode=block |
Strict-Transport-Security |
max-age=31536000; includeSubDomains |
Referrer-Policy |
strict-origin-when-cross-origin |
Permissions-Policy |
camera=(self), microphone=(self), geolocation=() |
Content-Security-Policy |
Restrictive policy allowing self-origin scripts, WebSocket connections, and specific media sources |
Password Policy
All passwords (set during registration, password change, or admin reset) must meet these requirements:
- 8 to 128 characters
- At least one uppercase letter (A-Z)
- At least one lowercase letter (a-z)
- At least one digit (0-9)
- At least one special character
Passwords are hashed using Argon2id with the following parameters: 64 MB memory, 3 iterations, 4 parallelism, 32-byte output.
Session Management
- JWT access tokens are signed with Ed25519 (EdDSA algorithm) and have a short lifetime.
- Refresh tokens are 32-byte random values, stored as SHA-256 hashes in the database.
- Refresh token rotation: each refresh request invalidates the old token and issues a new one.
- Suspended users have all refresh tokens revoked immediately.
API Reference
| Endpoint | Method | Description |
|---|---|---|
/admin/purge/message/{id} |
POST | Purge a single message (optional block_hashes query param) |
/admin/purge/user/{id}/messages |
POST | Purge all messages and files from a user |
/admin/purge/channel/{id} |
POST | Purge all messages and files in a channel |
/admin/messages/{id}/quarantine |
POST | Quarantine a message |
/admin/messages/{id}/unquarantine |
POST | Unquarantine a message |
/admin/blocked-hashes |
GET | List blocked hashes with page, per_page query params |
/admin/blocked-hashes |
POST | Add a hash (body: { hash, reason }) |
/admin/blocked-hashes/{id} |
DELETE | Remove a hash from the blocklist |
Next Step
Continue to Announcements to learn about publishing server-wide announcements.