BeyondTrust PAM – Secure SSH Access and File Transfers with Password Safe

BeyondTrust PAM – Secure SSH Access and File Transfers with Password Safe

Introduction


BeyondTrust PAM Password Safe is an enterprise solution for Privileged Access Management (PAM) that provides centralized control and accountability over all privileged accounts, secrets, and SSH keys across an organization’s infrastructure. It automates the discovery, management, and rotation of these credentials, while also enabling Just-in-Time access, real-time session monitoring and recording, and comprehensive auditing to meet compliance and security requirements.

Using BeyondTrust Password Safe provides significant security, compliance, and operational benefits for organizations that manage access from Macs to Linux or Windows servers. By centralizing privileged credentials in a secure vault, Password Safe eliminates the risks of shared or static passwords and automates credential rotation to reduce exposure. It enables just-in-time access and enforces least-privilege principles, ensuring users receive only the permissions they need for a limited time. BeyondTrust also delivers comprehensive audit logging, session monitoring, and recording, giving IT teams full visibility and control over privileged activity across platforms.

One of the challenges in moving to BeyondTrust Password Safe is the change in how users perform file transfers, such as using SCP to copy files or directories between local systems and remote servers. Since Password Safe manages and brokers privileged sessions through controlled access workflows, direct SSH-based connections that rely on locally stored credentials or keys are often restricted or replaced with session proxying. This means users who previously used simple SCP commands with static credentials or SSH keys may now need to go through the Password Safe interface, use temporary credential checkouts, or leverage approved session initiation methods to maintain compliance. While this enhances security and auditing by ensuring all privileged access is tracked and authorized, it can initially disrupt familiar workflows for administrators and developers who frequently transfer files, requiring adjustments in tools, automation scripts, and connection processes.

Using SSH Client with Password Safe Request and Approval System


A user can securely access remote systems using an SSH client integrated with the Password Safe Request and Approval system. This system enhances security by managing credentials and controlling access requests efficiently.

Request Information Auto-Population

When submitting a request, the system automatically populates the requester’s information, including:

  • Reason for Access
  • Request Duration

These fields are filled with default settings configured within Password Safe, streamlining the process for users.

Direct Connect to Managed Accounts/Applications

To access a managed account or application using Direct Connect, the requester must connect through Password Safe’s SSH Proxy. This requires a custom SSH connection string in one of the following formats:

For UPN (User Principal Name) Credentials

<Requester>+<Username@Domain>+<System Name>@<Password Safe>

For Down-Level Logon Names/Non-Domain Credentials

<Requester>@<Domain\Username>@<System Name>@<Password Safe>

SCP Connection String Formats

When transferring files securely using SCP (Secure Copy Protocol), the connection string format varies based on credential type:

For UPN Credentials for a Local File

scp -P [port] [local-file] <Requester>@<Domain\Username>@<System Name>@<Password Safe>:[remote-path]

For UPN Credentials for a Local Directory

scp -P [port] [local-directory] <Requester>@<Domain\Username>@<System Name>@<Password Safe>:[remote-path]

Notes:

  • Port 4422 is the default port for BeyondTrust Password Safe SSH proxy connections used in most environments. However, it is not a strict requirement and can be modified as needed.
  • Ensure you replace placeholders ([port], [local-file], [SERVER_NAME], etc.) with actual values.

Example – For UPN Credential for Local File

scp -P 4422 "/path/to/local/file" ad.domain.org\[ACCOUNT_NAME]+pam-admin+[SERVER_NAME]@vault.id.domain.org:/path/to/remote/director

Example – For UPN Credential for Local Directory

scp -P 4422 "/path/to/local/directory" ad.domain.org\[ACCOUNT_NAME]+pam-admin+[SERVER_NAME]@vault.id.domain.org:/path/to/remote/directory

Authentication Steps:

  1. Enter Your Account Password: This authenticates your identity within the system.
  2. Verify 2FA Prompt: Complete the 2FA authentication to finalize the secure connection.

