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 Solana Validator.

Best Practices

By default, most ASN providers provision bare metal machines with the ubuntu user as the primary sudo user to manage the server.

Beyond ubuntu , our approach when it comes to security is that of lest privileges, where we define these identity and access management users and groups as follows:

RBAC (UBUNTU GROUPS)
DESCRIPTION
PERMISSION

📂 sysadmin

Sudo access

To pre-set the permissions needed for each of the different roles played by operators.

📂 validator_admins

Can do everything to the validator, including install/uninstall, but nothing to the server

????

📂 validator_operators

Cannot install/uninstall the validator, but can perform all other operators, like upgrade, restart, migrate, start, and stop.

????

UBUNTU 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.

🧍Operator User: >>> alice, bob, etc.

Each human operator has his/her dedicated Ubuntu user.

Access the server via SSH and run Ansible scripts from the Ansible Control.

Prerequisites

Since the user provisioning is done via an Ansible script, you must have:

  1. A running Ansible Control

  2. Access to the user ubuntu on the provisioned server. See how HERE.

Setup Users CSV

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 your local workstation in a short and accessible path, like ~/Desktop or ~/Setup. You'll be using this path as a parameter when running the script.

Executing the Playbook

Before running the playbook, ensure that your inventory file (target_one_host.yml) is updated with the IP address of the target server where you will install the users. Your inventory file should look like this:

all:
  hosts:
    new-metal-box:
      ansible_host: 192.168.1.100
      ansible_port: 22

Replace <target_ip_address> with your actual values. Once the inventory is updated, you can run the playbook using:

ansible-playbook -i solana_new_metal_box.yml playbooks/pb_setup_server_users.yml \
  -e "target_host_name=new-metal-box" \
  -e "user_list=~/Desktop/iam_setup.csv"

Confirmation Step

Upon running the playbook, you will see a confirmation asking you to verify the IP of the host you are about to change:

TASK [Show server IP and request confirmation] ******************************************************
[Show server IP and request confirmation]
IMPORTANT: You are about to run this playbook on the server with IP: 192.168.1.100

To continue, please type exactly this IP: 192.168.1.100

If you are not sure, press Ctrl+C to cancel.

Type IP here

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.

User Passwords

Only users who require sudo (elevated) privileges are provisioned with passwords. These passwords are securely generated and encrypted using the age tool with each user’s public key. Users with sudo access must decrypt their password locally using their private SSH key to perform privileged actions.

These users with elevated privileges will receive an email with their temp password and should use age tool like so:

  • On Ubuntu/Debian: apt install age

  • On macOS: brew install age

For all other users, no password is set. These users access the server exclusively via SSH key-based authentication, and cannot escalate privileges. This approach minimizes the attack surface while maintaining secure administrative access for authorized operators.

Password Generation - Pending below

The playbook will extract user information from the CSV file and generate a password for each user. These passwords will be encrypted using Ansible Vault and stored in a local directory on the operator's computer.

During the execution, you will be prompted to enter a password to encrypt the vault file. This password is crucial as it will be needed later to view all the generated user credentials.

Ansible prompt:

Please enter a password to encrypt the vault file ~/.encryptedpsw/users_2025-06-17.yml
IMPORTANT: Save this password! You will need it later to view all the generated user credentials.

After entering the password, you will be asked to confirm it:

New Vault password:
Confirm New Vault password:

Accessing Encrypted Passwords

After the passwords are encrypted and stored, the playbook will require access to this encrypted file to generate and encrypt individual password files for each user. These files will be sent to each user via email.

During the execution, you will be prompted to enter the password for the generated passwords vault file:

Please enter the password for the generated passwords vault file (/hayek-validator-kit/ansible/vault/group_vars/generated_pass.yml)
This password is needed to access the user passwords that were previously generated.

User Creation and Group Assignment

The playbook will use the CSV file to create users. It will assign users to the corresponding groups based on the group_a and group_b columns. If either of these columns is empty, the playbook will omit the group assignment for that user.

Public Key Configuration

Additionally, the playbook will extract the public keys for each user from the CSV file and configure them on the target server for each user.

Temporary Password

The generated password is temporary. Users must change their password immediately upon accessing the server. This can be enforced using the command:

chage -d 0 {{ user }}

Sending Encrypted Passwords via Email

To send the passwords via email, the playbook needs access to the encrypted file containing the SMTP configurations, email_vars.yml. The passwords are encrypted using the age tool with each user's public key, which must be included in the CSV.

Below is an example of the email sent to users:

Hello dave,

Your server access credentials have been encrypted with your SSH public key.
For decrypt the password, you need to have the private key of the user.

Server IP: 192.168.1.100
Username: dave

The encrypted password file is attached to this email.

To decrypt your password:
1. Install age if not already installed:
   - On Ubuntu/Debian: apt install age
   - On macOS: brew install age
2. Save the attachment and run:
   age -d -i ~/.ssh/private_key dave_password.age

Connection command:
ssh -p 2522 [email protected]

Please change your password upon first login.

Best regards,
System Administrator

Cleanup

The playbook includes cleanup tasks to ensure that temporary vault files are removed after use. This is done to prevent potential issues with leftover files. The following tasks are executed:

  • Delete temporal vault file if it exists: This task removes the temporary vault file specified by generated_pass_file to avoid any issues with leftover files.

  • Delete temporal vault file backup if it exists: This task removes any backup of the temporary vault file, ensuring that no sensitive information is left behind.

These tasks are delegated to the localhost to ensure they are executed on the control machine.

Disabling the Ubuntu User

The playbook includes tasks to disable the ubuntu user after the new users are created. This is a security measure to prevent unauthorized access. The following tasks are executed:

  • Disable ubuntu user: This task disables the ubuntu user by locking the password and changing the shell to /usr/sbin/nologin.

  • Block SSH login for ubuntu user: This task modifies the SSH configuration to deny login for the ubuntu user.

  • Restart SSH service: This task restarts the SSH service to apply the changes.

These tasks ensure that the ubuntu user is completely disabled, and you must use one of the newly created users to access the server.

Last updated

Was this helpful?