A zero trust remote access VPN over QUIC
Octelium is a free and open source, self-hosted zero trust access platform. Client-based access runs over QUIC or WireGuard tunnels and behaves as a zero-config VPN: a single stable route, stable private dual-stack addresses and automatic private DNS. What makes it zero trust is what sits above the tunnel, where every request is authorized on its own.
- Free and open source
- Designed for self-hosting
- QUIC and WireGuard transports
kind: Service
metadata:
name: grafana
spec:
mode: HTTP
config:
upstream:
url: http://10.0.6.12:3000kind: Policy
metadata:
name: sre
spec:
rules:
- effect: ALLOW
condition:
all:
of:
- match: ctx.user.spec.type == "HUMAN"
- match: '"sre" in ctx.user.spec.groups'
- match: ctx.session.status.type == "CLIENT"kind: Service
metadata:
name: pg-prod
spec:
mode: POSTGRES
port: 5432
config:
upstream:
url: postgres://10.0.4.21:5432
postgres:
user: analytics_ro
database: analytics
auth:
password:
fromSecret: pg-passwordA unified secure access platform
The tunnel is one of them. 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
A tunnel that carries traffic, not permissions
Each resource is protected by an identity-aware proxy that provides application-layer-aware access control, secretless access, and visibility. Connecting to the Cluster establishes a path, and grants nothing by itself.
- The client connects over QUIC or WireGuard to every Gateway, and each Service is reached through a single stable route with a stable private dual-stack address and an automatically managed private DNS name.
- On Linux the client uses the WireGuard kernel implementation where it is available, a wireguard-go TUN device otherwise, and an unprivileged gVisor userspace stack where it has no privileges at all, so it also runs in containers, CI runners and IoT devices.
- The very same Services can also be published clientlessly over HTTPS, for people in a browser and for workloads over standard OAuth2 and bearer authentication, with no client at all.
kind: Service
metadata:
name: grafana
spec:
mode: HTTP
config:
upstream:
url: http://10.0.6.12:3000kind: Service
metadata:
name: workstation
spec:
mode: SSH
port: 22
config:
upstream:
url: ssh://192.168.1.24
user: alicekind: Service
metadata:
name: grafana
spec:
mode: HTTP
isPublic: true
config:
upstream:
url: http://10.0.6.12:3000Layer-7 aware access control with policy-as-code
Access is authorized on a per-request basis, using CEL or Open Policy Agent, against the identity behind the request and the content of the request itself rather than the network path it arrived on.
- Dynamic, fine-grained attribute-based access control ABAC with policy-as-code via CEL and OPA.
- Application-layer-aware access control that includes HTTP methods, paths, headers and serialized JSON body content, SSH users, Kubernetes verbs, resources and namespaces, and PostgreSQL and MySQL users and databases.
- 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: sensitive
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: Policy
metadata:
name: api-read-only
spec:
rules:
- effect: ALLOW
condition:
all:
of:
- match: ctx.request.http.method == "GET"
- match: ctx.request.http.path.startsWith("/v1/")
- match: '"analysts" in ctx.user.spec.groups'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'Credentials that are never distributed
Application-layer credentials are stored in the Cluster as Secrets and injected into the upstream connection once a request is authorized. A tunnel on its own does nothing about the API keys, database passwords and private keys that reach a resource once the tunnel is up.
- Covers HTTP API keys and access tokens, SSH passwords and private keys, PostgreSQL and MySQL passwords, kubeconfigs, and mTLS client certificates.
- The upstream account, user and credential can be selected dynamically per request from identity and context, so different Users reach the same upstream with different privileges.
- Revoking access is a Policy change rather than a credential rotation across every system a person or workload could reach.
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: Service
metadata:
name: pg-prod
spec:
mode: POSTGRES
port: 5432
config:
upstream:
url: postgres://10.0.4.21:5432
postgres:
user: analytics_ro
database: analytics
auth:
password:
fromSecret: pg-password
sslMode: REQUIREkind: Service
metadata:
name: stripe
spec:
mode: HTTP
config:
upstream:
url: https://api.stripe.com
http:
auth:
bearer:
fromSecret: stripe-api-keyA unified identity model for humans and workloads
Human and workload Users share the same identity management, authentication, access control and visibility model. A container in CI connects the same way an engineer does, and is authorized by the same Policies.
- 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.
- People authenticate through any OpenID Connect or SAML 2.0 identity provider, with native FIDO2 and WebAuthn passkeys, TOTP and TPM 2.0 authenticators available on top of it.
- The MCP and LLM gateway modes extend the same identity, policy and audit model to the tools and model providers that AI agents reach.
- 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: ci-runner
spec:
type: WORKLOAD
groups:
- cikind: Service
metadata:
name: tools-mcp
spec:
mode: MCP
isPublic: true
config:
upstream:
url: http://mcp.internal:8080
mcp:
endpoint: /mcpReal-time visibility at the application layer
OpenTelemetry-ready, application-layer aware, structured auditing and visibility emitted to your OpenTelemetry OTLP receivers, where they can be exported to your log management and SIEM tools.
- Application-layer-aware visibility with logs that include HTTP requests and responses, database queries, SSH session recordings, DNS question names, MCP methods and tool names, and LLM operations and token usage.
- 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.
- Gateways scale horizontally rather than each one imposing a fixed ceiling on the traffic and the number of connections it can carry.
- The Cluster is managed declaratively. Resources are defined in YAML, kept in a Git repository, and applied with a single octeliumctl apply that reproduces the entire Cluster state.
- Management is centralized over the Cluster's gRPC APIs, so the Cluster is fully programmable and no configuration change requires SSH access to a server.
$ octeliumctl apply ./cluster
Secret: pg-password Updated
Secret: bastion-key Updated
IdentityProvider: okta Updated
Policy: sre Created
Group: sre Created
Group: analysts Updated
Service: grafana Created
Service: pg-prod.db Created
Service: bastion Created
Namespace: db Created
Cluster Core resources successfully applied
7 resources created
3 resources updated
ClusterConfig updatedWhat a remote access VPN leaves open, and what closes it
A tunnel solves reachability. These are the problems that remain once the tunnel is up, next to the mechanism in an Octelium Cluster that handles each one.
- 01
Route tables that grow with the network
Services are addressed through the Cluster rather than through the networks their upstreams sit on, so a client keeps a single stable route no matter how many environments, clouds and clusters are behind it. There are no remote subnets to advertise and no overlapping ranges to reconcile.
Read more - 02
Split tunneling as a workaround
Because only Cluster traffic uses the tunnel, ordinary internet traffic never has to be pulled through a gateway to keep a connection usable, which is the usual reason full tunneling gets switched on and the usual source of its egress cost.
Read more - 03
Dual-stack translation
Clients connect with a private IPv6 address by default and can be forced to IPv4-only or dual-stack, independently of what each upstream speaks. No NAT64 or DNS64 has to be operated to bridge the two.
Read more - 04
Keeping a private DNS in sync
Every Service has a stable private FQDN assigned by the Cluster and resolved through an automatically configured split DNS, so dynamic upstreams such as containers, Kubernetes services and cloud-assigned endpoints do not need a DNS zone maintained by hand.
Read more - 05
Access described at the network level
Authorization is expressed against Services, identities and requests rather than IP addresses and subnets, so a new database created inside an allowed subnet is not automatically reachable, and a reused address does not silently inherit an old permission.
Read more - 06
Direct exposure of the resource
Traffic terminates at an identity-aware proxy that understands the protocol in front of each upstream, so the upstream is not directly reachable by whoever is on the network, including an attacker already inside the perimeter.
Read more - 07
Credentials that go stale
Human Users re-authenticate through your identity provider and workload Users through short-lived assertions or OAuth2 credentials, and application-layer credentials for upstreams are held by the Cluster rather than copied to laptops and CI systems.
Read more - 08
Logging that stops at layer 4
Every request produces an identity-aware AccessLog with the application-layer detail of the request itself, streamed over OpenTelemetry, instead of connection records that show an address reached a port.
Read more
Encrypting the path between two networks is a transport problem and a solved one. What is left is deciding, per request, who may reach which resource and with which credential, and being able to show afterwards what happened.
The same platform capabilities ship with every deployment, whichever way you use it.
Frequently asked
- Is the tunnel QUIC or WireGuard?
- Both are supported. Octelium uses WireGuard for tunneling by default, and a Cluster can additionally enable a QUIC-based tunneling mode. When the Cluster has it enabled, a client selects it with octelium connect --tunnel-mode quicv0 or by setting the OCTELIUM_QUIC environment variable. Everything above the transport, including identity, Policies, secretless access and auditing, is identical either way.
- How is the QUIC mode enabled on a Cluster?
- The quick installer takes a --quicv0 flag, and existing Clusters enable it through the pre-installation configuration. The QUIC listener uses UDP port 8443, so that port needs to be open if the machine sits behind a firewall, and an additional public DNS entry is required. WireGuard remains available alongside it.
- Do clients need root privileges?
- Not necessarily. On Linux the client first tries the WireGuard kernel implementation, which is the most performant and needs root or the NET_ADMIN capability. Without those it falls back to a wireguard-go TUN device, and without permission to create a TUN device it runs an unprivileged userspace network stack over gVisor Netstack. In that last mode Services are reached by mapping them to the host, which is what makes the client usable inside containers, CI runners and confined environments.
- What happens to DNS?
- Each Service has a private FQDN in the form service.namespace.local.yourdomain, with a shorter form for the default Namespace. The client configures a split DNS server for that suffix automatically, using resolvectl on Linux and networksetup on macOS. Nothing has to be memorized, distributed or kept in sync as upstream addresses change.
- Can resources behind NAT be reached without opening a port?
- Yes. A Service upstream can be an address that is only reachable from the side of a connected client, which serves it to the Cluster over its own tunnel using the --serve or --serve-all flags. That covers a laptop behind NAT, containers, Kubernetes pods in other clusters, private clouds and IoT devices, with no inbound port and no firewall change on that side.
- 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
WireGuard remote access VPN
Zero-config WireGuard tunnels with a single stable route, dual-stack addressing and automatic private DNS.
Read moreZero Trust Network Access
Octelium as a complete ZTNA and BeyondCorp platform for humans, workloads and AI agents on a single architecture.
Read moreBusiness VPN
A remote access platform for a whole team, with SSO, device posture, secretless access and application-layer auditing.
Read moreDeploy Octelium on your own infrastructure in minutes
Free and open source. Self-hosted. No vendor lock-in.