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:
- Service account access — RP-PAM needs an SSH-capable service account on each target host with permission to modify
authorized_keysfor the target users. - Network connectivity — The RP-PAM server must reach target hosts on the configured SSH port (default 22).
- 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:
- RP-PAM generates a new key pair using the configured algorithm (e.g., Ed25519).
- The public key is appended to
~/.ssh/authorized_keyson the target host, tagged with a comment: - The private key is encrypted with the user's session key and returned.
- 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:
Or on Windows (PowerShell):
Revoke (Grant Expired or Manually Revoked)¶
When a grant expires or an administrator revokes it:
- RP-PAM connects to the target host using the admin service account.
- The specific
authorized_keysline matching the grant ID comment is removed. - Any active sessions using that key are not forcibly terminated (SSH does not support this natively), but no new sessions can be established.
- 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¶
- Database Credential Module — Manage just-in-time database credentials
- Active Directory Module — Manage AD group membership grants
- Submitting Access Requests — How users request access
RP-PAM v1.0.0 — Copyright 2026 Ravenphyre. All rights reserved.