By following these guidelines, users can securely manage remote SSH connections and file transfers using the Password Safe system.

Password Safe SCP Transfer Bash Script


This is a secure file transfer script that uses Password Safe authentication with BeyondTrust EMP. This interactive tool simplifies SCP transfers by handling the complex authentication string formatting and providing user-friendly prompts. This generic version uses placeholder domains that should be customized for your organization.

Features

  • Bidirectional transfers: Upload to or download from remote servers
  • File and directory support: Transfer individual files or entire directories
  • Interactive prompts: Guided input with validation and command history
  • Flexible PAM configuration: Supports traditional pam-, AD domain, non-AD-bound, or custom account formats
  • Secure authentication: Uses BeyondTrust EMP Password Safe integration
  • Error handling: Validates paths and provides clear feedback
  • Transfer confirmation: Shows summary before executing
  • Debug output: Displays the actual SCP command for troubleshooting

Configuration Required

Before using this script, edit lines 23-25 to configure for your environment:

readonly VAULT_HOST="vault.example.org" # Your Password Safe vault hostname 
readonly VAULT_PORT="4422" # Your vault port (usually 4422)
readonly DOMAIN="ad.example.org" # Your Active Directory domain

PAM Account Options

The script supports four account format configurations:

  1. Traditional formatpam-<username> – Standard PAM account naming
  2. AD domain formatAD.EXAMPLE.ORG\<dept_prefix>-<account_id> – Active Directory integrated
  3. Non-AD-boundpam-admin – For servers not joined to AD
  4. Custom format: Manually enter any account format required by your Password Safe configuration

Check your Password Safe page to see which format is listed under “Account” for your target server.

Usage

Simply run the script and follow the interactive prompts:

./password_safe_scp_generic.sh

The script will guide you through:

  1. Selecting your PAM account format
  2. Choosing transfer direction (upload or download)
  3. Entering source and destination paths
  4. Providing your account name and server details
  5. Confirming the transfer before execution


Example Workflow


Upload Example:

  1. Select PAM account format → Traditional (pam-<username>)
  2. Transfer direction → Upload
  3. Local path → /Users/john/report.pdf
  4. Account name → john.doe
  5. Server name → fileserver01
  6. Remote path → /home/john/documents/
  7. Confirm → Yes

Download Example:

  1. Select PAM account format → AD domain format
  2. Transfer direction → Download
  3. Account name → john.doe
  4. Server name → fileserver01
  5. Remote path → /var/logs/app.log
  6. Local path → /Users/john/Downloads/
  7. Confirm → Yes


Sample Sessions


Sample Session – Upload

Password Safe SCP Transfer Tool with BeyondTrust EMP
====================================================

=== Password Safe SCP Configuration ===

=== PAM Account Configuration ===
1. Traditional format (pam-<username>)
2. AD domain format (AD.EXAMPLE.ORG\<dept_prefix>-<account_id>)
3. Non-AD-bound server (pam-admin)
4. Custom format (enter manually)

NOTE: Check your Password Safe page to see what 'Account' is listed
      for your server to determine the correct option.

Select account format (1, 2, 3, or 4): 3
Selected: Non-AD-bound server
Using PAM account: pam-admin

=== Transfer Direction ===
1. Upload (Local -> Server)
2. Download (Server -> Local)

Select transfer direction (1 or 2): 1
Selected: Upload (Local to Server)

=== Upload Configuration ===
Enter path to local file or directory: /Users/john/documents/report.pdf
Enter your account name: john.doe
Enter server name: webserver01.example.org
Enter remote destination path: /home/john/uploads/

Detected: File upload

=== Transfer Summary ===
PAM Account: pam-admin
Direction: upload
Local path: /Users/john/documents/report.pdf
Remote destination: /home/john/uploads/
Account name: john.doe
Server: webserver01.example.org
Transfer type: file

