Why VPN Is the Wrong Abstraction for SSH
A VPN grants network reachability. SSH requires privileged authorization to a specific host. When these two concepts are conflated, every VPN user can see every server on the network—even those they should never connect to. The VPN becomes a flat network key that opens doors far beyond what any individual user needs.
The attack surface is straightforward: compromise a VPN credential (phishing, credential stuffing, stolen laptop) and you gain visibility into the entire network segment. From there, lateral movement to high-value targets becomes a scanning exercise rather than an authentication challenge.
The safer pattern publishes SSH as a named resource behind identity and policy controls. No network-level access is required. Users authenticate to a specific server, for a specific reason, for a bounded time window—and every keystroke is recorded.
The Secure SSH Access Architecture
Secure SSH flow: user authenticates via SSO+MFA, policy engine evaluates access, session broker connects to target with recording enabled, access auto-expires
Certificate-Based vs Key-Based Access
Traditional SSH access relies on long-lived key pairs. A private key on a developer’s laptop is effectively a permanent credential—it doesn’t expire, isn’t tied to identity, and can be copied without detection. The entire security model depends on the private key file not being compromised.
Certificate-based SSH improves on this by issuing short-lived certificates signed by a trusted CA. But it introduces PKI complexity: CA rotation, certificate distribution, clock synchronization, and debugging “certificate not yet valid” errors across time zones.
The browser-native model sidesteps both approaches. The user never holds a credential at all. The session broker authenticates to the target server using JIT-generated credentials that exist only for the session duration. When the session ends, the credential is invalidated. There is nothing on the user’s device to steal.
| Dimension | Static SSH Keys | SSH Certificates | Browser-Native Sessions |
|---|---|---|---|
| Credential lifetime | Permanent until manually revoked | Hours to days (configurable) | Session duration only |
| Identity binding | None—key can be shared | Certificate principal field | SSO identity, non-transferable |
| Client software | Standard ssh client | Standard ssh client + CA trust | Browser only |
| Revocation | authorized_keys cleanup (manual) | Certificate expiry (automatic) | Instant—broker terminates session |
| Session recording | None built-in | None built-in | Automatic, full fidelity |
| Audit attribution | Key fingerprint only | Certificate principal | Full SSO identity + session context |
| Operational overhead | Key rotation scripts | CA management, clock sync | None—managed by platform |
SSO Integration Patterns
The SSO integration determines how identity flows from your corporate directory into SSH access decisions. There are three common patterns:
Pattern 1: Group-Based Access
Map IdP groups directly to server groups. Members of the “backend-engineers” group can access backend production servers. Members of “sre-oncall” can access all servers but only during their on-call rotation. This is the simplest model and works well for stable team structures.
Pattern 2: Attribute-Based Access (ABAC)
Use IdP attributes (department, clearance level, project assignment) combined with resource tags (environment, sensitivity, data classification) to compute access dynamically. More flexible than groups, but requires well-maintained attribute data in your IdP.
Pattern 3: Request-Based Access (JIT)
No standing access. Engineers request access to specific servers for specific reasons with a time window. An approval workflow (manager, security team, or automated policy) grants temporary access. This produces the strongest audit evidence but adds friction for routine access.
Recommended Approach
Use group-based access for non-production environments (low friction, reasonable security). Use JIT request-based access for production infrastructure (higher friction, strongest evidence). This layered approach matches friction to risk level.
MFA Enforcement at the Session Level
Many organizations enforce MFA at the VPN level but not at the SSH level. This means that once a user is on the network, SSH access to any reachable server requires only the SSH key—no additional authentication step. A compromised key bypasses MFA entirely.
Session-level MFA enforcement requires a second factor at the point of SSH connection, not just at network entry. This can be:
- TOTP/WebAuthn at session start: User provides a second factor before the SSH session begins
- Push notification approval: A push to the user’s phone confirms intent before connecting
- Step-up authentication for sensitive hosts: Production servers require additional verification even if MFA was provided at login
- Continuous authentication: Long-running sessions periodically re-verify the user is still present
Session Recording Architecture
Session recording for SSH captures three streams of data:
| Stream | What It Captures | Use Case |
|---|---|---|
| Input stream | Every keystroke typed by the user | Reconstructing exact commands, detecting typos vs. intentional actions |
| Output stream | All terminal output including command results | Understanding what the user saw, verifying successful operations |
| Timing data | Timestamp for each input/output event | Playback at real speed, correlating with external events |
The recording is stored server-side (never on the user’s device) and indexed for search. Security teams can search across all sessions for specific commands (rm -rf, chmod 777, curl | bash) or access patterns (connections to production databases, root escalations).
Command-Level Auditing
Beyond recording the visual session, command-level auditing parses the input stream to extract structured command data. This enables:
- Alert on dangerous commands: Notify the security team when
rm -rf /, mass file deletions, or unauthorized package installations are executed - Compliance queries: “Show me all sessions where a user accessed /etc/shadow on production servers in the last 30 days”
- Incident reconstruction: During a security incident, quickly identify which commands were run on compromised hosts and by whom
- Policy enforcement: Block or flag specific commands before execution (e.g., prevent
shutdownon production without approval)
Automatic Access Expiry
Every SSH access grant should have an expiry condition. Standing access—permanent SSH keys, persistent VPN access—violates the principle of least privilege by definition. Access should expire based on:
| Expiry Trigger | Example | Enforcement |
|---|---|---|
| Time window | “Access for 2 hours to debug the outage” | Session terminated at window end |
| Reason completion | “Access until JIRA-1234 is resolved” | Access revoked when ticket closes |
| Role change | Engineer moves to a different team | IdP group change triggers access removal |
| On-call rotation end | Primary on-call shifts to next engineer | PagerDuty/OpsGenie integration revokes access |
| Inactivity | No session started for 14 days | Standing grant automatically removed |
Pilot Rollout Plan
Start small, measure results, expand based on evidence:
- Week 1–2: Select pilot group. Choose one on-call team (3–5 engineers) and 5–10 servers they access regularly
- Week 2–3: Deploy and configure. Install agent on pilot servers, configure SSO integration, define initial policies
- Week 3–4: Parallel operation. Run new system alongside existing VPN+key access. Measure both paths.
- Week 4–5: Collect metrics. Time-to-first-access, user satisfaction, sessions recorded, keys removed
- Week 5–6: Expand or adjust. Based on pilot data, expand to next team or adjust configuration
Pilot Caution
Do not remove VPN/key access during the pilot. Run both systems in parallel until the new system has proven reliable during at least one real incident. The worst outcome is blocking access during a production emergency because the new system has an untested edge case.
Measuring Success
Track these metrics to determine if the migration is delivering value:
| Metric | Before (VPN + Keys) | Target (SSO + Sessions) |
|---|---|---|
| Time to first access (new engineer) | Hours to days (key provisioning) | Under 5 minutes (SSO login) |
| Standing SSH keys in production | Hundreds to thousands | Zero (JIT credentials only) |
| Session recording coverage | 0% (no recording infrastructure) | 100% of production sessions |
| Mean time to revoke access (offboarding) | Days to weeks (manual key cleanup) | Instant (IdP deprovisioning propagates) |
| Audit evidence generation time | Days (manual log correlation) | Minutes (automated report) |
Hardening the Host Side
Replacing the VPN solves the network trust problem, but the host still needs attention. Disable password authentication in sshd_config, set PermitRootLogin no, and configure AllowGroups to accept only the service account that the access platform uses for agent-based sessions. When the access broker manages the credential lifecycle, the host should accept only broker-originated connections—not direct key-based logins that bypass policy. Use the SSH hardening generator to produce a production-grade sshd_config aligned with CIS benchmarks.
Consider deploying host-based intrusion detection (OSSEC, Wazuh, or Falco) alongside the access platform. The access layer controls who enters; the host layer detects anomalous behavior after entry. Together they provide defense in depth that neither VPN nor keys alone can offer.
Related Resources
- Try browser-based SSH SSO
- Audit your existing SSH keys
- Generate hardened sshd_config
- Session recording documentation
Replace VPN-Gated SSH with Identity-Aware Sessions
Give engineers fast, secure access to servers with SSO, MFA, session recording, and auto-expiry built in. No VPN, no keys, no client install. Connect your first server in under 5 minutes.
Start Free Trial