Contao is a PHP-based CMS that stores users in a MySQL/MariaDB database. It separates backend users (administrators and editors who access /contao) from frontend members (registered site visitors). Both are managed through the Contao backend or the Contao Manager CLI.
Adding Backend Users
Creating a User via the Backend
- Log in to the Contao backend at
https://your-site.com/contao - Navigate to System > Users in the left sidebar
- Click the New user icon (green plus)
- Fill in the Account settings:
- Username (used for login)
- Full name
- Email address
- Password (and confirmation)
- Under User groups, assign the user to one or more groups
- Set Account status to Active
- Optionally set Account expires for temporary access
- Click Save
Backend User Groups
User groups define permissions. Manage them at System > User groups:
System > User groups > [New group]
Key permission areas:
├── Allowed modules (which backend sections are visible)
├── Allowed content elements (which element types can be used)
├── Allowed page types (regular, redirect, forward, root)
├── Allowed filemounts (which directories the user can access)
├── Allowed pagemounts (which page tree branches are editable)
├── Allowed image sizes
├── Allowed form fields
└── Excluded fields (hide specific fields from editing forms)
Example group configurations:
| Group | Modules | Pagemounts | Filemounts |
|---|---|---|---|
| Editors | Article, News, Events | /site-content/ | /files/media/ |
| Designers | Themes, Layout | All | /files/themes/ |
| Admins | All | All | All |
Adding Users via Contao Console
Contao 4.x uses the Symfony console. Contao 5 provides dedicated user management commands:
# Contao 4.x -- Create user via console
php vendor/bin/contao-console contao:user:create
# Interactive prompts:
# Username: jsmith
# Name: John Smith
# Email: jsmith@example.com
# Password: ********
# Admin? [yes/no]: no
# Groups: [1] Editors
# Contao 5 -- More detailed user management
php vendor/bin/contao-console contao:user:create \
--username=jsmith \
--name="John Smith" \
--email=jsmith@example.com \
--password="SecurePass123!" \
--group=2
# List all backend users
php vendor/bin/contao-console contao:user:list
# Change a user's password
php vendor/bin/contao-console contao:user:password jsmith
Creating an Admin User (Recovery)
If you are locked out, use the install tool or console:
# Create a new admin user via the install tool
# Navigate to: https://your-site.com/contao/install
# Enter the install tool password (from parameters.yml or .env)
# Use "Create Admin User" form
# Or via console
php vendor/bin/contao-console contao:user:create --admin
Adding Frontend Members
Frontend members are separate from backend users. Manage them at Members in the backend:
- Navigate to Members in the left sidebar
- Click the New member icon
- Fill in Personal data (name, email, address, etc.)
- Under Account settings:
- Set a Username and Password
- Assign to Member groups (for access control)
- Set Account status to Active
- Click Save
# Bulk import members from CSV via console (Contao 5)
php vendor/bin/contao-console contao:member:import members.csv
# CSV format: firstname,lastname,email,username,password,groups
Removing and Deactivating Users
Deactivating a Backend User
- Go to System > Users
- Click the Edit icon next to the user
- Set Disable account to checked (or set an Account expires date in the past)
- Click Save
Deactivated users cannot log in. Their content and attribution are preserved.
Deleting a Backend User
- Go to System > Users
- Click the Delete icon (red X) next to the user
- Confirm the deletion
What Happens to Their Content
When you delete a Contao backend user:
- Published articles and pages remain intact -- content is not removed
- Content records retain the original
authorfield (user ID), but name resolution shows "Unknown" - News articles keep the author attribution until manually changed
- Event entries are preserved with the original author
- The system log retains entries from the deleted user
- File uploads remain in the filesystem under
/files/
Console-Based Removal
# Disable a user
php vendor/bin/contao-console contao:user:disable jsmith
# Delete a user (Contao 5)
php vendor/bin/contao-console contao:user:delete jsmith
# Direct database approach (Contao 4)
mysql -u contao_user -p contao_db -e \
"UPDATE tl_user SET disable = 1 WHERE username = 'jsmith';"
Reassigning Content
-- Reassign all articles from one user to another
UPDATE tl_article
SET author = (SELECT id FROM tl_user WHERE username = 'neweditor')
WHERE author = (SELECT id FROM tl_user WHERE username = 'jsmith');
-- Reassign news items
UPDATE tl_news
SET author = (SELECT id FROM tl_user WHERE username = 'neweditor')
WHERE author = (SELECT id FROM tl_user WHERE username = 'jsmith');
-- Reassign calendar events
UPDATE tl_calendar_events
SET author = (SELECT id FROM tl_user WHERE username = 'neweditor')
WHERE author = (SELECT id FROM tl_user WHERE username = 'jsmith');
Bulk User Management
Export Users
-- Export all backend users
SELECT id, username, name, email, admin,
IF(disable, 'disabled', 'active') as status,
FROM_UNIXTIME(lastLogin) as last_login
FROM tl_user
ORDER BY username;
Bulk Import via PHP
<?php
// contao/bulk-import.php -- Run with: php vendor/bin/contao-console contao:run bulk-import.php
use Contao\UserModel;
use Contao\System;
$csv = array_map('str_getcsv', file('import_users.csv'));
$header = array_shift($csv);
foreach ($csv as $row) {
$data = array_combine($header, $row);
$existing = UserModel::findByUsername($data['username']);
if ($existing) {
echo "SKIP: {$data['username']}\n";
continue;
}
$user = new UserModel();
$user->username = $data['username'];
$user->name = $data['name'];
$user->email = $data['email'];
$user->password = password_hash($data['password'], PASSWORD_DEFAULT);
$user->admin = ($data['role'] === 'admin') ? 1 : 0;
$user->groups = serialize([$data['group_id']]);
$user->disable = 0;
$user->tstamp = time();
$user->dateAdded = time();
$user->save();
echo "ADDED: {$data['username']}\n";
}
LDAP Integration
Contao supports LDAP authentication via the contao-ldap-bundle:
# Install the LDAP bundle
composer require contao/ldap-bundle
# config/config.yml
contao_ldap:
server:
host: ldap.example.com
port: 389
encryption: tls
bind:
dn: "cn=admin,dc=example,dc=com"
password: "%env(LDAP_BIND_PASSWORD)%"
search:
base_dn: "ou=people,dc=example,dc=com"
filter: "(uid={username})"
mapping:
username: uid
name: cn
email: mail
groups:
base_dn: "ou=groups,dc=example,dc=com"
filter: "(member={dn})"
mapping:
contao_editors: "cn=cms-editors"
contao_admins: "cn=cms-admins"
When LDAP is enabled, users authenticate against the directory. A local Contao user record is created on first login with group membership mapped from LDAP groups.
Two-Factor Authentication
Contao 4.6+ supports 2FA natively:
- Go to System > Security (or the user's profile)
- Enable Two-factor authentication
- Each user sets up their own TOTP authenticator
To enforce 2FA for all backend users:
# config/config.yml
contao:
security:
two_factor:
enforce: true
Offboarding Checklist
- Deactivate the backend user -- Set
disable = 1to preserve content attribution - Reassign content -- Update author fields on articles, news, and events
- Remove group memberships -- Clear all group assignments before deactivation
- Check pagemounts and filemounts -- Verify no user-specific mounts expose sensitive directories
- Revoke frontend member access -- If the user also had a frontend account, deactivate it
- Review the system log -- Check
System > System Logfor recent actions by the user - Update LDAP -- If using LDAP, disable the directory account to prevent re-authentication
- Clear sessions -- Remove the user's session from
var/sessions/