Bolt CMS (versions 4 and 5) stores users in a database (SQLite by default, MySQL/PostgreSQL supported) and manages them through the admin backend at /bolt/ or via the command-line bin/console tool. Bolt uses Symfony's security component under the hood, with roles defined in YAML configuration.
Adding Users via the Admin Backend
Creating a New User
- Log in to the Bolt admin at
https://your-site.com/bolt/ - Navigate to Configuration > Users & Permissions (or Users in the main menu)
- Click Add a new user
- Fill in the required fields:
- Username (alphanumeric, used for login)
- Display Name (shown on authored content)
- Email (must be unique)
- Password (minimum 6 characters)
- Roles: Select one or more roles
- Set the Enabled toggle to active
- Click Save
Built-in Roles
Bolt ships with these default roles (configurable in config/bolt/permissions.yaml):
| Role | Access Level |
|---|---|
ROLE_ADMIN |
Full access: all content types, users, configuration, extensions |
ROLE_CHIEF_EDITOR |
Manage all content types, publish, and manage other editors' content |
ROLE_EDITOR |
Create and edit content, manage media, cannot change settings |
ROLE_USER |
Basic authenticated access, typically for frontend members |
Adding Users via the Console
The Bolt CLI is the fastest way to create users, especially in CI/CD pipelines or automated deployments:
# Create a new admin user
bin/console bolt:add-user \
--username=jsmith \
--display-name="John Smith" \
--email=jsmith@example.com \
--password="SecurePass123!" \
--roles=ROLE_EDITOR
# Create a user interactively (prompts for each field)
bin/console bolt:add-user
# List all existing users
bin/console bolt:list-users
# Reset a user's password
bin/console bolt:reset-password jsmith
Bolt 5 User Commands
Bolt 5 refined the CLI commands:
# Bolt 5 syntax
php bin/console bolt:setup-user \
--username=jsmith \
--displayname="John Smith" \
--email=jsmith@example.com \
--password="SecurePass123!" \
--role=ROLE_EDITOR
# Enable/disable a user from CLI
php bin/console bolt:user:enable jsmith
php bin/console bolt:user:disable jsmith
Configuring Custom Roles
Edit config/bolt/permissions.yaml to define granular roles with content-type-level permissions:
# config/bolt/permissions.yaml
roles:
ROLE_BLOG_EDITOR:
description: "Can manage blog posts only"
label: Blog Editor
ROLE_PAGE_EDITOR:
description: "Can manage pages only"
label: Page Editor
ROLE_MEDIA_MANAGER:
description: "Can manage uploaded files"
label: Media Manager
# Content-type permissions
contenttype-permissions:
blogposts:
edit: [ROLE_BLOG_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
create: [ROLE_BLOG_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
delete: [ROLE_CHIEF_EDITOR, ROLE_ADMIN]
publish: [ROLE_CHIEF_EDITOR, ROLE_ADMIN]
pages:
edit: [ROLE_PAGE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
create: [ROLE_PAGE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
delete: [ROLE_ADMIN]
publish: [ROLE_CHIEF_EDITOR, ROLE_ADMIN]
# Global permissions
global-permissions:
dashboard: [ROLE_USER, ROLE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN]
settings: [ROLE_ADMIN]
users: [ROLE_ADMIN]
extensions: [ROLE_ADMIN]
files:upload: [ROLE_EDITOR, ROLE_CHIEF_EDITOR, ROLE_ADMIN, ROLE_MEDIA_MANAGER]
Removing and Disabling Users
Disabling a User (Recommended)
- Go to Configuration > Users & Permissions
- Click the user you want to disable
- Toggle the Enabled switch to off
- Click Save
Disabled users cannot log in but their account, content attribution, and history are preserved.
Deleting a User
- Go to Configuration > Users & Permissions
- Click the user
- Click Delete (at the bottom of the edit form)
- Confirm the deletion
What Happens to Their Content
When you delete a Bolt CMS user:
- Published content remains live but the author field shows as empty or "Unknown"
- Bolt stores the
author_idas a foreign key -- if the user record is deleted, the relationship breaks - Draft and held content is preserved but appears unowned
- Media files uploaded by the user remain in the
public/files/directory - Version history entries referencing the user show a null author
To avoid orphaned content, disable users instead of deleting them.
CLI Removal
# Disable a user via console
php bin/console bolt:user:disable jsmith
# There is no built-in delete command -- use SQL directly
# For SQLite (default Bolt database):
sqlite3 var/data/bolt.db "DELETE FROM bolt_user WHERE username = 'jsmith';"
# For MySQL:
mysql -u bolt_user -p bolt_db -e "DELETE FROM bolt_user WHERE username = 'jsmith';"
Bulk User Management
Database-Level Bulk Operations
# Export all users to CSV (SQLite example)
sqlite3 -header -csv var/data/bolt.db \
"SELECT username, display_name, email, roles, enabled FROM bolt_user;" \
> users_export.csv
# Bulk disable all users except admins
sqlite3 var/data/bolt.db \
"UPDATE bolt_user SET enabled = 0 WHERE roles NOT LIKE '%ROLE_ADMIN%';"
# Bulk import using a PHP script with Doctrine
php bin/console bolt:run-script bulk-import.php
Bulk Import Script
<?php
// bulk-import.php -- Run with: php bin/console bolt:run-script bulk-import.php
use Bolt\Entity\User;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
$hasher = $this->getContainer()->get(UserPasswordHasherInterface::class);
$csv = array_map('str_getcsv', file('users.csv'));
array_shift($csv); // Remove header row
foreach ($csv as $row) {
[$username, $displayName, $email, $password, $role] = $row;
$user = new User();
$user->setUsername($username);
$user->setDisplayName($displayName);
$user->setEmail($email);
$user->setRoles([$role]);
$user->setEnabled(true);
$user->setPassword($hasher->hashPassword($user, $password));
$em->persist($user);
echo "Created: $username\n";
}
$em->flush();
echo "Import complete.\n";
SSO and LDAP Integration
Bolt CMS uses Symfony's security system, so LDAP and SSO can be configured through Symfony bundles.
LDAP Authentication
# config/packages/security.yaml
security:
providers:
ldap_provider:
ldap:
service: Symfony\Component\Ldap\Ldap
base_dn: dc=example,dc=com
search_dn: cn=admin,dc=example,dc=com
search_password: '%env(LDAP_SEARCH_PASSWORD)%'
default_roles: ROLE_EDITOR
uid_key: uid
firewalls:
main:
provider: ldap_provider
form_login_ldap:
service: Symfony\Component\Ldap\Ldap
dn_string: 'uid={username},ou=people,dc=example,dc=com'
# config/services.yaml
services:
Symfony\Component\Ldap\Ldap:
arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
arguments:
- host: ldap.example.com
port: 389
options:
protocol_version: 3
referrals: false
Offboarding Checklist
- Disable the account -- Do not delete to preserve content attribution
- Reassign owned content -- Update the
author_idon critical content records - Revoke any API tokens -- Check
config/bolt/for per-user API credentials - Change shared secrets -- If the user had access to
APP_SECRETin.env, rotate it - Review file uploads -- Audit
public/files/for sensitive uploads by the departing user - Clear sessions -- Delete the user's session files from
var/sessions/ - Update LDAP/SSO -- If using external auth, disable the account there as well