Passwordless, keyless SSH at any scale
Octelium is a free and open source, self-hosted zero trust access platform. Its SSH mode authenticates to the upstream server on the User's behalf, so nobody receives a password or a private key, there is no SSH certificate authority to operate, and every session is authorized per connection and recorded.
- Free and open source
- No keys to distribute
- No PKI to operate
kind: Service
metadata:
name: bastion
spec:
mode: SSH
port: 22
config:
upstream:
url: ssh://10.0.2.14
ssh:
user: deploy
auth:
privateKey:
fromSecret: bastion-keykind: Policy
metadata:
name: ops
spec:
rules:
- effect: ALLOW
condition:
all:
of:
- match: ctx.user.spec.type == "HUMAN"
- match: '"ops" in ctx.user.spec.groups'
- match: ctx.request.ssh.connect.user != "root"kind: Service
metadata:
name: essh1
spec:
mode: SSH
config:
ssh:
eSSHMode: trueA unified secure access platform
SSH is one mode of the same platform. Each capability is described in detail below, in the same order.
- Unified access platform
One architecture for client-based zero-config VPN-like access over WireGuard and QUIC tunnels and clientless access over browsers for humans and OAuth2 access for workloads.
Read more - L7-aware access control
Identity-based, application-layer aware ABAC access control with policy-as-code via CEL and OPA, applied on a per-request basis.
Read more - Secretless access
Dynamic secretless access where teams and AI agents access protected infrastructure without ever holding a credential.
Read more - Unified identity management
Teams, workloads and AI agents share the same model for identity management, access control, and auditing.
Read more - Real-time visibility and auditing
OpenTelemetry-native, real-time, application-layer-aware visibility and structured logging.
Read more - GitOps-friendly management
Octelium is administered like Kubernetes. Define your resources in YAML files, store them in a Git repository.
Read more
One architecture for every host you reach
Each SSH server is represented by a Service, which is served by an identity-aware proxy that abstracts away the network details of the upstream behind it. People keep using their ordinary SSH client.
- The Service is reached over a client-based WireGuard or QUIC tunnel at a stable private name, so a host's actual address, network and environment stop being things anyone has to know.
- An upstream can also be an address that is only reachable from the side of a connected host, which covers workstations, private clouds and equipment behind NAT with no inbound port.
- The embedded SSH mode serves SSH from inside the octelium client itself, without a standalone SSH server on the host and without root privileges, which suits fleets of containers and IoT devices.
kind: Service
metadata:
name: app-01
spec:
mode: SSH
port: 22
config:
upstream:
url: ssh://10.0.2.20
ssh:
user: deploy
auth:
privateKey:
fromSecret: deploy-keykind: Service
metadata:
name: workstation
spec:
mode: SSH
port: 22
config:
upstream:
url: ssh://192.168.1.24
user: alicekind: Service
metadata:
name: fleet
spec:
mode: SSH
config:
ssh:
eSSHMode: trueLayer-7 aware access control with policy-as-code
Access is authorized using CEL or Open Policy Agent, against the identity behind the connection and the SSH request itself rather than the network path it arrived on.
- The SSH user requested by the client is part of the request context, and combines with identity, group membership, device posture, session type and time in the same expression.
- Subsystem requests such as SFTP and local port forwarding are disabled by default and enabled explicitly per Service, so file transfer and tunnelling are separate decisions from shell access.
- Zero standing privileges. No permanent admins or superuser Users. All access is explicitly allowed by a Policy that can be tied by time and context.
kind: Policy
metadata:
name: no-root-ssh
spec:
rules:
- effect: ALLOW
condition:
all:
of:
- match: ctx.request.ssh.connect.user != "root"
- match: '"ops" in ctx.user.spec.groups'kind: Policy
metadata:
name: production-ssh
spec:
rules:
- effect: ALLOW
condition:
all:
of:
- match: ctx.user.spec.type == "HUMAN"
- match: ctx.session.status.type == "CLIENT"
- match: ctx.device.status.osType in ["LINUX", "MAC"]
- match: '"sre" in ctx.user.spec.groups'kind: Service
metadata:
name: bastion
spec:
mode: SSH
port: 22
config:
upstream:
url: ssh://10.0.2.14
ssh:
user: deploy
auth:
privateKey:
fromSecret: bastion-key
enableSubsystem: true
enableLocalPortForwarding: trueKeys and passwords that are never distributed
The upstream password or private key is stored in the Cluster as a Secret and used by the proxy to authenticate to the SSH server once a connection has been authorized. Nobody receives it, so there is nothing to rotate across laptops when someone leaves.
- Passwords and private keys are both supported, and the upstream's own public key is pinned in the Service in OpenSSH format so the proxy verifies the host it connects to.
- The Service can force the upstream SSH user regardless of what the client asks for, which removes shared privileged accounts as a practical concern rather than a policy exception.
- Dynamic configuration maps different groups to different upstream accounts and credentials on the same host, so an operations group lands in one account and everyone else in another.
octeliumctl create secret \
--file ~/.ssh/id_ed25519 \
bastion-key
# The Service then references it by name,
# and Users never receive the key itself.kind: Service
metadata:
name: bastion
spec:
mode: SSH
port: 22
config:
upstream:
url: ssh://10.0.2.14
ssh:
user: deploy
auth:
password:
fromSecret: bastion-password
upstreamHostKey:
key: ssh-ed25519 AAAAC3NzaC1lZDI1...kind: Service
metadata:
name: ssh1
spec:
mode: SSH
dynamicConfig:
configs:
- name: root
upstream:
url: ssh://10.0.2.14
ssh:
user: root
auth:
password:
fromSecret: root-password
- name: usr
upstream:
url: ssh://10.0.2.14
ssh:
user: usr
auth:
password:
fromSecret: usr-password
rules:
- condition:
match: '"ops" in ctx.user.spec.groups'
configName: root
- condition:
matchAny: true
configName: usrA unified identity model for humans and workloads
Human and workload Users share the same identity management, authentication, access control and visibility model. A deployment job that needs a shell is authorized and recorded exactly as a person would be.
- People authenticate through any OpenID Connect or SAML 2.0 identity provider, or GitHub OAuth2, with native FIDO2 and WebAuthn passkeys, TOTP and TPM 2.0 authenticators on top of it.
- Workloads authenticate with authentication tokens, with the OAuth2 client credentials flow, or secretlessly with federated OIDC assertions from GitHub Actions, cloud providers and Kubernetes clusters.
- The client runs unprivileged where it has to, using a userspace network stack, so it works inside containers and CI runners as well as on a laptop.
- Cordium, built on Octelium, provides isolated sandboxes for agents and developers, where processes reach authorized Services through the Workspace identity with no secrets inside the sandbox.
kind: IdentityProvider
metadata:
name: github-actions
spec:
oidcIdentityToken:
issuerURL: https://token.actions.githubusercontent.com
audience: https://example.comkind: User
metadata:
name: deployer
spec:
type: WORKLOAD
groups:
- cikind: Service
metadata:
name: bastion
spec:
mode: SSH
config:
upstream:
url: ssh://10.0.2.14
ssh:
visibility:
enableSessionStdinRecording: trueSession recordings, streamed as they happen
Every SSH session produces AccessLogs identifying the User, Session and Device alongside the SSH detail of the session itself, emitted in real time to your OpenTelemetry OTLP receivers.
- Entry types cover session start and end, shell, exec and subsystem requests, direct TCP forwarding start and end, and the session recording itself.
- Recording can be disabled per Service, and stdin recording enabled explicitly, which matters for non-interactive sessions where stdin is not echoed back through stdout.
- Logs are exported over OpenTelemetry OTLP in real-time to SIEM providers you already operate.
A scalable platform that also deploys your workloads
A Cluster runs on Kubernetes and uses it to scale its own data plane, place Service proxies across Gateways, and run containerized applications that the Cluster itself deploys.
- Hosts, their Services, the Groups that may reach them and the Secrets they use are all YAML in a Git repository, applied with a single octeliumctl apply that reproduces the entire Cluster state.
- Managed containers deploy, scale and serve containerized applications as Service upstreams, alongside the SSH Services that reach the hosts running them.
- Management is centralized over the Cluster's gRPC APIs, so onboarding a new fleet of hosts can itself be automated.
$ octeliumctl apply ./cluster
Secret: bastion-key Updated
Secret: root-password Updated
IdentityProvider: okta Updated
Policy: no-root-ssh Created
Group: ops Created
Group: sre Updated
Service: bastion Created
Service: app-01 Created
Service: fleet Created
User: deployer Created
Cluster Core resources successfully applied
7 resources created
3 resources updated
ClusterConfig updatedWhat SSH access has to solve, and what solves each part
SSH itself is not the difficult part. These are the problems that appear once more than a handful of people reach more than a handful of hosts, next to the mechanism in an Octelium Cluster that handles each one.
- 01
Getting a key onto the right machines
Nothing is distributed. The upstream password or private key is stored in the Cluster as a Secret and used by the identity-aware proxy to authenticate to the upstream, so no authorized_keys file has to be maintained across a fleet.
Read more - 02
Taking it away again
Revoking access is a Policy change or a Session revocation rather than a key removal on every host someone could reach, which is what makes offboarding reliable rather than a checklist.
Read more - 03
Avoiding a certificate authority to run
There is no SSH PKI to operate, no signing service to keep available and no certificate lifetime to tune. Authentication to the Cluster is your existing identity provider, and authentication to the upstream is the Cluster's own credential.
Read more - 04
Deciding which account someone lands in
The Service can force the upstream SSH user regardless of what the client asks for, and dynamic configuration can map different groups to different accounts and credentials on the same host.
Read more - 05
Verifying the host being connected to
The upstream's public key is pinned in the Service in OpenSSH format and verified by the proxy on connect, so host key checking is configuration rather than something each person confirms on first use.
Read more - 06
Reaching hosts that cannot run a server
The embedded SSH mode serves SSH from inside the octelium client itself, without a standalone SSH server on the host and without root privileges, which suits fleets of containers, IoT devices and confined environments.
Read more - 07
Limiting what a session can do
SSH subsystem requests such as SFTP and local port forwarding are both disabled by default and enabled explicitly per Service, so file transfer and tunnelling are decisions rather than side effects of shell access.
Read more - 08
Being able to show what happened
Sessions are recorded and streamed in real time over OpenTelemetry, alongside exec requests, subsystem requests and port forwarding events, each identified by the User, Session and Device behind it.
Read more
Certificates shorten the life of a credential, which helps. They do not remove the credential from the person's machine, and they add a certificate authority to operate. Injecting the credential at the proxy removes both.
The same platform capabilities ship with every deployment, whichever way you use it.
Frequently asked
- How do people connect?
- With their ordinary SSH client. The Service is reachable at a stable private name over the client-based tunnel, and the identity-aware proxy authenticates to the upstream on the User's behalf. Nothing about the local SSH workflow changes, and no key or password is entered.
- Do I have to run a certificate authority?
- No. There is no SSH PKI to operate. People authenticate to the Cluster through your existing OpenID Connect or SAML 2.0 identity provider, and the Cluster authenticates to the upstream with a password or private key held as a Secret. Which credential is used, and which upstream account it maps to, can be selected per request from identity and context.
- Can it SSH into hosts that do not run an SSH server?
- Yes. The embedded SSH mode lets a connected client serve SSH from inside the octelium client itself, without a standalone SSH server on the host and without root privileges. Authorized Users then SSH into a host by using that Session's name as the SSH user. A Cluster ships with a built-in Service for this, so nothing has to be defined to use it.
- Are sessions recorded?
- Yes. SSH Services emit full session recordings alongside exec requests, subsystem requests and port forwarding session events, streamed in real time over OpenTelemetry to your own log management and SIEM providers. Recording can be disabled per Service, and stdin recording can be enabled explicitly, which is useful for non-interactive sessions where stdin is not echoed.
- Can SFTP and port forwarding be used?
- Both are disabled by default and enabled explicitly per Service, with enableSubsystem for subsystem requests such as SFTP and enableLocalPortForwarding for local forwarding. Port forwarding sessions are recorded as their own event types in the access logs.
- Is Octelium free and open source?
- Yes. Octelium is free and open source and is designed for single-tenant self-hosting. There is no proprietary cloud-based control plane, and it is not a limited edition of a separate paid product. An enterprise package is available for organizations that need capabilities such as a web console, SCIM provisioning and secret encryption at rest, and it is free for personal, homelab and evaluation use.
Related solutions
Zero trust database access
Secretless PostgreSQL and MySQL access with per-request authorization and application-layer auditing.
Read moreZero trust Kubernetes access
Per-verb Kubernetes authorization with the kubeconfig held by the Cluster rather than handed to a User.
Read moreStrongDM alternative
The same infrastructure access model across SSH, databases and Kubernetes, self-hosted end to end.
Read moreDeploy Octelium on your own infrastructure in minutes
Free and open source. Self-hosted. No vendor lock-in.