Skip to content

SSH Key Manager Module

Section: Modules | Article 34
Audience: System Administrators
Last Updated: 2026-04-07


Overview

The SSH Key Manager module allows RP-PAM to manage just-in-time SSH access to Linux and Unix servers. When a user is granted access, RP-PAM generates a temporary SSH key pair, installs the public key on the target host, and provides the private key to the user. When the grant expires or is revoked, the public key is automatically removed.

This eliminates the need for shared SSH keys, standing access, or manually managing authorized_keys files.


How It Works

Step What Happens
1. Request User requests SSH access to a resource via the portal or API
2. Approval Approval workflow completes (if required)
3. Grant RP-PAM generates a new key pair using the configured algorithm
4. Install The public key is appended to ~/.ssh/authorized_keys on the target host
5. Deliver The private key is returned to the user (encrypted, one-time download)
6. Expire/Revoke When the grant ends, the public key line is removed from the target host

Prerequisites

Before enabling the SSH module:

  1. Service account access — RP-PAM needs an SSH-capable service account on each target host with permission to modify authorized_keys for the target users.
  2. Network connectivity — The RP-PAM server must reach target hosts on the configured SSH port (default 22).
  3. Host key fingerprints — For security, you should pre-register host key fingerprints or enable TOFU (Trust On First Use) in the module configuration.

Module Configuration

The SSH module is configured through the modules.ssh section of rppam.config or via the REST API.

Configuration JSON

{
  "moduleType": "ssh",
  "displayName": "SSH Key Manager",
  "enabled": true,
  "config": {
    "sshHost": "linux-server-01.corp.local",
    "sshPort": 22,
    "adminUser": "rppam-svc",
    "adminKeyPath": "/etc/rppam/keys/service-key",
    "keyAlgorithm": "ed25519",
    "keyBits": 4096,
    "grantTtlMinutes": 480,
    "authorizedKeysPath": ".ssh/authorized_keys",
    "hostKeyFingerprint": "SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "trustOnFirstUse": false
  }
}

Configuration Fields

Field Type Required Default Description
sshHost string Yes Hostname or IP of the target SSH server
sshPort integer No 22 SSH port on the target server
adminUser string Yes Username RP-PAM uses to connect and manage keys
adminKeyPath string Yes Path to the private key file for the admin user
keyAlgorithm string No ed25519 Algorithm for generated keys: ed25519, rsa, ecdsa
keyBits integer No 4096 Key size in bits (only applies to rsa and ecdsa)
grantTtlMinutes integer No 480 Default grant duration in minutes (8 hours)
authorizedKeysPath string No .ssh/authorized_keys Relative path from user home to authorized_keys
hostKeyFingerprint string No Expected host key fingerprint for verification
trustOnFirstUse boolean No false Accept and store the host key on first connection

Enabling the Module

Via REST API — PowerShell

$body = @{
    moduleType  = "ssh"
    displayName = "SSH - Linux Servers"
    enabled     = $true
    config      = @{
        sshHost      = "linux-server-01.corp.local"
        sshPort      = 22
        adminUser    = "rppam-svc"
        adminKeyPath = "/etc/rppam/keys/service-key"
        keyAlgorithm = "ed25519"
    }
} | ConvertTo-Json -Depth 3

Invoke-RestMethod -Uri "https://rppam.corp.local:7101/api/v1/modules" `
    -Method POST `
    -Headers @{ Authorization = "Bearer $adminJwt" } `
    -ContentType "application/json" `
    -Body $body

Via REST API — curl

curl -s -X POST "https://rppam.corp.local:7101/api/v1/modules" \
  -H "Authorization: Bearer $ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "moduleType": "ssh",
    "displayName": "SSH - Linux Servers",
    "enabled": true,
    "config": {
      "sshHost": "linux-server-01.corp.local",
      "sshPort": 22,
      "adminUser": "rppam-svc",
      "adminKeyPath": "/etc/rppam/keys/service-key",
      "keyAlgorithm": "ed25519"
    }
  }' | jq .

Verify the Module Is Active

PowerShell:

Invoke-RestMethod -Uri "https://rppam.corp.local:7101/api/v1/modules" `
    -Headers @{ Authorization = "Bearer $adminJwt" }

curl:

curl -s "https://rppam.corp.local:7101/api/v1/modules" \
  -H "Authorization: Bearer $ADMIN_JWT" | jq '.[] | select(.moduleType == "ssh")'

Look for "status": "healthy" in the response. If the status is "error", check that the admin user can connect to the target host.


How Grants Work

Grant (Access Approved)

When a user receives an approved SSH grant:

  1. RP-PAM generates a new key pair using the configured algorithm (e.g., Ed25519).
  2. The public key is appended to ~/.ssh/authorized_keys on the target host, tagged with a comment:
    ssh-ed25519 AAAAC3Nza... rppam-grant:abc123-exp:2026-04-07T20:00:00Z
    
  3. The private key is encrypted with the user's session key and returned.
  4. The grant is recorded in the audit log.

The user receives: - The private key (one-time download, shown in portal or returned via API) - The target host, port, and username - The grant expiry time

Using the Grant

The user connects with the provided key:

ssh -i /tmp/rppam-grant-key targetuser@linux-server-01.corp.local

Or on Windows (PowerShell):

ssh -i C:\Users\jdoe\Downloads\rppam-grant-key targetuser@linux-server-01.corp.local

Revoke (Grant Expired or Manually Revoked)

When a grant expires or an administrator revokes it:

  1. RP-PAM connects to the target host using the admin service account.
  2. The specific authorized_keys line matching the grant ID comment is removed.
  3. Any active sessions using that key are not forcibly terminated (SSH does not support this natively), but no new sessions can be established.
  4. The revocation is recorded in the audit log.

Manual revoke via PowerShell:

Invoke-RestMethod -Uri "https://rppam.corp.local:7101/api/v1/grants/$grantId/revoke" `
    -Method POST `
    -Headers @{ Authorization = "Bearer $adminJwt" }

Manual revoke via curl:

curl -s -X POST "https://rppam.corp.local:7101/api/v1/grants/$GRANT_ID/revoke" \
  -H "Authorization: Bearer $ADMIN_JWT" | jq .


Key Algorithm Comparison

Algorithm Key Size Security Level Performance Recommendation
ed25519 256-bit (fixed) High Fastest Recommended for most deployments
ecdsa 256 / 384 / 521-bit High Fast Good alternative where Ed25519 is not supported
rsa 2048 / 4096-bit High (at 4096) Slower Use only for legacy compatibility

Troubleshooting

Problem Cause Solution
Module status shows "error" Cannot connect to target host Verify network connectivity and SSH port; check adminUser credentials
"Permission denied" during grant Admin user lacks write access to authorized_keys Ensure the admin user can write to the target user's .ssh/authorized_keys
Key not removed on revoke Target host unreachable at revoke time RP-PAM retries automatically; check network; manual cleanup may be needed
"Host key verification failed" Host key changed or trustOnFirstUse is false Update hostKeyFingerprint in module config or set trustOnFirstUse: true
User cannot connect with granted key File permissions on private key too open Run chmod 600 /tmp/rppam-grant-key (Linux) or set ACL on Windows

Next Steps


RP-PAM v1.0.0 — Copyright 2026 Ravenphyre. All rights reserved.