Do you want to proceed with the transfer? (y/N): y
Starting file upload to server...
DEBUG: Executing upload command:
scp -P 4422 "/Users/john/documents/report.pdf" ad.example.org\\john.doe+pam-admin+webserver01.example.org@vault.example.org:/home/john/uploads/
report.pdf                                    100%  256KB   1.2MB/s   00:00
✓ File upload completed successfully!

Sample Session – Download

Password Safe SCP Transfer Tool with BeyondTrust EMP
====================================================

=== Password Safe SCP Configuration ===

=== PAM Account Configuration ===
1. Traditional format (pam-<username>)
2. AD domain format (AD.EXAMPLE.ORG\<dept_prefix>-<account_id>)
3. Non-AD-bound server (pam-admin)
4. Custom format (enter manually)

NOTE: Check your Password Safe page to see what 'Account' is listed
      for your server to determine the correct option.

Select account format (1, 2, 3, or 4): 1
Selected: Traditional pam- format
Enter your username (will be formatted as pam-<username>): john.doe
Using PAM account: pam-john.doe

=== Transfer Direction ===
1. Upload (Local -> Server)
2. Download (Server -> Local)

Select transfer direction (1 or 2): 2
Selected: Download (Server to Local)

=== Download Configuration ===
Enter your account name: john.doe
Enter server name: dataserver02.example.org
Enter remote file or directory path: /var/log/application/
Enter local destination path: /Users/john/Downloads/logs/

Is this a directory download? (y/N): y
Set as: Directory download

=== Transfer Summary ===
PAM Account: pam-john.doe
Direction: download
Remote path: /var/log/application/
Local destination: /Users/john/Downloads/logs/
Account name: john.doe
Server: dataserver02.example.org
Transfer type: directory

Do you want to proceed with the transfer? (y/N): y
Starting directory download from server...
DEBUG: Executing download command:
scp -r -P 4422 ad.example.org\\john.doe+pam-john.doe+dataserver02.example.org@vault.example.org:/var/log/application/ "/Users/john/Downloads/logs/"
Downloading: app.log, error.log, access.log...
✓ Directory download completed successfully!

Sample Session – AD Domain Format

Password Safe SCP Transfer Tool with BeyondTrust EMP
====================================================

=== Password Safe SCP Configuration ===

=== PAM Account Configuration ===
1. Traditional format (pam-<username>)
2. AD domain format (AD.EXAMPLE.ORG\<dept_prefix>-<account_id>)
3. Non-AD-bound server (pam-admin)
4. Custom format (enter manually)

NOTE: Check your Password Safe page to see what 'Account' is listed
      for your server to determine the correct option.

Select account format (1, 2, 3, or 4): 2
Selected: AD domain format
Enter your department prefix: IT
Enter your account ID: 12345
Using PAM account: AD.EXAMPLE.ORG\IT-12345

=== Transfer Direction ===
1. Upload (Local -> Server)
2. Download (Server -> Local)

Select transfer direction (1 or 2): 1
Selected: Upload (Local to Server)

=== Upload Configuration ===
Enter path to local file or directory: /Users/john/backup/
Enter your account name: john.doe
Enter server name: backupserver.example.org
Enter remote destination path: /backups/weekly/

Detected: Directory upload

=== Transfer Summary ===
PAM Account: AD.EXAMPLE.ORG\IT-12345
Direction: upload
Local path: /Users/john/backup/
Remote destination: /backups/weekly/
Account name: john.doe
Server: backupserver.example.org
Transfer type: directory

Do you want to proceed with the transfer? (y/N): y
Starting directory upload to server...
DEBUG: Executing upload command:
scp -r -P 4422 "/Users/john/backup/" ad.example.org\\john.doe+AD.EXAMPLE.ORG\IT-12345+backupserver.example.org@vault.example.org:/backups/weekly/
Uploading: file1.dat, file2.dat, config.xml...
✓ Directory upload completed successfully!

Password Safe SCP Bash Script


See the Password Safe SCP Transfer Bash script below for more details:

