Adding & Removing Users on Contao | OpsBlu Docs

Adding & Removing Users on Contao

Adding & Removing Users on Contao — setup, configuration, and best practices for Contao.

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

  1. Log in to the Contao backend at https://your-site.com/contao
  2. Navigate to System > Users in the left sidebar
  3. Click the New user icon (green plus)
  4. Fill in the Account settings:
    • Username (used for login)
    • Full name
    • Email address
    • Password (and confirmation)
  5. Under User groups, assign the user to one or more groups
  6. Set Account status to Active
  7. Optionally set Account expires for temporary access
  8. 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:

  1. Navigate to Members in the left sidebar
  2. Click the New member icon
  3. Fill in Personal data (name, email, address, etc.)
  4. Under Account settings:
    • Set a Username and Password
    • Assign to Member groups (for access control)
    • Set Account status to Active
  5. 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

  1. Go to System > Users
  2. Click the Edit icon next to the user
  3. Set Disable account to checked (or set an Account expires date in the past)
  4. Click Save

Deactivated users cannot log in. Their content and attribution are preserved.

Deleting a Backend User

  1. Go to System > Users
  2. Click the Delete icon (red X) next to the user
  3. 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 author field (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:

  1. Go to System > Security (or the user's profile)
  2. Enable Two-factor authentication
  3. 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

  1. Deactivate the backend user -- Set disable = 1 to preserve content attribution
  2. Reassign content -- Update author fields on articles, news, and events
  3. Remove group memberships -- Clear all group assignments before deactivation
  4. Check pagemounts and filemounts -- Verify no user-specific mounts expose sensitive directories
  5. Revoke frontend member access -- If the user also had a frontend account, deactivate it
  6. Review the system log -- Check System > System Log for recent actions by the user
  7. Update LDAP -- If using LDAP, disable the directory account to prevent re-authentication
  8. Clear sessions -- Remove the user's session from var/sessions/