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:

ROLES (GROUPS)
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:

PERMISSION
sysadmin
validator_operators
validator_viewers

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:

USERS
DESCRIPTION
USAGE

⚙️ 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.

225B
Open

❇️ 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:

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 sol service user

  • Copy sudoers templates that configure permissions for:

    • validator-operators

    • validator-viewers

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:

🎟️ 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

ROLE
FILE
INHERITANCE

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.

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, or

  • Remove the lock file at /etc/password-security/password-reset-blocked-alan to 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?