#!/usr/bin/env bash
#
# Revised - 2025.10.03
#
# This script provides secure file transfer using Password Safe authentication with BeyondTrust EMP.
# This is a generic version with placeholder domains that should be customized for your organization.
#
# It supports both upload and download operations with interactive prompts for user input.
# You must configure the VAULT_HOST, VAULT_PORT, and DOMAIN variables for your environment.
#
# Features:
#
# - Bidirectional file transfer (upload/download)
# - Flexible PAM account configuration (traditional pam-, AD domain, or custom formats)
# - Enhanced readline support with command history and editing capabilities
# - File and directory transfer support
# - Input validation and user confirmation
# - Debug output for troubleshooting
#

set -euo pipefail

# Configuration Defaults - EDIT THESE FOR YOUR ENVIRONMENT
readonly VAULT_HOST="vault.example.org"
readonly VAULT_PORT="4422"
readonly DOMAIN="ad.example.org"

# Global variables for user inputs
local_path=""
remote_path=""
account_name=""
server_name=""
transfer_type=""
transfer_direction=""
pam_account=""

# Function to prompt for user input with validation
prompt_input()
{
    local prompt="$1"
    local var_name="$2"
    local allow_empty="${3:-false}"
    local input
    
    while true; do
        read -rep "$prompt: " input
        
        if [[ -n "$input" ]] || [[ "$allow_empty" == "true" ]]; then
            eval "$var_name='$input'"
            break
        else
            echo "Error: This field cannot be empty. Please try again."
        fi
    done
}

# Function to validate file/directory exists (for uploads) or remote path format (for downloads)
validate_path()
{
    local path="$1"
    local direction="$2"
    
    if [[ "$direction" == "upload" ]]; then
        if [[ ! -e "$path" ]]; then
            echo "Error: Local path '$path' does not exist."
            return 1
        fi
    else
        # For downloads, just check that remote path is not empty and looks reasonable
        if [[ -z "$path" || ! "$path" =~ ^/ ]]; then
            echo "Error: Remote path should start with '/' (e.g., /home/user/file.txt)"
            return 1
        fi
    fi
    return 0
}

# Function to get PAM account configuration
get_pam_account()
{
    local username dept_prefix account_id
    
    echo "=== PAM Account Configuration ==="
    echo "1. Traditional format (pam-<username>)"
    echo "2. AD domain format (AD.EXAMPLE.ORG\\<dept_prefix>-<account_id>)"
    echo "3. Non-AD-bound server (pam-admin)"
    echo "4. Custom format (enter manually)"
    echo
    echo "NOTE: Check your Password Safe page to see what 'Account' is listed"
    echo "      for your server to determine the correct option."
    echo
    
    while true; do
        read -rep "Select account format (1, 2, 3, or 4): " choice
        case "$choice" in
            1)
                echo "Selected: Traditional pam- format"
                prompt_input "Enter your username (will be formatted as pam-<username>)" username
                pam_account="pam-$username"
                echo "Using PAM account: $pam_account"
                break
                ;;
            2)
                echo "Selected: AD domain format"
                prompt_input "Enter your department prefix" dept_prefix
                prompt_input "Enter your account ID" account_id
                pam_account="${DOMAIN^^}\\${dept_prefix}-${account_id}"
                echo "Using PAM account: $pam_account"
                break
                ;;
            3)
                pam_account="pam-admin"
                echo "Selected: Non-AD-bound server"
                echo "Using PAM account: pam-admin"
                break
                ;;
            4)
                echo "Selected: Custom format"
                prompt_input "Enter your complete PAM account name" pam_account
                echo "Using PAM account: $pam_account"
                break
                ;;
            *)
                echo "Error: Please enter 1, 2, 3, or 4."
                ;;
        esac
    done
    echo
}

