Platform

PAM — Privileged Access Management

Clavex PAM covers three sub-systems under /api/v1/organizations/{org}/pam: JIT access requests with an approval workflow, an encrypted credential vault, and an agentless SSH Certificate Authority ("Platform SSO for Linux") backed by HashiCorp Vault. All endpoints require the security resource permission.

The Three Sub-Systems

JIT Access Requests
Time-bounded requests with approve/deny/revoke, plus a break-glass emergency path.
🔑
Credential Vault
Encrypted secrets with checkout/return, optional approval gating, and rotation logging.
🖧
SSH Certificate Authority
Vault-backed ephemeral SSH certs — no agent installed on target hosts.

Sub-System 1 — JIT Access Requests

A user requests time-bounded access to a named resource; an admin approves or denies it. Approved requests become the authorization gate for credential vault checkout and (optionally) SSH certificate signing below.

bash
# Request access $ curl -s -X POST https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/access-requests \ -H "Authorization: Bearer $ORG_TOKEN" -H "Content-Type: application/json" \ -d '{ "resource_type": "ssh_host", "resource_id": "db-primary-01", "resource_name": "Production DB primary", "justification": "Investigating replication lag ticket OPS-4821", "requested_duration": 60 }' | jq '{id,status}' { "id": "c9e1...", "status": "pending" }
# Admin approves $ curl -s -X POST https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/access-requests/c9e1.../approve \ -H "Authorization: Bearer $ORG_TOKEN" -H "Content-Type: application/json" \ -d '{"note": "approved — known incident"}'
Break-glass: when normal approval would be too slow for an incident, POST /pam/access-requests/break-glass creates a pre-approved request directly — subject to a weekly usage cap and a minimum justification length, and it immediately notifies every admin (webhook + optional Slack/Teams).

Sub-System 2 — Credential Vault

Secrets are encrypted at rest and only decrypted momentarily on checkout. Flag a credential require_access_request to force the approval gate above before the secret can be revealed.

bash
# Store a credential $ curl -s -X POST https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/credentials \ -H "Authorization: Bearer $ORG_TOKEN" -H "Content-Type: application/json" \ -d '{ "name": "db-primary-01 root", "credential_type": "password", "secret": "correct-horse-battery-staple", "target_host": "db-primary-01", "require_access_request": true, "checkout_duration": 60 }' | jq '{id,name}'
# Check out (must reference the approved request from Sub-System 1) $ curl -s -X POST https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/credentials/{cred_id}/checkout \ -H "Authorization: Bearer $ORG_TOKEN" -H "Content-Type: application/json" \ -d '{"access_request_id": "c9e1...", "reason": "OPS-4821"}' { "secret": "correct-horse-battery-staple", "warning": "This secret will not be shown again." }
# Return it when done $ curl -s -X POST https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/credentials/{cred_id}/return \ -H "Authorization: Bearer $ORG_TOKEN" -H "Content-Type: application/json" \ -d '{"checkout_id": "..."}'

Set rotation_interval_days to have Clavex track credential age; GET .../credentials/{cred_id}/rotation-log returns the rotation history.

Sub-System 3 — SSH Certificate Authority

Point Clavex at a Vault SSH secrets engine. Clavex signs short-lived user certificates on demand — sshd trusts the CA's public key, so there is nothing to install on the target host.

bash
# 1. Point Clavex at your Vault SSH secrets engine $ curl -s -X PUT https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/ssh-ca \ -H "Authorization: Bearer $ORG_TOKEN" -H "Content-Type: application/json" \ -d '{ "vault_addr": "https://vault.acme.internal:8200", "vault_token": "hvs.CAESIJ...", "vault_mount": "ssh", "vault_role": "clavex-signer", "cert_ttl_seconds": 3600, "require_access_request": false }'
# 2. Fetch the CA public key and configure sshd on each target host $ curl -s https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/ssh-ca/public-key \ -H "Authorization: Bearer $ORG_TOKEN" > /etc/ssh/clavex_ca.pub # /etc/ssh/sshd_config: TrustedUserCAKeys /etc/ssh/clavex_ca.pub AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
# 3. Sign a user's SSH public key for an ephemeral cert $ curl -s -X POST https://id.clavex.eu/api/v1/organizations/$ORG_ID/pam/ssh-ca/sign \ -H "Authorization: Bearer $ORG_TOKEN" -H "Content-Type: application/json" \ -d '{ "public_key": "ssh-ed25519 AAAAC3Nza... user@laptop", "valid_principals": "alice@acme.eu" }' | jq '{signed_key,expires_at}'
# 4. Use it $ # save signed_key as ~/.ssh/id_ed25519-cert.pub, then: $ ssh -i ~/.ssh/id_ed25519 alice@db-primary-01
JIT-gated SSH: set require_access_request: true on the CA config to force ssh-ca/sign to require an active, approved access request — the same approval gate used for the credential vault.
Zero-downtime CA rotation: rotating the SSH CA key is a staged process (POST /pam/ssh-ca/rotation/start → status polling → mark-ready → complete) so both the old and new CA public keys are trusted during cutover and no session is dropped. This is an advanced operation — see the Admin API reference for the full state machine.

Privileged Session Recording

Independently of the sub-systems above, Clavex can track a privileged session's lifecycle and timeline of events (useful for session replay / audit tooling you build on top):

EndpointPurpose
POST /pam/sessionsStart a session, optionally linked to an access request
POST /pam/sessions/:id/eventsAppend a timeline event (keystrokes, commands, screen changes — payload is opaque JSON)
POST /pam/sessions/:id/endClose the session
GET /pam/sessions/:id/eventsReplay the recorded timeline