User Access
How to create and manage access for users on a new server
Once your raw metal server is ready to host a Solana validator, the system administrator must provision access for the validator operators. This guide walks you through the process of running the Ansible script to provision users on a newly provisioned metal server.
Architecture
Our security strategy follows the principle of least privilege.
We define IAM users and roles in advance, which serve as the blueprint during setup. Each role maps directly to an Ubuntu group, ensuring every user operating on the host has only the minimal access required for their tasks.
🎭 Roles
These are the roles with their asserted purpose and description:
📂 sysadmin Purpose: Complete system administration
Sudo access. Break-glass access for critical system emergencies
📂 validator_operators Purpose: Validator admin, operations & process control
Complete validator management without OS access. Can do everything to the validator config either directly or via the Ansible Control, including install/uninstall, but nothing to the server or OS.
📂 validator_viewers Purpose: System observability & metrics
Observability without modification capability. This role is intended for users who need read-only access to the validator. Members can view service status, access logs, monitor, and inspect validator keys, but cannot perform any administrative or operational actions either directly or via the Ansible Control.
🚦 Permissions
These are the permissions that apply to each role along with some example commands that apply to each permission:
user_mgmt
Example commands:
sudo passwd forgetfuluser
sudo userdel baduser
sudo useradd gooduser
✅
❌
❌
pkg_mgmt
Example commands:
sudo apt update
sudo apt install htop
✅
✅
❌
pwd_selfsvc
Example commands:
sudo reset-my-password
✅
✅
❌
validator_mgmt
Example commands:
sudo systemctl restart sol
kill UID sol service
✅
✅
❌
validator_monitoring
Example commands:
systemctl status sol
journalctl -u sol.service -f
✅
✅
✅
👥 Users
Users belong to roles, except ubuntu and sol, which have special treatment as shown here:
⚙️ ubuntu
Provisioned by ASN with a server. Disabled after secure user setup.
To provision server users.
⚙️ sol
Primary validator service runner and owner of the validator files and data.
Runs the validator service. Restricted to everything else.
🧍Operator User: >>> alice, bob, etc.
Each human operator has his/her dedicated user.
Access the server via SSH, with no password. Can run some Ansible scripts from the Ansible Control depending on their role membership.
If a non-member user of a role, attempts to execute any of the commands within one of the permission, or attempts to run an Ansible Script with permissions they don't have, they will get an error that looks like this:
Each role operates under the principle of least privilege with deny-by-default access control. Users are granted only the specific permissions explicitly defined using dedicated config files for each role. You can see the details later on this guide on under the User Access section.
User Setup
Pre-Requisites
This page assumes you have access to a provisioned bare metal with the ubuntu user with sudo access as explained in the Choosing Your Metal page.
Since the user provisioning is done via an Ansible script, you must also have a running Ansible Control.
🎛️ Config File
The pb_setup_server_users.yml expects a CSV with users and groups meta that will be used for the identity and access management provisioning.
You can use the template below as a starting point and modify as needed. Once you are happy with the setup, put in this folder ~/new-metal-box/iam_setup.csv. You'll be using this path as a parameter when running the script.
❇️ Provisioning
Before running the user provisioning playbook, ensure that your inventory file (solana_new_metal_box.yml) is updated with the IP address of the target server where you will install the users. Your inventory file should look like this:
Replace <target_ip_address> with your actual values. Once the inventory is updated, you can run the playbook using:
Before running the playbook, establish an initial SSH connection (ssh ubuntu@<target_ip_address>) so the server fingerprint is registered on the ansible-control.
Extended Variables Explanation
-e "server_role=monitor": Prevents the creation of the sol service user, which is not needed on monitoring (or other role) servers and disables the creation of RBAC (Role-Based Access Control) templates for validator-operators and validator-viewers roles.
When server_role=validator is used, the playbook would:
Create the
solservice userCopy sudoers templates that configure permissions for:
validator-operatorsvalidator-viewers
Note: The playbook is configured to run with the user ubuntu which is the only user in the newly provisioned server.
Upon running the playbook, you will see a confirmation asking you to verify the IP of the host you are about to change:
This step is a safety measure to ensure you are provisioning the correct server. Type the IP address shown to continue. If you are not sure, press Ctrl+C to cancel the process.
❌ Ubuntu User
Before the playbook completes, a final security warning is issued to inform the operator that the default ubuntu user will be disabled. This is a deliberate security measure, as many cloud providers (ASN) preconfigure servers with the ubuntu user by default, which poses a risk if left active.
A notification is displayed with the following message:
Once confirmed, the ubuntu user is disabled, and the SSH session will be terminated.
🎟️ User Access
The playbook automatically configures the required sudo permissions for each role by deploying dedicated policy files under /etc/sudoers.d/. The system uses a hierarchical approach where higher roles inherit permissions from lower roles.
Role Hierarchy and Permissions
sysadmin
10-sysadmin
None (top level)
validator_operators
30-validator-operators
Inherits from viewers
validator_viewers
40-validator-viewers
Base level
Password Self Service
Users who belong to the sysadmin or validator_operators groups are required to set their own password in order to perform privilege escalation via sudo.
Initial Access
After the user logs in using their SSH private key, they will see a welcome message guiding them through the self-service password setup:
Run the following command once logged in:
Security Question Setup
After running the sudo reset-my-password command for the first time, users will be prompted to configure a personal security question and answer. This is a mandatory step in the password self-service process.
This security question and answer can be randomly generated using a password manager such as 1Password and securely stored in the same vault alongside your other credentials. It is important that the question is not something obvious or personal, as attackers may attempt to guess it using social engineering techniques. Treat your security question and answer with the same level of confidentiality as your password to ensure maximum protection.
The security question and answer are encrypted using AES-256 with a high number of iterations and a unique salt, ensuring robust protection against brute-force or dictionary attacks. This encrypted data is stored in the path /etc/password-security/alan, with strict file permissions accessible only by root.
If a user wishes to reset their password using the self-service script (sudo reset-my-password), they will be prompted to correctly answer their security question.
The user has a maximum of 3 attempts. After three failed answers, the script will deny further access for 24 hours, displaying the following message:
To regain access before the lockout period ends, a user from the sysadmin group must either:
Manually reset the password using
sudo passwd alan, orRemove the lock file at
/etc/password-security/password-reset-blocked-alanto re-enable the self-service flow.
Password Self-Service Logging
To ensure full traceability and auditability, all user interactions with the reset-my-password script are logged in the file /var/log/password-reset.log. This includes events such as security question setup, password resets, and encryption actions.
Each log entry includes a timestamp, session ID, username, event type, and source IP address. This enables administrators to monitor and audit all password self-service activity in a secure and structured format.
All log files are owned by root and are protected from unauthorized access. This logging system ensures compliance with internal audit policies and helps detect misuse or suspicious activity in password operations.
Discovering Your Sudo Permissions
To help users understand what commands they are allowed to run, a message is displayed at login as part of the system's welcome screen:
Each user is provided with a permissions.txt file in their home directory. This file is:
Automatically generated by Ansible during provisioning
Updated based on the user’s assigned role and sudoers configuration
Last updated
Was this helpful?