# Function to get transfer direction
get_transfer_direction()
{
    echo "=== Transfer Direction ==="
    echo "1. Upload (Local -> Server)"
    echo "2. Download (Server -> Local)"
    echo
    
    while true; do
        read -rep "Select transfer direction (1 or 2): " choice
        case "$choice" in
            1)
                transfer_direction="upload"
                echo "Selected: Upload (Local to Server)"
                break
                ;;
            2)
                transfer_direction="download"
                echo "Selected: Download (Server to Local)"
                break
                ;;
            *)
                echo "Error: Please enter 1 for Upload or 2 for Download."
                ;;
        esac
    done
    echo
}

# Function to get user inputs
get_user_inputs()
{
    echo "=== Password Safe SCP Configuration ==="
    echo
    
    # Get PAM account configuration first
    get_pam_account
    
    # Get transfer direction
    get_transfer_direction
    
    if [[ "$transfer_direction" == "upload" ]]; then
        # Upload: Local -> Server
        echo "=== Upload Configuration ==="
        
        # Get local path
        while true; do
            prompt_input "Enter path to local file or directory" local_path
            if validate_path "$local_path" "upload"; then
                break
            fi
        done
        
        # Get account name
        prompt_input "Enter your account name" account_name
        
        # Get server name
        prompt_input "Enter server name" server_name
        
        # Get remote directory path
        prompt_input "Enter remote destination path" remote_path
        
        # Determine if it's a directory or file
        if [[ -d "$local_path" ]]; then
            transfer_type="directory"
            echo
            echo "Detected: Directory upload"
        else
            transfer_type="file"
            echo
            echo "Detected: File upload"
        fi
        
    else
        # Download: Server -> Local
        echo "=== Download Configuration ==="
        
        # Get account name
        prompt_input "Enter your account name" account_name
        
        # Get server name
        prompt_input "Enter server name" server_name
        
        # Get remote file/directory path
        while true; do
            prompt_input "Enter remote file or directory path" remote_path
            if validate_path "$remote_path" "download"; then
                break
            fi
        done
        
        # Get local destination path
        prompt_input "Enter local destination path" local_path
        
        # Ask user about transfer type for downloads
        echo
        read -rep "Is this a directory download? (y/N): " dir_response
        case "$dir_response" in
            [yY]|[yY][eE][sS])
                transfer_type="directory"
                echo "Set as: Directory download"
                ;;
            *)
                transfer_type="file"
                echo "Set as: File download"
                ;;
        esac
    fi
    
    # Show summary
    echo
    echo "=== Transfer Summary ==="
    echo "PAM Account: $pam_account"
    echo "Direction: $transfer_direction"
    if [[ "$transfer_direction" == "upload" ]]; then
        echo "Local path: $local_path"
        echo "Remote destination: $remote_path"
    else
        echo "Remote path: $remote_path"
        echo "Local destination: $local_path"
    fi
    echo "Account name: $account_name"
    echo "Server: $server_name"
    echo "Transfer type: $transfer_type"
    echo
}

# Function for single file Password Safe SCP (Upload)
psscp_file_upload()
{
    local account_name="$1"
    local server_name="$2"
    local source_file="$3"
    local destination="$4"
    local connection_string
    
    # All accounts use the UPN format: <Domain>\<Requester>+<Account>+<System>@<Vault>
    connection_string="${DOMAIN}\\${account_name}+${pam_account}+${server_name}@${VAULT_HOST}"
    
    echo "Starting file upload to server..."
    echo "DEBUG: Executing upload command:"
    echo "scp -P $VAULT_PORT \"$source_file\" ${connection_string}:${destination}"
    echo
    scp -P "$VAULT_PORT" "$source_file" "${connection_string}:${destination}"
}

# Function for single file Password Safe SCP (Download)
psscp_file_download()
{
    local account_name="$1"
    local server_name="$2"
    local source_file="$3"
    local destination="$4"
    local connection_string
    
    # All accounts use the UPN format: <Domain>\<Requester>+<Account>+<System>@<Vault>
    connection_string="${DOMAIN}\\${account_name}+${pam_account}+${server_name}@${VAULT_HOST}"
    
    echo "Starting file download from server..."
    echo "DEBUG: Executing download command:"
    echo "scp -P $VAULT_PORT ${connection_string}:${source_file} \"$destination\""
    echo
    scp -P "$VAULT_PORT" "${connection_string}:${source_file}" "$destination"
}

# Function for recursive Password Safe SCP (Upload)
psscp_dir_upload()
{
    local account_name="$1"
    local server_name="$2"
    local source_dir="$3"
    local destination="$4"
    local connection_string
    
    # All accounts use the UPN format: <Domain>\<Requester>+<Account>+<System>@<Vault>
    connection_string="${DOMAIN}\\${account_name}+${pam_account}+${server_name}@${VAULT_HOST}"
    
    echo "Starting directory upload to server..."
    echo "DEBUG: Executing upload command:"
    echo "scp -r -P $VAULT_PORT \"$source_dir\" ${connection_string}:${destination}"
    echo
    scp -r -P "$VAULT_PORT" "$source_dir" "${connection_string}:${destination}"
}

# Function for recursive Password Safe SCP (Download)
psscp_dir_download()
{
    local account_name="$1"
    local server_name="$2"
    local source_dir="$3"
    local destination="$4"
    local connection_string
    
    # All accounts use the UPN format: <Domain>\<Requester>+<Account>+<System>@<Vault>
    connection_string="${DOMAIN}\\${account_name}+${pam_account}+${server_name}@${VAULT_HOST}"
    
    echo "Starting directory download from server..."
    echo "DEBUG: Executing download command:"
    echo "scp -r -P $VAULT_PORT ${connection_string}:${source_dir} \"$destination\""
    echo
    scp -r -P "$VAULT_PORT" "${connection_string}:${source_dir}" "$destination"
}

# Function to confirm transfer
confirm_transfer()
{
    local response
    read -rep "Do you want to proceed with the transfer? (y/N): " response
    
    case "$response" in
        [yY]|[yY][eE][sS])
            return 0
            ;;
        *)
            echo "Transfer cancelled."
            return 1
            ;;
    esac
}

# Main execution function
main()
{
    echo "Password Safe SCP Transfer Tool with BeyondTrust EMP"
    echo "===================================================="
    echo
    
    # Get all required inputs
    get_user_inputs
    
    # Confirm before proceeding
    if ! confirm_transfer; then
        exit 0
    fi
    
    # Perform the transfer based on direction and type
    echo "DEBUG: transfer_direction='$transfer_direction', transfer_type='$transfer_type'"
    
    if [[ "$transfer_direction" == "upload" ]]; then
        case "$transfer_type" in
            "file")
                if psscp_file_upload "$account_name" "$server_name" "$local_path" "$remote_path"; then
                    echo "✓ File upload completed successfully!"
                else
                    echo "✗ File upload failed!"
                    exit 1
                fi
                ;;
            "directory")
                if psscp_dir_upload "$account_name" "$server_name" "$local_path" "$remote_path"; then
                    echo "✓ Directory upload completed successfully!"
                else
                    echo "✗ Directory upload failed!"
                    exit 1
                fi
                ;;
            *)
                echo "Error: Unknown transfer type '$transfer_type'"
                exit 1
                ;;
        esac
    else
        # Download operations
        case "$transfer_type" in
            "file")
                if psscp_file_download "$account_name" "$server_name" "$remote_path" "$local_path"; then
                    echo "✓ File download completed successfully!"
                else
                    echo "✗ File download failed!"
                    exit 1
                fi
                ;;
            "directory")
                if psscp_dir_download "$account_name" "$server_name" "$remote_path" "$local_path"; then
                    echo "✓ Directory download completed successfully!"
                else
                    echo "✗ Directory download failed!"
                    exit 1
                fi
                ;;
            *)
                echo "Error: Unknown transfer type '$transfer_type'"
                exit 1
                ;;
        esac
    fi
}

# Script entry point
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi

 

No Comments

Leave a Reply