# Table of Contents - [Introduction - Octelium Docs](#introduction-octelium-docs) - [Introduction - Octelium Docs](#introduction-octelium-docs) - [Introduction - Cordium Docs](#introduction-cordium-docs) - [Quick Installation Guide - Octelium Docs](#quick-installation-guide-octelium-docs) - [First Steps to Managing the Cluster - Octelium Docs](#first-steps-to-managing-the-cluster-octelium-docs) - [Cluster Components - Octelium Docs](#cluster-components-octelium-docs) - [Scopes - Octelium Docs](#scopes-octelium-docs) - [How Octelium Works - Octelium Docs](#how-octelium-works-octelium-docs) - [CLI Tools - Octelium Docs](#cli-tools-octelium-docs) - [Zero Trust in Octelium - Octelium Docs](#zero-trust-in-octelium-octelium-docs) - [Resources - Octelium Docs](#resources-octelium-docs) - [Quick Installation Guide - Cordium Docs](#quick-installation-guide-cordium-docs) - [Introduction - Cordium Docs](#introduction-cordium-docs) - [Cluster - Cordium Docs](#cluster-cordium-docs) - [AI Agents - Cordium Docs](#ai-agents-cordium-docs) - [Accessing and Serving Octelium Services - Cordium Docs](#accessing-and-serving-octelium-services-cordium-docs) - [Introduction - Octelium Docs](#introduction-octelium-docs) - [Concepts - Cordium Docs](#concepts-cordium-docs) - [CLI - Cordium Docs](#cli-cordium-docs) - [Access Methods - Cordium Docs](#access-methods-cordium-docs) - [CLI - Cordium Docs](#cli-cordium-docs) - [Codex - Cordium Docs](#codex-cordium-docs) - [Claude Code - Cordium Docs](#claude-code-cordium-docs) - [OpenCode - Cordium Docs](#opencode-cordium-docs) - [APIs and SDKs - Cordium Docs](#apis-and-sdks-cordium-docs) - [Running Containers - Cordium Docs](#running-containers-cordium-docs) - [Workspace Configuration - Cordium Docs](#workspace-configuration-cordium-docs) - [CI/CD - Cordium Docs](#ci-cd-cordium-docs) - [Cluster Configuration - Cordium Docs](#cluster-configuration-cordium-docs) --- # Introduction - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Introduction ============ [What is Octelium?](https://octelium.com/docs/octelium/latest/overview/intro#what-is-octelium) ----------------------------------------------------------------------------------------------- Octelium is a free and open source, self-hosted unified zero trust secure access platform. Octelium replaces VPNs, tunnels, gateways, reverse proxies, bastion hosts, and other remote access tools with a unified, modern, scalable zero trust architecture. Octelium provides secure access for humans and workloads to private and internal resources behind NAT, protected public resources such as SaaS APIs and databases, and containerized applications, via a common model for identity management, client-based and clientless access, application-layer aware access control via policy-as-code, dynamic secretless access, and real-time auditing and visibility. Depending on the deployment and use case, Octelium can serve as a remote access VPN, ZTNA/BeyondCorp platform, secure tunnel infrastructure, API, AI or MCP gateway, infrastructure AI agentic systems, Kubernetes ingress alternative, application deployment platform, or homelab infrastructure. Human clientless browser access Workload / Human client-based access over WireGuard / QUIC AI Agent clientless access via OAuth2 / bearer token Unified identity for humans, workloads & AI agents Clientless BeyondCorp access Private cloud AWS, GCP, Azure Databases internal & SaaS APIs internal & SaaS Kubernetes internal & SaaS SSH internal & public Resources behind NAT laptops, IoT, on-prem Overview of an Octelium Cluster. On the left, three kinds of clients connect: a human over clientless browser access, a workload or human over client-based access via WireGuard or QUIC, and an AI agent over clientless access via OAuth2 or bearer token. All traffic flows into the central Octelium Cluster, whose rotating capabilities include unified identity for humans, workloads and AI agents, short-lived fine-grained access tokens, per-request ABAC, L7-aware access control and dynamic routing, secretless access, zero-config WireGuard and QUIC access, clientless BeyondCorp access, OpenTelemetry-native visibility, and policy-as-code. On the right, the Cluster securely reaches upstreams: private cloud resources, internal and SaaS databases, APIs, Kubernetes, SSH, and resources behind NAT on laptops, containers and IoT devices. note Want to see Octelium in practice? The [first steps guide](https://octelium.com/docs/octelium/latest/overview/management) walks through creating a _Service_, applying identity-based access control, connecting to the _Cluster_, and accessing the protected resource. [How is Octelium Different?](https://octelium.com/docs/octelium/latest/overview/intro#how-is-octelium-different) ----------------------------------------------------------------------------------------------------------------- * **A modern, unified, secure access platform** Octelium is built around identity-aware proxies rather than broad network access. Its unified architecture brings together three concerns that are commonly handled by separate systems: * **Unified access platform for humans and workloads** Human and workload _Users_ share the same identity management, authentication, access control and visibility model. Humans authenticate via your OpenID Connect or SAML 2.0 identity providers as well as native FIDO2/WebAuthn/Passkey, TOTP and TPM 2.0, while workloads authenticate via standard OAuth2 client credentials, authentication tokens or secretless OIDC-based assertions (e.g. from GitHub Actions, Azure, Kubernetes clusters, etc...). * **Unified architecture for client-based and clientless access** Both private zero-config client-based access over WireGuard/QUIC tunnels, and public clientless BeyondCorp access, via browsers for humans and via standard OAuth2 and bearer authentication for workloads, without any agents, clients or SDKs. * **Unified access to private, protected public, and containerized applications** Any private resource behind NAT in any environment (e.g. on-prem, private clouds, your own laptop, IoT devices, etc...), protected public resources such as SaaS APIs and databases, as well as containerized applications (via [managed containers](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers) ) deployed and scaled by the Octelium _Cluster_ itself. * **Dynamic secretless access** _Users_ access protected HTTP APIs, SSH servers, PostgreSQL and MySQL databases, Kubernetes clusters, RDP servers and mTLS-protected resources without ever holding the API key, password, private key, kubeconfig or certificate. Such credentials are stored in the _Cluster_ as _Secrets_ and injected on a per-request basis at the identity-aware proxy without having to share, manage, rotate, and distribute such credentials to _Users_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ). * **Dynamic application-layer aware access control with policy-as-code** Octelium provides centralized, fine-grained attribute-based access control (ABAC) on a per-request basis via policy-as-code using [CEL](https://cel.dev/) as well as [OPA](https://www.openpolicyagent.org/) (Open Policy Agent). This L7-aware access control includes HTTP request path, method, serialized JSON body, etc..., database queries, Kubernetes verbs and namespaces (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy#l7-aware-policies) ). * **Zero standing privileges** Octelium intentionally has no notion whatsoever of an "admin" or "superuser" _User_. Every permission, including access to the API Server itself, must be explicitly granted by a _Policy_ and is evaluated on a per-request basis, which means that access can be tied to time, context and attributes (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy) ). * **Sandboxed development and AI agent execution with Cordium** [Cordium](https://octelium.com/docs/cordium/latest/overview/intro) is an open-source, self-hosted sandbox platform built on Octelium. Cordium _Workspaces_ provide isolated execution environments for developers, AI agents, and automated workloads, and can be accessed through browser-based terminals, SSH, the `cordium` CLI, or gRPC-based SDKs. Processes running inside a _Workspace_ can access authorized Octelium _Services_ through the Workspace identity without distributing upstream API keys, SSH keys, database passwords, or other application credentials into the sandbox. * **Declarative, GitOps-friendly management** A _Cluster_ is administered like Kubernetes: you define your resources in YAML files, store them in a Git repository, and a single `octeliumctl apply` command is enough to (re)produce the entire _Cluster_ state anywhere. Management is centralized via the _Cluster_'s gRPC-based APIs, which means you never SSH into servers to set up configurations, and the entire _Cluster_ is programmable via SDKs (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview) ). * **OpenTelemetry-ready, application-layer aware auditing and visibility** Access logs identify the _User_, _Session_ and _Device_ as well as the application-layer details of the request (e.g. HTTP paths, database queries, SSH session recordings, etc...) and are emitted in real time to your OpenTelemetry OTLP receivers, where they can be exported to your log management and SIEM tools (read more [here](https://octelium.com/docs/octelium/latest/management/core/visibility) ). * **Built on Kubernetes for seamless horizontal scalability and high availability** An Octelium Cluster uses Kubernetes as an infrastructure to deploy and scale its control-plane and data-plane components, place _Service_ proxies across _Gateways_, restart failed components, and run containerized applications deployed by the _Cluster_. This allows the same architecture to run on a single-node Kubernetes installation for small deployments or scale across multi-node managed and on-prem Kubernetes environments. * **Context-aware, identity-based, L7 aware dynamic configuration and routing** Octelium can select upstreams, upstream accounts and credentials, protocol-specific settings, and routing behavior dynamically from request context. These decisions can be expressed with policy-as-code via CEL or OPA and evaluated on a per-request basis. * **No change in your infrastructure is needed** Your upstream resources don't need to be aware of Octelium at all. They can be listening to any behind-NAT private network, even to localhost. No public gateways, no need to open ports behind firewalls to serve your resources wherever they are. Connected clients only need outbound internet connectivity. * **Avoiding traditional VPN networking problems altogether** Each _Service_ is assigned stable private dual-stack addresses and an automatically managed private DNS name within a single stable route. There are no injected routes for remote networks, no routing conflicts, and no NAT64/DNS64 pain, regardless of what the upstreams themselves support (read more [here](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) ). * **Open source and designed for self-hosting** No proprietary cloud-based control plane or paid SaaS. Octelium _Clusters_ are meant to be self-hosted. You can host a _Cluster_ on top of a single-node Kubernetes cluster running on a cheap cloud VM/VPS, and you can also host it on scalable cloud-based or on-prem multi-node Kubernetes installations with no vendor lock-in. [Use Cases](https://octelium.com/docs/octelium/latest/overview/intro#use-cases) -------------------------------------------------------------------------------- **Secure access:** * **Modern Remote Access VPN:** Zero-config, layer-7 aware client-based and clientless access. See the quick installation guide [here](https://octelium.com/docs/octelium/latest/overview/quick-install) . * **Zero Trust Access to SaaS APIs:** Secretless access without distributing long-lived API keys. See examples for a generic API [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/zero-trust-saas-api) , AWS Lambda [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/lambda-zero-trust-secretless-access) and AWS S3 [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/s3-zero-trust-secretless-access) . * **API Gateway:** A self-hosted, scalable and secure API gateway for microservices. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/api-gateway) . * **AI Gateway:** Identity-based access control, routing and visibility for any LLM provider. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/ai/ai-gateway) . * **MCP Gateways and AI Agent-based Architectures:** Identity management, authentication, access control and visibility for [MCP](https://modelcontextprotocol.io/introduction) gateways and AI agent architectures and agentic meshes. See an example [here](https://octelium.com/management/guide/service/ai/self-hosted-mcp.mdx) . **Deployment and hosting:** * **Self-Hosted Secure Tunnels:** An ngrok/Cloudflare Tunnel alternative for identity-based as well as anonymous access. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/open-source-self-hosted-ngrok-alternative) . * **Self-Hosted PaaS:** Deploy, scale and host containerized applications, similar to Vercel or Netlify. See an example for [Next.js/Vite apps](https://octelium.com/docs/octelium/latest/management/guide/service/http/nextjs-vite) . * **Kubernetes Ingress Alternative:** Route to any Kubernetes service via dynamic, L7-aware policy-as-code. * **Homelab:** Securely access all your resources behind NAT from anywhere, and privately or publicly host your websites, APIs and heavy containers (e.g. Ollama, ClickHouse, Pi-hole, etc...). See examples for [remote VSCode](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/remote-vscode-code-server) and [Pi-hole](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/pihole) . [Where to Go Next](https://octelium.com/docs/octelium/latest/overview/intro#where-to-go-next) ---------------------------------------------------------------------------------------------- * **Try it in your browser:** Spin up a full _Cluster_ inside a GitHub Codespace via the [playground](https://github.com/octelium/playground) with zero installation. * **Install a Cluster in minutes:** The [quick installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) installs a full single-node _Cluster_ on any cheap VM/VPS using your own domain. * **Understand the architecture first:** [How Octelium Works](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) walks through the identity-aware proxy model, the request lifecycle and the control plane. --- # Introduction - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Introduction ============ [What is Octelium?](https://octelium.com/docs/octelium/latest/overview/intro#what-is-octelium) ----------------------------------------------------------------------------------------------- Octelium is a free and open source, self-hosted unified zero trust secure access platform. Octelium replaces VPNs, tunnels, gateways, reverse proxies, bastion hosts, and other remote access tools with a unified, modern, scalable zero trust architecture. Octelium provides secure access for humans and workloads to private and internal resources behind NAT, protected public resources such as SaaS APIs and databases, and containerized applications, via a common model for identity management, client-based and clientless access, application-layer aware access control via policy-as-code, dynamic secretless access, and real-time auditing and visibility. Depending on the deployment and use case, Octelium can serve as a remote access VPN, ZTNA/BeyondCorp platform, secure tunnel infrastructure, API, AI or MCP gateway, infrastructure AI agentic systems, Kubernetes ingress alternative, application deployment platform, or homelab infrastructure. Human clientless browser access Workload / Human client-based access over WireGuard / QUIC AI Agent clientless access via OAuth2 / bearer token Unified identity for humans, workloads & AI agents Clientless BeyondCorp access Private cloud AWS, GCP, Azure Databases internal & SaaS APIs internal & SaaS Kubernetes internal & SaaS SSH internal & public Resources behind NAT laptops, IoT, on-prem Overview of an Octelium Cluster. On the left, three kinds of clients connect: a human over clientless browser access, a workload or human over client-based access via WireGuard or QUIC, and an AI agent over clientless access via OAuth2 or bearer token. All traffic flows into the central Octelium Cluster, whose rotating capabilities include unified identity for humans, workloads and AI agents, short-lived fine-grained access tokens, per-request ABAC, L7-aware access control and dynamic routing, secretless access, zero-config WireGuard and QUIC access, clientless BeyondCorp access, OpenTelemetry-native visibility, and policy-as-code. On the right, the Cluster securely reaches upstreams: private cloud resources, internal and SaaS databases, APIs, Kubernetes, SSH, and resources behind NAT on laptops, containers and IoT devices. note Want to see Octelium in practice? The [first steps guide](https://octelium.com/docs/octelium/latest/overview/management) walks through creating a _Service_, applying identity-based access control, connecting to the _Cluster_, and accessing the protected resource. [How is Octelium Different?](https://octelium.com/docs/octelium/latest/overview/intro#how-is-octelium-different) ----------------------------------------------------------------------------------------------------------------- * **A modern, unified, secure access platform** Octelium is built around identity-aware proxies rather than broad network access. Its unified architecture brings together three concerns that are commonly handled by separate systems: * **Unified access platform for humans and workloads** Human and workload _Users_ share the same identity management, authentication, access control and visibility model. Humans authenticate via your OpenID Connect or SAML 2.0 identity providers as well as native FIDO2/WebAuthn/Passkey, TOTP and TPM 2.0, while workloads authenticate via standard OAuth2 client credentials, authentication tokens or secretless OIDC-based assertions (e.g. from GitHub Actions, Azure, Kubernetes clusters, etc...). * **Unified architecture for client-based and clientless access** Both private zero-config client-based access over WireGuard/QUIC tunnels, and public clientless BeyondCorp access, via browsers for humans and via standard OAuth2 and bearer authentication for workloads, without any agents, clients or SDKs. * **Unified access to private, protected public, and containerized applications** Any private resource behind NAT in any environment (e.g. on-prem, private clouds, your own laptop, IoT devices, etc...), protected public resources such as SaaS APIs and databases, as well as containerized applications (via [managed containers](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers) ) deployed and scaled by the Octelium _Cluster_ itself. * **Dynamic secretless access** _Users_ access protected HTTP APIs, SSH servers, PostgreSQL and MySQL databases, Kubernetes clusters, RDP servers and mTLS-protected resources without ever holding the API key, password, private key, kubeconfig or certificate. Such credentials are stored in the _Cluster_ as _Secrets_ and injected on a per-request basis at the identity-aware proxy without having to share, manage, rotate, and distribute such credentials to _Users_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ). * **Dynamic application-layer aware access control with policy-as-code** Octelium provides centralized, fine-grained attribute-based access control (ABAC) on a per-request basis via policy-as-code using [CEL](https://cel.dev/) as well as [OPA](https://www.openpolicyagent.org/) (Open Policy Agent). This L7-aware access control includes HTTP request path, method, serialized JSON body, etc..., database queries, Kubernetes verbs and namespaces (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy#l7-aware-policies) ). * **Zero standing privileges** Octelium intentionally has no notion whatsoever of an "admin" or "superuser" _User_. Every permission, including access to the API Server itself, must be explicitly granted by a _Policy_ and is evaluated on a per-request basis, which means that access can be tied to time, context and attributes (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy) ). * **Sandboxed development and AI agent execution with Cordium** [Cordium](https://octelium.com/docs/cordium/latest/overview/intro) is an open-source, self-hosted sandbox platform built on Octelium. Cordium _Workspaces_ provide isolated execution environments for developers, AI agents, and automated workloads, and can be accessed through browser-based terminals, SSH, the `cordium` CLI, or gRPC-based SDKs. Processes running inside a _Workspace_ can access authorized Octelium _Services_ through the Workspace identity without distributing upstream API keys, SSH keys, database passwords, or other application credentials into the sandbox. * **Declarative, GitOps-friendly management** A _Cluster_ is administered like Kubernetes: you define your resources in YAML files, store them in a Git repository, and a single `octeliumctl apply` command is enough to (re)produce the entire _Cluster_ state anywhere. Management is centralized via the _Cluster_'s gRPC-based APIs, which means you never SSH into servers to set up configurations, and the entire _Cluster_ is programmable via SDKs (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview) ). * **OpenTelemetry-ready, application-layer aware auditing and visibility** Access logs identify the _User_, _Session_ and _Device_ as well as the application-layer details of the request (e.g. HTTP paths, database queries, SSH session recordings, etc...) and are emitted in real time to your OpenTelemetry OTLP receivers, where they can be exported to your log management and SIEM tools (read more [here](https://octelium.com/docs/octelium/latest/management/core/visibility) ). * **Built on Kubernetes for seamless horizontal scalability and high availability** An Octelium Cluster uses Kubernetes as an infrastructure to deploy and scale its control-plane and data-plane components, place _Service_ proxies across _Gateways_, restart failed components, and run containerized applications deployed by the _Cluster_. This allows the same architecture to run on a single-node Kubernetes installation for small deployments or scale across multi-node managed and on-prem Kubernetes environments. * **Context-aware, identity-based, L7 aware dynamic configuration and routing** Octelium can select upstreams, upstream accounts and credentials, protocol-specific settings, and routing behavior dynamically from request context. These decisions can be expressed with policy-as-code via CEL or OPA and evaluated on a per-request basis. * **No change in your infrastructure is needed** Your upstream resources don't need to be aware of Octelium at all. They can be listening to any behind-NAT private network, even to localhost. No public gateways, no need to open ports behind firewalls to serve your resources wherever they are. Connected clients only need outbound internet connectivity. * **Avoiding traditional VPN networking problems altogether** Each _Service_ is assigned stable private dual-stack addresses and an automatically managed private DNS name within a single stable route. There are no injected routes for remote networks, no routing conflicts, and no NAT64/DNS64 pain, regardless of what the upstreams themselves support (read more [here](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) ). * **Open source and designed for self-hosting** No proprietary cloud-based control plane or paid SaaS. Octelium _Clusters_ are meant to be self-hosted. You can host a _Cluster_ on top of a single-node Kubernetes cluster running on a cheap cloud VM/VPS, and you can also host it on scalable cloud-based or on-prem multi-node Kubernetes installations with no vendor lock-in. [Use Cases](https://octelium.com/docs/octelium/latest/overview/intro#use-cases) -------------------------------------------------------------------------------- **Secure access:** * **Modern Remote Access VPN:** Zero-config, layer-7 aware client-based and clientless access. See the quick installation guide [here](https://octelium.com/docs/octelium/latest/overview/quick-install) . * **Zero Trust Access to SaaS APIs:** Secretless access without distributing long-lived API keys. See examples for a generic API [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/zero-trust-saas-api) , AWS Lambda [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/lambda-zero-trust-secretless-access) and AWS S3 [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/s3-zero-trust-secretless-access) . * **API Gateway:** A self-hosted, scalable and secure API gateway for microservices. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/api-gateway) . * **AI Gateway:** Identity-based access control, routing and visibility for any LLM provider. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/ai/ai-gateway) . * **MCP Gateways and AI Agent-based Architectures:** Identity management, authentication, access control and visibility for [MCP](https://modelcontextprotocol.io/introduction) gateways and AI agent architectures and agentic meshes. See an example [here](https://octelium.com/management/guide/service/ai/self-hosted-mcp.mdx) . **Deployment and hosting:** * **Self-Hosted Secure Tunnels:** An ngrok/Cloudflare Tunnel alternative for identity-based as well as anonymous access. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/open-source-self-hosted-ngrok-alternative) . * **Self-Hosted PaaS:** Deploy, scale and host containerized applications, similar to Vercel or Netlify. See an example for [Next.js/Vite apps](https://octelium.com/docs/octelium/latest/management/guide/service/http/nextjs-vite) . * **Kubernetes Ingress Alternative:** Route to any Kubernetes service via dynamic, L7-aware policy-as-code. * **Homelab:** Securely access all your resources behind NAT from anywhere, and privately or publicly host your websites, APIs and heavy containers (e.g. Ollama, ClickHouse, Pi-hole, etc...). See examples for [remote VSCode](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/remote-vscode-code-server) and [Pi-hole](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/pihole) . [Where to Go Next](https://octelium.com/docs/octelium/latest/overview/intro#where-to-go-next) ---------------------------------------------------------------------------------------------- * **Try it in your browser:** Spin up a full _Cluster_ inside a GitHub Codespace via the [playground](https://github.com/octelium/playground) with zero installation. * **Install a Cluster in minutes:** The [quick installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) installs a full single-node _Cluster_ on any cheap VM/VPS using your own domain. * **Understand the architecture first:** [How Octelium Works](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) walks through the identity-aware proxy model, the request lifecycle and the control plane. --- # Introduction - Cordium Docs Search Docs Quick Links Introduction ============ [What Is Cordium?](https://octelium.com/docs/cordium/latest/overview/intro#what-is-cordium) -------------------------------------------------------------------------------------------- Cordium is a free and open source, self-hosted, identity-based, horizontally scalable sandbox platform built on [Kubernetes](https://kubernetes.io/) and [Octelium](https://octelium.com/docs/octelium/latest/overview/intro) . It provides isolated, reproducible sandboxes for humans, AI agents, and automated workloads. Cordium is designed around two tightly integrated purposes that most platforms treat as separate concerns: * **General-purpose sandboxed execution**: a platform for running both long-lived workloads (remote development environments, persistent coding sessions, running servers) and short-lived tasks (AI agent runs, CI/CD jobs, automated scripts) inside isolated, reproducible sandboxes accessible via a web browser, SSH, the `cordium` CLI, or a gRPC-based SDK. * **Identity-based zero-trust secretless remote access**: a platform that leverages Octelium ZTNA capabilities to provide secretless, policy-driven access to infrastructure resources (SSH servers, databases, internal HTTP APIs, mTLS services) from within Workspaces, without exposing, distributing, or managing upstream application-layer credentials (e.g. API keys and access tokens, SSH private keys, database passwords, etc.). This works for both human users opening a browser-based terminal and AI agents executing programmatically inside a Workspace. Cordium is 100% free and open source. It is designed for single-tenant self-hosting and built on standard Kubernetes infrastructure with no proprietary cloud control plane and no vendor lock-in. [Main Features](https://octelium.com/docs/cordium/latest/overview/intro#main-features) --------------------------------------------------------------------------------------- * **Unified platform for humans and AI agents.** The same **Workspace** (synonymous with a sandbox) can be accessed interactively through a browser-based terminal, via SSH, through the CLI, or programmatically via gRPC-based SDKs. This makes Cordium equally suitable as a remote development environment for engineers (comparable to GitHub Codespaces) and as an execution sandbox for AI agents, and automated workloads. Workspaces support both long-lived runs (remote development, persistent servers) and short-lived runs (AI agent tasks, build jobs, scripted automation). * **Highly customizable sandbox environments.** Workspace filesystems can be built from OCI/Docker images, Dockerfiles, git repositories, and devcontainers. Multi-repository cloning, including private repositories with authentication. Workspace configurations are fully declarative via YAML files and can be instantiated through the `cordium` CLI or managed programmatically via the gRPC API. Each running Workspace supports full root access within the sandbox, allowing users to run containers, install system packages, and run privileged services. **Templates** support pre-building for fast Workspace instantiation. **Spaces** provide namespacing for Workspaces, Templates, Secrets, and GitProviders. Secrets can be referenced in environment variables and repository authentication configurations. Workspace storage can be persistent or ephemeral. Resource limits (memory, CPU, and storage) can be defined at the Workspace, Space, and Cluster level. * **Rootless container-based sandboxing on standard Kubernetes.** No bare-metal nodes or specialized hardware are needed. Workspaces run efficiently on any Kubernetes cluster. * **Zero-trust platform on Octelium.** Cordium is built on Octelium, inheriting its zero-trust infrastructure as a foundational layer to provide the following capabilities: * **Dynamic secretless access.** Octelium's layer-7 awareness enables Users to seamlessly access resources protected by application-layer credentials without exposing, managing, or distributing such secrets (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ). This works for HTTP APIs without sharing API keys and access tokens, SSH servers without sharing passwords and private keys, Kubernetes clusters, PostgreSQL/MySQL databases, and any L7 protocol protected by mTLS. * **Modern, dynamic, fine-grained access control.** Octelium provides a centralized, scalable, fine-grained, dynamic, context-aware, layer-7-aware, attribute-based access control system (ABAC) evaluated on a per-request basis (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy) ) with policy-as-code using [CEL](https://cel.dev/) and [OPA](https://www.openpolicyagent.org/) (Open Policy Agent). Octelium has no notion of an "admin" user, enforcing zero standing privileges by default. * **Continuous strong authentication.** A unified authentication system for both human and workload Users, supporting any web identity provider (IdP) that uses OpenID Connect or SAML 2.0, as well as GitHub OAuth2 (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#web-identity-providers) ). It also supports secretless authentication for workloads via OIDC-based assertions (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#workload-identity-providers) ). Built-in support for MFA, re-authentication, and login via FIDO2/WebAuthn/Passkey, TOTP, and TPM 2.0 Authenticators. * **OpenTelemetry-native auditing and visibility.** Real-time, identity-based, L7-aware visibility and access logging. Every request is logged and exported to your OpenTelemetry OTLP receivers for integration with log management and SIEM providers. * **Kubernetes-native pluggable storage.** Cordium leverages Kubernetes-native storage for Workspace persistence and integrates with any Kubernetes CSI driver and VolumeSnapshot provider. This includes Longhorn, AWS EBS, GCP Persistent Disk, Azure Disk, Ceph/Rook, OpenEBS, and any other CSI-compliant storage solution. Storage class and volume snapshot class selection is policy-driven via CEL expressions, allowing operators to route different Workspace types to different storage backends. * **Ready for agentic AI.** Cordium is not only a sandbox for isolated long-lived and short-lived process execution by sandboxed AI agents. It leverages Octelium's zero-trust infrastructure to provide identity-based, fine-grained, L7-aware, context-aware, ABAC-based access to resources (e.g. remote private/internal resources behind NAT, publicly protected SaaS resources such as APIs and databases, etc.) of any type from within Workspaces. This includes **secretless access** for resources that require application-layer credentials (API keys, access tokens, SSH passwords and private keys, database passwords, and mTLS private keys) without exposing, distributing, or sharing such credentials with the sandboxed AI agent. Credential mappings and privilege scopes can be dynamically assigned to specific agents based on identity and context on a per-request basis. * **Open source and designed for self-hosting.** Cordium, like Octelium itself, is fully open source and designed for single-tenant self-hosting. There is no proprietary cloud-based control plane, and this is not a limited open source version of a separate fully functional paid SaaS product. Cordium can be deployed on a single-node Kubernetes cluster running on a low-cost cloud VM/VPS, or on production-grade multi-node Kubernetes installations, cloud-based or on-premises, with no vendor lock-in. [The Problem Cordium Solves](https://octelium.com/docs/cordium/latest/overview/intro#the-problem-cordium-solves) ----------------------------------------------------------------------------------------------------------------- Modern development and automation workflows require isolated, reproducible execution environments that can be provisioned on demand, accessed from anywhere, and decommissioned cleanly. At the same time, those environments need access to infrastructure: databases, internal APIs, source code repositories, SSH targets. Managing that access (distributing credentials, rotating secrets, scoping permissions) is operationally expensive and a persistent source of security incidents. Existing approaches address one side or the other. Remote development platforms (GitHub Codespaces, Coder, Gitpod) solve the execution environment problem but leave credential management entirely to the user. Most sandbox platforms for AI agents focus primarily on execution isolation and SDK ergonomics, while infrastructure access and credential governance are usually handled separately. Modern identity-aware proxy-based zero trust access platforms solve the credential problem but are not designed as execution environments. Cordium unifies these. A Workspace is simultaneously an isolated execution environment and a first-class identity in the Octelium Cluster system. Processes running inside a Workspace can access any authorized Octelium-managed resource (e.g. a PostgreSQL/MySQL database, an SSH server, an internal HTTP API, a generic TCP/UDP workload, etc...) through their Workspace identity alone, with no credential injection, no static API keys, and no secrets in environment variables. The Workspace's access scope is determined based on identity and context on a per-request basis via policy-as-code using CEL and OPA expressions. --- # Quick Installation Guide - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Quick Installation Guide ======================== This is a quick guide for you to install a full-fledged single-node Octelium _Cluster_ on any cheap Linux machine, VM or cloud VPS (e.g. DigitalOcean droplet, Hetzner, AWS EC2, etc...). This single-node _Cluster_ is good enough for development, personal, or undemanding production use cases. note To install a production, scalable multi-node _Cluster_ over a typical cloud-based or on-premise Kubernetes installation, we recommend referring to this guide [here](https://octelium.com/docs/octelium/latest/install/cluster/installing-cluster) . You can also install an Octelium _Cluster_ as a playground inside a running GitHub Codespace in this [repository](https://github.com/octelium/playground) . [Requirements](https://octelium.com/docs/octelium/latest/overview/quick-install#requirements) ---------------------------------------------------------------------------------------------- This guide only needs 2 requirements: * Having a cheap cloud server/VM instance (e.g. DigitalOcean Droplet, Hetzner server, AWS EC2, etc...) that's running a recent Linux distribution (e.g. Ubuntu 24.04 LTS or later, Debian 12+, etc...), preferably freshly installed, with at the very least 2GB of RAM, 2vCPUs and 20 GB of disk storage as a sensible minimum requirement. * Having a domain or a subdomain of a [domain name](https://en.wikipedia.org/wiki/Domain_name) that you actually own (e.g. `example.com`, `octelium.example.com`, `sub.sub.example.com`, etc...). This domain is the _Cluster_'s domain since an Octelium _Cluster_ is defined and addressed by its domain once installed (e.g. through the `octelium` and `octeliumctl` commands). The installer script in this guide takes care of automatically installing the Octelium _Cluster_ and all of its dependencies. In other words, you only need a fresh VM/VPS and the installer will take care of installing everything. [Installation](https://octelium.com/docs/octelium/latest/overview/quick-install#installation) ---------------------------------------------------------------------------------------------- Once you SSH into your VPS/VM as the Linux `root` user, you install the _Cluster_ by running the following commands: `1curl -o install-cluster.sh https://octelium.com/install-cluster.sh 2chmod +x install-cluster.sh 3 4# IMPORTANT: Replace with your actual domain/subdomain to be used as the Cluster domain 5./install-cluster.sh --domain ` note The above installation command should work flawlessly with any VM with a public IP address (e.g. DigitalOcean droplets, Hetzner VMs, etc...). For more advanced installation options (e.g. the _Cluster_'s VM is behind NAT/firewall such as EC2 machines and Google Cloud Compute instances), please refer to [this](https://octelium.com/docs/octelium/latest/overview/quick-install#advanced-installation-options) section below. The script should take a few minutes depending on your VM's capabilities to finish. Here is a demo video to show what the installation process looks like: note To install [Cordium](https://octelium.com/docs/cordium/latest/overview/intro) , add the `--cordium` flag to the `./install-cluster.sh` command. Cordium is an open source sandbox platform built on Octelium and Kubernetes that allows developers and workloads, including AI agents, to access Octelium _Services_ from within remote, reproducible, sandboxes via browsers, CLI, API and SSH (read [more](https://octelium.com/docs/cordium/latest/use/access-methods) ). note To install the enterprise package, add the `--enterprise` flag to the `./install-cluster.sh` command. The enterprise package is free to use, forever, for personal (e.g. homelab) and evaluation use cases. It includes enterprise-grade features such as a web-based console for management, real-time visibility, UI policy builders and testers, as well as other features such as SCIM 2.0, SIEM integrations, TLS and DNS management, secret encryption at rest, managed upgrades, etc... **Upon completion of the _Cluster_ installation, you will see the following message, which includes an `octelium login` command at the end of it**: `1The Cluster installation is now complete! 2You can start interacting with the Cluster once you set the Cluster TLS certificate and the public DNS.For more information, you might want to visit the docs at https://octelium.com/docs 3# ... 4Once you set up your public DNS and Cluster TLS certificate, 5use the following command to login and start interacting with the Cluster. 6 7octelium login --domain --auth-token ` **You can now copy that `octelium login` command in order to use it later from your own machine to log in to the _Cluster_ and begin using it**. [Post-Installation](https://octelium.com/docs/octelium/latest/overview/quick-install#post-installation) -------------------------------------------------------------------------------------------------------- To complete the installation and start interacting with the _Cluster_, 2 final steps are required: Setting the public DNS for the _Cluster_ domain and Setting the _Cluster_ domain TLS certificate. ### [Public DNS](https://octelium.com/docs/octelium/latest/overview/quick-install#public-dns) You need to set **two DNS entries** in your DNS provider (e.g. Cloudflare, Namecheap, GoDaddy, etc...) in order for the _Cluster_ to be publicly addressable via its domain name: 1. An `A` entry to resolve `` to the VM/VPS's public IP address as follows: | Entry Field | Value | | --- | --- | | Type | `A` | | Name / Host | `` | | Value | `` | 2. A `CNAME` entry resolving the wildcard domain `*.` to ``. This entry effectively resolves all of the `` sub-domains to the VM/VPS public IP address. You simply need to set your `CNAME` DNS entry as follows: | Entry Field | Value | | --- | --- | | Type | `CNAME` | | Name / Host | `*.` | | Value | `` | ### [TLS Certificate](https://octelium.com/docs/octelium/latest/overview/quick-install#tls-certificate) You need to set the _Cluster_ domain TLS certificate in order for the _Cluster_, its _API Server_ as well as its public _Services_ to be able to communicate over HTTPS. For example, you can use [Let's Encrypt](https://letsencrypt.org/) via [Certbot](https://certbot.eff.org/instructions) to issue a certificate for your _Cluster_ domain (you can read more [here](https://octelium.com/docs/octelium/latest/install/cluster/tls-certificate) ) and then provide the issued certificate to the _Cluster_. This x509 certificate needs to be issued for the following domains (i.e. the domains that need to be included in the certificate's SAN list): * ``. * `*.` wildcard. * `*.local.` wildcard. This is not required but recommend if you want to have TLS-based _Services_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/overview#listening-over-tls) ). Here is an example of certbot issuing a certificate via the DNS-01 challenge (read more in the Let's Encrypt docs): `1 2# Run as root from within your Cluster VM/VPS 3apt-get update 4apt install certbot 5 6# Replace with your own domain 7certbot certonly --email --agree-tos --cert-name -d ",*.,*.local." --manual --preferred-challenges dns` The newly issued certificate is now stored in the `/etc/letsencrypt/live/` directory. Now, from your VPS/VM, you can provide the certificate to the _Cluster_ simply via the `octops cert` command as follows: `1# Replace with your own domain 2octops cert --key /etc/letsencrypt/live//privkey.pem --cert /etc/letsencrypt/live//fullchain.pem --kubeconfig /etc/rancher/k3s/k3s.yaml` [Login to the Cluster](https://octelium.com/docs/octelium/latest/overview/quick-install#login-to-the-cluster) -------------------------------------------------------------------------------------------------------------- Now that we did set the _Cluster_ public DNS and TLS certificate, we can now use the `octelium login` command that we copied earlier to login to the _Cluster_ from our local machine (e.g. your own laptop) as follows: `1octelium login --domain --auth-token ` **If you try to invoke the command above before setting your actual domain's certificate**, you will be met with an `authentication handshake failed` since the current _Cluster_ TLS certificate is an initial self-signed certificate created by the _Cluster_ during installation. You can skip that error, for now until you set your own real TLS certificate, by setting the `OCTELIUM_INSECURE_TLS` environment variable to `true`. Here is an example: `1export OCTELIUM_INSECURE_TLS=true 2octelium login --domain --auth-token ` note In addition to using `OCTELIUM_INSECURE_TLS` environment variable to skip verifying the server TLS certificate, you can also use the `OCTELIUM_DEV` environment variable which is generally used for development and debugging and it throws the debug logs of the Octelium clients as follows: `1export OCTELIUM_DEV=true 2octelium login --domain --auth-token ` [Initial Configuration](https://octelium.com/docs/octelium/latest/overview/quick-install#initial-configuration) ---------------------------------------------------------------------------------------------------------------- This step is not required; however, it might be useful if this is your first Octelium _Cluster_. In Octelium, _Cluster_ resources are mainly managed via the `octeliumctl apply` command, which is very similar to how `kubectl apply` works (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview#applying-changes) ). For now, we are going to use an initial configuration for your _Cluster_ that includes only two resources: * A _User_ for yourself that includes your primary email. We use the name `alice` and the email `alice@example.com` in the example configuration below. * An _IdentityProvider_ in order for you to login to the _Cluster_ using your _User_'s email via the web _Portal_. Octelium supports three types of such _IdentityProviders_: * GitHub OAuth2. You can see a detailed example [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#github-oauth2) . * OpenID Connect _IdentityProviders_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#openid-connect) ). You can see a detailed example if you have a Gitlab cloud account [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#gitlab-example) . * SAML 2.0 _IdentityProviders_. You can read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#saml-20) . note You can also read detailed guides on how to self-host FOSS identity providers (IdPs) on the same Kubernetes cluster that is running the Octelium _Cluster_ for [Keycloak](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/keycloak-helm-self-host) , [Authentik](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/authentik-helm-self-host) and [Dex](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/dex-helm-self-host) and use them to create an OpenID Connect _IdentityProvider_ that can be used to login into the _Cluster_. In this guide, we're going to use a Gitlab OpenID Connect _IdentityProvider_ for the sake of simplicity. Once you create the Gitlab OIDC application and obtain your Gitlab client ID and client secret, you now store the client secret as an Octelium _Secret_ as follows: `1# Set the "OCTELIUM_DOMAIN" environment variable to your Cluster domain in order to skip using "--domain" flag for every command 2export OCTELIUM_DOMAIN= 3 4octeliumctl create secret idp-client-secret` Now, you create a YAML file in the machine you just logged in via `octelium login` and add the initial configuration as follows: `1kind: User 2metadata: 3 name: alice 4spec: 5 type: HUMAN 6 email: alice@example.com 7 authorization: 8 policies: ["allow-all"] 9--- 10kind: IdentityProvider 11metadata: 12 name: gitlab 13spec: 14 displayName: Login with Gitlab 15 oidc: 16 issuerURL: https://gitlab.com 17 clientID: abcd... 18 clientSecret: 19 fromSecret: idp-client-secret` And now, we apply the creation of these two resources to the _Cluster_ via the `octeliumctl apply` as follows: `1octeliumctl apply /path/to/config_file.yaml` [Tips](https://octelium.com/docs/octelium/latest/overview/quick-install#tips) ------------------------------------------------------------------------------ If this is your first Octelium _Cluster_, the following tips might be useful for you: * Once you login for the first time via the `octelium login` command as shown above, you should create at least one _User_ with enough access permissions for yourself (see the initial configuration example [here](https://octelium.com/docs/octelium/latest/overview/quick-install#initial-configuration) ). The authentication token _Credential_ (read more about _Credentials_ [here](https://octelium.com/docs/octelium/latest/management/core/credential) ) used in this initial `octelium login` command is issued for the `root` _User_, which is installed automatically by the _Cluster_ during the installation process. It should be noted that there is nothing special about the `root` _User_ in Octelium and you can actually delete it once you add your own _Users_ and other resources. Once you add your own _Users_ with enough permissions to act as the _Cluster_ administrators, _IdentityProviders_, and other resources, you can safely remove the initial authentication token \_Credential as follows: `1octeliumctl delete cred root-init` * Octelium CLIs, namely `octelium` and `octeliumctl`, are designed to simultaneously work with multiple Octelium _Clusters_. That's why you need to add the `--domain ` flag to each command. Obviously, this becomes tiresome and annoying if you're doing too many commands in the same shell for a single _Cluster_. That's why it's recommended to set the environment variable `OCTELIUM_DOMAIN` to your domain to use all your commands without having to use the `--domain` flag for each command. Here is an example: `1export OCTELIUM_DOMAIN= 2 3# List the Cluster Services 4octeliumctl get service 5# OR 6octeliumctl get svc 7 8 9# List the Cluster Users 10octeliumctl get user 11 12 13# List the Cluster Sessions 14octeliumctl get session 15# OR 16octeliumctl get sess 17 18# Create an authentication token Credential for "root" User 19octeliumctl create credential --user root --policy allow-all first-cred` * After you login for the first time via the `octelium login` command, you might want to connect to the _Cluster_ and access its available _Services_ (read more about connecting via the `octelium` CLI [here](https://octelium.com/docs/octelium/latest/user/cli/connect) ). For example, the _Cluster_ creates a `demo-nginx` _Service_ during the installation. You can access it as follows: `1export OCTELIUM_DOMAIN= 2 3# Connect via the detached mode 4octelium connect -d 5# OR in foreground 6sudo -E octelium connect 7# Then access the "demo-nginx" Service 8# This Service is installed during the Cluster installation 9curl demo-nginx 10 11 12# OR via the rootless mode and mapping the Service to a localhost port 13octelium connect -p demo-nginx:9000 14# And then access the Service 15curl localhost:9000` * TLS certificates usually expire within a few months. For example, certificates issued by Let's Encrypt expire after 90 days by default. It would be better for you to automate the process of rotating TLS certificates and providing them to your Octelium _Cluster_ either via `octops cert` or by re-creating the TLS secret with `kubectl` using some simple bash scripts, or, even better, by using a FOSS solution like [cert-manager](https://cert-manager.io/) (read more [here](https://octelium.com/docs/octelium/latest/install/cluster/tls-certificate#cert-manager) ). * Since Octelium is a zero trust architecture, all access to protected resources, represented by _Services_, must be explicitly allowed by _Policies_ (read more about _Policies_ and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy) ). As shown in the initial configuration example [here](https://octelium.com/docs/octelium/latest/overview/quick-install#initial-configuration) , the _User_ `alice` has the `allow-all` _Policy_ attached, which grants her access to all _Services_, unless there are further _Policies_ that override it by explicitly denying her access. Octelium installs the `allow-all` and `deny-all` _Policies_ during the installation process to make it easier for you to directly use them and attach them to your different resources. Attaching _Policies_ is not restricted to just _Users_ as in the example above, you can actually attach _Policies_ to _Users_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/user#policies) ), _Services_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/overview#policies) ), _Groups_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/group#policies) ), _Namespaces_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/namespace#policies) ). You can also attach _Policies_ to your issued _Credentials_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#policies) ). * The installer in this guide automatically installs [k3s](https://k3s.io/) as the underlying Kubernetes cluster, and then installs the Octelium _Cluster_ on top of it. You can access that Kubernetes cluster, typically via `kubectl`, by setting the kubeconfig file to `/etc/rancher/k3s/k3s.yaml`. Here is an example: `1export KUBECONFIG="/etc/rancher/k3s/k3s.yaml" 2kubectl get pods -A 3kubectl get pods -n octelium` [What Now?](https://octelium.com/docs/octelium/latest/overview/quick-install#what-now) --------------------------------------------------------------------------------------- Your _Cluster_ is up and running. Where you go next depends on what you want to do. **Manage your _Cluster_.** Start with [First Steps](https://octelium.com/docs/octelium/latest/overview/management) , then explore [_Services_](https://octelium.com/docs/octelium/latest/management/core/service/overview) , [_Users_](https://octelium.com/docs/octelium/latest/management/core/user) , [_Policies_](https://octelium.com/docs/octelium/latest/management/core/policy) , [_IdentityProviders_](https://octelium.com/docs/octelium/latest/management/core/identity-providers) , [_Credentials_](https://octelium.com/docs/octelium/latest/management/core/credential) and [_Authenticators_](https://octelium.com/docs/octelium/latest/management/core/authenticator) (e.g. FIDO passkeys and TOTP MFA). **Connect and access _Services_** from your own machine via the [`octelium` client](https://octelium.com/docs/octelium/latest/user/cli/connect) . **Explore guides by use case:** * **Gateways:** Octelium as an [API](https://octelium.com/docs/octelium/latest/management/guide/service/http/api-gateway) , [AI](https://octelium.com/docs/octelium/latest/management/guide/service/ai/ai-gateway) or [MCP](https://octelium.com/docs/octelium/latest/management/guide/service/ai/self-hosted-mcp) gateway. * **Web apps & sites:** secure [Next.js / Vite apps](https://octelium.com/docs/octelium/latest/management/guide/service/http/nextjs-vite) , [host a site from behind NAT](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/website-api-hosting-nat) , or use Octelium as an [ngrok alternative](https://octelium.com/docs/octelium/latest/management/guide/service/http/open-source-self-hosted-ngrok-alternative) . * **Databases:** [passwordless access to NeonDB](https://octelium.com/docs/octelium/latest/management/guide/service/databases/neon) . * **Cloud, secretless:** reach [AWS S3](https://octelium.com/docs/octelium/latest/management/guide/service/http/s3-zero-trust-secretless-access) and [Lambda](https://octelium.com/docs/octelium/latest/management/guide/service/http/lambda-zero-trust-secretless-access) without distributing keys. * **Homelab:** deploy [Pi-hole](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/pihole) or [VS Code](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/remote-vscode-code-server) , or self-host an _IdentityProvider_ with [Keycloak](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/keycloak-helm-self-host) , [Authentik](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/authentik-helm-self-host) or [Dex](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/dex-helm-self-host) . [Advanced Installation Options](https://octelium.com/docs/octelium/latest/overview/quick-install#advanced-installation-options) -------------------------------------------------------------------------------------------------------------------------------- The above `./install-cluster.sh --domain ` should automatically work with any VM/VPS with a public IP address (e.g. DigitalOcean, Hetzner, Vultr, etc...). Therefore, you generally do **not** need to read this section unless you want to install the _Cluster_ in a special environment (e.g. VM is behind NAT and/or firewall, you want to use QUIC tunneling, the _Cluster_ is meant for internal testing/playground use cases, etc...). * If your VM/VPS is behind NAT where the IP address of the default/main network device of the machine is a private/internal IP address instead of its public IP address (e.g. EC2 and GCP instances under default configurations), then you will need to use the `--nat` flag as follows: `1./install-cluster.sh --domain --nat` note The `--nat` flag instructs the _Cluster_'s [_Ingress_](https://octelium.com/docs/octelium/latest/reference/components#ingress) to use and listen on the main internal/private VM address instead of using the machine's public address. If you want to install the _Cluster_ in an internal network behind NAT and access it internally from within that private network (this is only recommended for internal testing use cases), you can add the `--force-machine-ip` flag in addition to the `--nat` flag. The `--force-machine-ip` instructs the WireGuard listener in the _Cluster_'s [_GatewayAgent_](https://octelium.com/docs/octelium/latest/reference/components#gateway-agent) to use and listen on the main internal/private IP address instead of the machine's public address. note If the VM/VPS is behind a firewall (e.g. EC2, Google GCP VMs, etc...), you will need to open the TCP port `443` for Octelium ingress and the UDP port `53820` for WireGuard. * By default, the installation script attempts to automatically obtain the public IP address of the VM/VPS, you can explicitly set the public IP address via the `--public-ip` flag. Here is an example: `1./install-cluster.sh --domain --public-ip 1.2.3.4` * By default the Octelium _Cluster_ uses only WireGuard for tunneling. You can additionally enable the QUIC-based tunneling mode (read more [here](https://octelium.com/docs/octelium/latest/install/cluster/pre-install#quic-mode) ) via the `--quicv0` flag as follows: `1./install-cluster.sh --domain --quicv0` note If your VPS is behind a firewall, you will also have to open the UDP port `8443` for the QUIC listener. You also need to create an additional public DNS entry as shown in detail [here](https://octelium.com/docs/octelium/latest/install/cluster/dns#quic-mode) . * By default the `latest` _Cluster_ version is installed. You can install a specific _Cluster_ version via the `--version` flag as follows: `1./install-cluster.sh --domain --version 0.1.2` [Troubleshooting](https://octelium.com/docs/octelium/latest/overview/quick-install#troubleshooting) ---------------------------------------------------------------------------------------------------- Here are some of the common problems you might experience when trying to access the _Cluster_ for the first time, typically via the initial `octelium login` command, from your own local machine to the _Cluster_: ### [Produced Zero Addresses](https://octelium.com/docs/octelium/latest/overview/quick-install#produced-zero-addresses) If your `octelium login` command produces the following error: `1Error: rpc error: code = Unavailable desc = name resolver error: produced zero addresses` That means you did not set your `CNAME` DNS entry as shown above. You can even verify that by using `ping` as follows: `1ping octelium-api.` If it does not resolve, it means that your `CNAME` entry is simply not set. Also make sure that you did set your `A` DNS entry. You can verify by using `ping` as follows: `1ping ` And if this ping also does not resolve, it means that your `A` entry is simply not set too. You might also need to flush your local machine DNS cache to make sure that your local machine is not resolving to any old, now invalid, DNS entries as follows: In Linux: `1sudo resolvectl flush-caches` In Windows as an Admin: `1ipconfig /flushdns` In macOS: `1sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder` ### [Certificate Signed by Unknown Authority](https://octelium.com/docs/octelium/latest/overview/quick-install#certificate-signed-by-unknown-authority) If your `octelium login` command produces the following error: `1gRPC error Unavailable: connection error: desc = "transport: authentication handshake failed: tls: failed to verify certificate: x509: certificate signed by unknown authority"` Then you still have not set your TLS certificate via `octops cert` or `kubectl create secret tls` as shown above. You can proceed with the command just by setting the `OCTELIUM_INSECURE_TLS` or `OCTELIUM_DEV` environment variables to `true` as follows: `1export OCTELIUM_INSECURE_TLS=true 2octelium login --domain --auth-token ` However, it's recommended to set your own TLS certificate that's signed by a real CA such as Let's Encrypt as soon as possible. ### [Connection Refused](https://octelium.com/docs/octelium/latest/overview/quick-install#connection-refused) If your `octelium login` shows something as follows: `1rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp ... connect: connection refused"` From your _Cluster_ VM itself, verify that the Octelium ingress is actually running and bound to an external IP address as follows: `1export KUBECONFIG="/etc/rancher/k3s/k3s.yaml" 2kubectl get svc -n octelium octelium-ingress-dataplane` The `EXTERNAL-IP` field of the output that command should be set to your actual main IP address and does not have a `` or an empty value. If your _Cluster_ VM is behind NAT, you might need to uninstall the _Cluster_ via `./install-cluster.sh --uninstall` and re-install by adding the `--nat` flag as shown above. You can also try to curl `curl -k https://` to verify that the Octelium ingress is running. The `-k` flag is used here in order to ignore the TLS certificate errors since the initial TLS certificate is a self-signed certificate that should be replaced with `octops cert` or `kubectl create secret tls` as shown above. That `curl` command should output an HTML of the login web page. ### [Unable to Access Services](https://octelium.com/docs/octelium/latest/overview/quick-install#unable-to-access-services) note This section assumes that you can successfully access the _Cluster_ via the `octelium` and `octeliumctl` commands (e.g. `octeliumctl get service`, `octelium status`, etc...) and you are also able to access the _Cluster_'s web login page located at the URL `https://` via your browser. If you can successfully connect to the _Cluster_ via `octelium connect` but cannot access any _Service_ at all when connected even though you can access public _Services_ through your web browser, then this might be a NAT-related issue in your _Cluster_ VM/machine. This problem shows up, once connected via `sudo -E octelium connect`, when you try to access the `demo-nginx` _Service_ that is created by default during the _Cluster_ installation via `curl demo-nginx` but you end up getting a timeout error such as `Could not resolve host: demo-nginx`. You can verify this is a NAT-related issue in your VM as follows: * First verify that you can actually successfully access that `demo-nginx` _Service_ via your web browser. You can go to portal at `https://portal.` and visit that _Service_ from the list of _Service_ shown. If you can not access `https://portal.` or `https://demo-nginx.` then this is not a NAT-related issue. * Now open a terminal and connect to the _Cluster_ as a non-root unprivileged OS user as follows: `1 2# Enable debugging in the octelium CLI 3export OCTELIUM_DEV=true 4 5 6# Now connect as a normal/non-root OS user 7# And map the demo-nginx Service to localhost:9090 8octelium connect -p demo-nginx:9090 9 10# Now access it from another terminal 11curl localhost:9090` You should be getting the same timeout error in this unprivileged mode (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect#tunnel-implementation) ). If you can successfully curl the _Service_ now in the unprivileged mode then this is not a NAT-related issue, but most probably a DNS-related issue on your own client-side machine. * Now, from your _Cluster_ VM/machine, obtain your main IP address as follows: `1echo $(ip addr show "$(ip route show default | awk '/default/ {print $5}')" | grep "inet " | awk '{print $2}' | cut -d'/' -f1)` This should be a public IP address (read more in Wikipedia [here](https://en.wikipedia.org/wiki/Private_network) ) if you installed the _Cluster_ via `./install-cluster.sh --domain ` as shown in the beginning of this guide. If you obtained a private IP address as an output to the command above, then the solution to this problem is to add the `--nat` flag (read more the advanced installation options section [here](https://octelium.com/docs/octelium/latest/overview/quick-install#advanced-installation-options) ) as follows: `1# First uninstall the currently installed Cluster 2./install-cluster.sh --uninstall 3# Then re-install the Cluster 4./install-cluster.sh --domain --nat` If you want to install the _Cluster_ on some internal virtual machine inside an internal/private network (e.g. microVM inside your host) for internal testing purposes, then add also the `--force-machine-ip` as follows: `1./install-cluster.sh --domain --nat --force-machine-ip` note Still having problems trying to install the _Cluster_? Join our [Discord](https://octelium.com/external/discord) , [Slack](https://octelium.com/external/slack) or [Reddit](https://www.reddit.com/r/octelium/) channels or open a GitHub [issue](https://github.com/octelium/octelium/issues) for support. [Upgrade the Cluster](https://octelium.com/docs/octelium/latest/overview/quick-install#upgrade-the-cluster) ------------------------------------------------------------------------------------------------------------ You can later upgrade your Octelium _Cluster_ via the `octops upgrade` command (read more [here](https://octelium.com/docs/octelium/latest/install/cluster/upgrade) ) from within your VPS/VM as follows: `1export KUBECONFIG="/etc/rancher/k3s/k3s.yaml" 2 3# First you might want to check for available upgrades via --check flag 4octops upgrade --check 5 6# Now you can actually upgrade the Cluster 7octops upgrade ` [Uninstall the Cluster](https://octelium.com/docs/octelium/latest/overview/quick-install#uninstall-the-cluster) ---------------------------------------------------------------------------------------------------------------- If you ever want to uninstall the _Cluster_ later for whatever reason, including to re-install the _Cluster_, you can simply do that using the same installation script via the `--uninstall` flag as follows: `1./install-cluster.sh --uninstall` This command removes the Octelium _Cluster_ and its underlying k3s Kubernetes cluster. --- # First Steps to Managing the Cluster - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links First Steps to Managing the Cluster =================================== An Octelium _Cluster_ is designed to be managed similarly to Kubernetes clusters. The main way to manage an Octelium _Cluster_ is via the `octeliumctl` CLI. If you're accustomed to `kubectl`, you will feel right at home very quickly as it follows the same declarative philosophy enabling you to define your resources in one or more `yaml` files and by just using a single command (i.e. `octeliumctl apply`) you can apply all changes to the _Cluster_ and synchronize its state (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview) ). The declarative way enables you to grow your _Cluster_ resources very easily in an organized and trackable way that can be stored in a Git repository where you can effortlessly update/rollback your _Cluster_ state with a single command. note Check out the quick installation guide [here](https://octelium.com/docs/octelium/latest/overview/quick-install) to quickly install an Octelium _Cluster_ on any cloud VM/VPS. [Creating our first Service](https://octelium.com/docs/octelium/latest/overview/management#creating-our-first-service) ----------------------------------------------------------------------------------------------------------------------- Each protected resource is represented in the _Cluster_ by a _Service_. A _Service_ is implemented by an identity-aware proxy (IaP) called [_Vigil_](https://octelium.com/docs/octelium/latest/reference/components#vigil) abstracting all dynamic network-layer details of the protected resource (i.e. upstream) behind it and is capable of providing secure secretless access that eliminates sharing and managing L7 credentials such as API keys and database passwords (read more about secretless access [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ) for various protocols including HTTP, SSH, PostgreSQL, MySQL, among others besides protecting generic TCP/UDP-based applications (read more about _Service_ modes [here](https://octelium.com/docs/octelium/latest/management/core/service/overview#mode) ). The upstream of the _Service_ can be: * An internal resource running in any private network (e.g. on-prem, private cloud, your own laptop behind a NAT, etc...) which can be a static IPv4 or IPv6 address or a FQDN with dynamic endpoints as is the case with Kubernetes services for example. Furthermore, you can use an internal resource directly accessible from the private network where the Octelium _Cluster_ (and its underlying Kubernetes cluster) is running. * A publicly protected resource such as SaaS APIs, databases and SSH servers. See some examples ([here](https://octelium.com/docs/octelium/latest/management/guide/service/http/api-gateway) and [here](https://octelium.com/docs/octelium/latest/management/guide/service/databases/neon) ). * Octelium can also automatically deploy, scale and secure access for your containerized apps and microservices to be served as _Services_ (read more about managed containers [here](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers) ). We are going to define our first _Service_ with the name `first-service` whose upstream is the public URL `https://www.google.com`: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: HTTP 6 config: 7 upstream: 8 url: https://www.google.com` Serving the public website `https://www.google.com` as a _Service_, however, isn't particularly useful, beyond demonstrating that a _Service_ can serve public or internal/private FQDNs that might point to dynamic upstreams with changing IP addresses—a capability remote access VPNs lack since they operate at the network layer/layer-3. We can do something a little more interesting, like deploying the `nginx` container image and serve it as a _Service_ (read more about managed containers [here](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers) ) as follows: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: HTTP 6 config: 7 upstream: 8 container: 9 port: 80 10 image: nginx:latest 11 replicas: 3` A _Service_ can also provide _secretless_ access for the authorized _Users_ to an upstream that requires an application-layer (L7) credential such as HTTP bearer access tokens (read more about secretless access [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ). Octelium's application-layer awareness allows you to simply eliminate the need to manage and distribute such credentials, which are often long-lived and over-privileged in many practical cases, at any scale. Here is an example: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: HTTP 6 config: 7 upstream: 8 url: https://api.openai.com 9 http: 10 path: 11 addPrefix: /v1 12 auth: 13 bearer: 14 fromSecret: openai-api-key` note The highlighted `openai-api-key` is the name of a _Secret_ that actually represents the API access token, referenced in the _Service_ by its name in order to not store sensitive data along with other _Cluster_ configurations which can be stored in git repositories for example (read more about creating _Secrets_ [here](https://octelium.com/docs/octelium/latest/management/core/secret) ). note You can read more about HTTP-specific configuration that includes request/response header manipulation, JSON schema validation, caching, rate limiting, Lua scripting, Envoy ExtProc and dynamic direct responses [here](https://octelium.com/docs/octelium/latest/management/core/service/http) and [here](https://octelium.com/docs/octelium/latest/management/core/service/http-plugins) . Octelium's application-layer awareness is not exclusive to `HTTP`\-based _Services_. You can also define an `SSH` _Service_ that provides secretless access without having to distribute and share SSH passwords or private keys (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/ssh#secretless-access) ). Here is an example: `1kind: Service 2metadata: 3 name: ssh1 4spec: 5 mode: SSH 6 port: 2022 7 config: 8 upstream: 9 url: ssh://address-to-host 10 ssh: 11 user: root 12 auth: 13 password: 14 fromSecret: ssh1-password 15 upstreamHostKey: 16 key: ssh-rsa AAAA...` note Octelium also supports an "embedded SSH" mode, where you can serve SSH via an embedded SSH server that is running from within the `octelium` client without having to rely on an existing SSH server on the host. This can be especially useful for constrained environments such as containers and IoT fleets (read more about the embedded SSH mode [here](https://octelium.com/docs/octelium/latest/management/core/service/embedded-ssh) ). note Octelium currently supports several L7 aware modes: [SSH](https://octelium.com/docs/octelium/latest/management/core/service/ssh) , [PostgreSQL](https://octelium.com/docs/octelium/latest/management/core/service/postgres) , [MySQL](https://octelium.com/docs/octelium/latest/management/core/service/mysql) , [DNS](https://octelium.com/docs/octelium/latest/management/core/service/dns) , [gRPC](https://octelium.com/docs/octelium/latest/management/core/service/http#grpc-mode) , [Web](https://octelium.com/docs/octelium/latest/management/core/service/http#web-app-mode) , [Kubernetes](https://octelium.com/docs/octelium/latest/management/core/service/kubernetes) in addition to the raw [TCP](https://octelium.com/docs/octelium/latest/management/core/service/tcp) and [UDP](https://octelium.com/docs/octelium/latest/management/core/service/udp) modes. And you can also serve any remote upstream from the host of any connected _User_ to the _Cluster_ (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect#serving-services) ) as follows: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: HTTP 6 config: 7 upstream: 8 url: https://www.google.com 9 user: john` This allows you to serve upstreams running behind NAT from anywhere (e.g. private clouds, on-prem, your own laptop, IoT devices, etc...). You can see a more detailed example [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/open-source-self-hosted-ngrok-alternative) . Now, to actually apply the creation of our _Service_ `first-service`, we use the `octeliumctl apply` command (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview#applying-changes) ) as follows: `1octeliumctl apply --domain /path/to/octelium/config/dir` note If you're familiar with Kubernetes, you might have noticed the YAML visual resemblance between Octelium resources and Kubernetes resources and now you might be wondering whether Octelium resources are just Kubernetes resources or simply CRDs. The answer is no. Octelium and its resources are completely separate from Kubernetes. Octelium has its own gRPC-based [_API Server_](https://octelium.com/docs/octelium/latest/reference/components#api-server) , and its resources are stored in the PostgreSQL data store via the [_Resource Server_](https://octelium.com/docs/octelium/latest/reference/components#resource-server) . Since the Octelium CLIs (i.e. `octelium` and `octeliumctl`) are designed to work with multiple _Clusters_ as defined by their own domains, you will have to add the `--domain` flag to every command. It's much easier to define the domain as an environment variable in your shell once and then use any command without having to add the `--domain` flag as follows: `1export OCTELIUM_DOMAIN=` Or in Windows PowerShell as follows: `1$env:OCTELIUM_DOMAIN = ""` Now let's connect to our _Cluster_ as follows: `1# Connect in background via the detached mode 2octelium connect -d 3# OR in foreground 4sudo -E octelium connect` note In Windows, you need to run your PowerShell as administrator as equivalent of `sudo` in Linux and macOS. In Windows 11, however, `sudo` is natively supported. Now that we're connected to the _Cluster_, we can access the _Service_ `first-service` simply using any tool that can talk HTTP, let's try `curl` for example as follows: `1curl first-service 2# This is equivalent to 3curl first-service.local.` note Why does this hostname `first-service` work? Simply put, when you connect to a _Cluster_ via the command `octelium connect`, Octelium automatically configures your machine DNS and adds the suffix `.local.`, which is the common suffix for all _Services_ in the _Cluster_, to your machine's DNS search domains so you don't have to type the entire private FQDN yourself. You can also run `octelium connect` as a completely unprivileged process and map the _Service_ `first-service` to a localhost port (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect#mapping-services-to-host) ) as follows: `1octelium connect -p first-service:8080` In the above example, we mapped the _Service_ to the localhost port `8080`. Now we can access it as follows: `1curl localhost:8080` note You can read more about connecting to _Clusters_ via the `octelium` CLI and its more advanced options [here](https://octelium.com/docs/octelium/latest/user/cli/connect) . So far, in order to access our _Service_ `first-service`, _Users_ will have to use the `octelium` CLI and connect to the _Cluster_ first. Octelium, however, also supports the clientless BeyondCorp mode, which enables you to securely expose an HTTP-based _Service_ publicly in order to be accessed by authorized `HUMAN` _Users_ via their browsers and even by `WORKLOAD` _Users_ through standard OAuth2 client credentials authentication flow (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/clientless) ). You can very simply do so as follows: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: WEB 6 isPublic: true 7 config: 8 upstream: 9 container: 10 port: 80 11 image: nginx:latest` And now, authorized _Users_ can publicly access the _Service_ via their browsers at the public URL `https://first-service.` Octelium can also fully expose a _Service_ for anonymous access. This allows you to effectively use Octelium as a self-hosted PaaS or a hosting platform where you can publicly expose HTTP-based _Services_ to the public internet. Such _Services_' upstreams might be running anywhere or be deployed as managed containers as we have seen earlier. You can read more about the anonymous access mode [here](https://octelium.com/docs/octelium/latest/management/core/service/anonymous-access) . Here is an example: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: WEB 6 isPublic: true 7 isAnonymous: true 8 config: 9 upstream: 10 container: 11 port: 80 12 image: nginx:latest` You can also use dynamic configuration in order to, for example, route to different upstreams and/or set different upstream credentials mapping to different upstream accounts and permissions, set different request/response headers, etc... depending on the request's identity and/or context (read more about dynamic configuration [here](https://octelium.com/docs/octelium/latest/overview/management/dynamic-config.mdx) ). Here is a simple example that can be used for an API gateway use case (read more [here](https://octelium.com/octelium/latest/management/guide/service/api-gateway/index.mdx) ): `1kind: Service 2metadata: 3 name: my-api 4spec: 5 mode: HTTP 6 isPublic: true 7 dynamicConfig: 8 configs: 9 - name: v1 10 upstream: 11 url: https://apiv1.example.com 12 - name: v2 13 upstream: 14 url: https://apiv2.example.com 15 rules: 16 - condition: 17 match: ctx.request.http.path.startsWith("/v1") 18 configName: v1 19 - condition: 20 match: ctx.request.http.path.startsWith("/v2") 21 configName: v2` Dynamic configuration can also be used for other layer-7 aware modes such as `SSH`, `POSTGRES` and `MYSQL` as well as for `TCP` and `UDP`. For example, you can dynamically force certain _Users_ to log in as certain SSH users based on identity or context via policy-as-code. For PostgreSQL or MySQL, you can enforce _Users_ to use certain database users/passwords as well as different databases and even upstreams based on identity and context. [Creating a User](https://octelium.com/docs/octelium/latest/overview/management#creating-a-user) ------------------------------------------------------------------------------------------------- There are 2 types of _Users_ (You can read in detail about _User_ management [here](https://octelium.com/docs/octelium/latest/management/core/user) ): `HUMAN` _Users_ and `WORKLOAD` _Users_ which can be used by non-human entities (e.g. servers, VMs and microVMs, containers, applications, IoT devices, etc...). Both _User_ types can use the private client-based ZTNA mode, which acts as a zero-config VPN from the _User_'s perspective where _Users_ can address _Services_ via stable private FQDNs and hostnames assigned by the _Cluster_. Both _User_ types can also securely access publicly exposed HTTP-based _Services_ via the clientless, public BeyondCorp mode (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/clientless) ) as follows: * `HUMAN` _Users_ can access web-based _Services_ via their browsers without having to install clients on their machines. * `WORKLOAD` _Users_ can use the OAuth2 client credentials flow enabling your applications written in any programming language to access any publicly exposed HTTP-based _Service_ (e.g. HTTP and gRPC APIs, Kubernetes API servers, etc...) solely via standard OAuth2 libraries without having to use any special SDKs or install any clients (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#oauth2-client-credentials) ). Moreover, Golang-based applications can use the official Golang SDK (read more [here](https://octelium.com/docs/octelium/latest/management/guide/octelium-go) ) to control the _Cluster_ and access its _Services_. We are now going to create our first _User_ for a friend in order to be able to connect to our _Cluster_ and access our _Service_ `first-service`. As always, we add a new `yaml` file, in this example `users.yaml`, in the same directory (i.e. `/path/to/octelium/config/dir`) dedicated to _Users_. Now we can define our _User_ `john` as follows: `1kind: User 2metadata: 3 name: john 4spec: 5 type: HUMAN 6 email: john@example.com` And to actually apply the creation of our _User_, we use the `octeliumctl apply` command as follows: `1octeliumctl apply /path/to/octelium/config/dir` [User Authentication](https://octelium.com/docs/octelium/latest/overview/management#user-authentication) --------------------------------------------------------------------------------------------------------- `HUMAN` _Users_ can use their emails to authenticate to the _Cluster_ via web browsers using _IdentityProviders_. There are currently 3 methods: * GitHub OAuth _IdentityProvider_ as shown in detail [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#github-oauth2) * OpenID Connect _IdentityProviders_ (e.g. Okta, Auth0, etc...) as shown [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#openid-connect) . * SAML 2.0 _IdentityProviders_ (e.g. Okta, Entra ID, etc...) as shown [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#saml-20) . note You can also read detailed guides on how to self-host FOSS identity providers (IdPs) on the same Kubernetes cluster that is running the Octelium _Cluster_ for [Keycloak](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/keycloak-helm-self-host) , [Authentik](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/authentik-helm-self-host) and [Dex](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/dex-helm-self-host) and use them to create an OpenID Connect _IdentityProvider_ that can be used to login into the _Cluster_. Furthermore, `HUMAN` _Users_ can register their FIDO2 _Authenticators_ (e.g. Yubikeys) in order to natively login later via Passkey (read more [here](https://octelium.com/docs/octelium/latest/management/core/authenticator#passkey-login) ). note You can read more about _Authenticators_ and WebAuthn/TOTP MFA as shown [here](https://octelium.com/docs/octelium/latest/management/core/authenticator) . For `WORKLOAD` _Users_, they can authenticate themselves via the `octelium login` or `octeliumctl login` commands using various ways: * Authentication token _Credentials_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#authentication-tokens) ) * OAuth2 client credentials (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#oauth2-client-credentials) ) * "Secretless" OpenID Connect identity assertions (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#oidc-assertion) ). * Access tokens directly issued and used as bearer authentication tokens (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#access-tokens) ). A _User_ can interact with the _Cluster_ and access its _Services_ **only** through a valid _Session_ that is automatically created by the _Cluster_ upon a valid authentication via an authentication token, OAuth2 client credential authentication, or an _IdentityProvider_. A _User_ needs to periodically re-authenticate to keep the _Session_ valid until it eventually expires. You can read more about _Session_ management [here](https://octelium.com/docs/octelium/latest/management/core/session) . [Access Control](https://octelium.com/docs/octelium/latest/overview/management#access-control) ----------------------------------------------------------------------------------------------- Now, while our friend `john` can actually connect to our _Cluster_, he still cannot access the _Service_ `first-service` unless we explicitly allow him via a _Policy_. For example, we can allow `john` to access everything in our _Cluster_ by attaching the `allow-all` _Policy_ as follows: `1kind: User 2metadata: 3 name: john 4spec: 5 type: HUMAN 6 email: john@example.com 7 authorization: 8 policies: ["allow-all"]` note This `allow-all` _Policy_ is automatically created during the _Cluster_ installation and you can modify/delete it, whenever you want to. Allowing `john` to access everything in the _Cluster_, however, does not sound like a very good idea since we seek to only grant access our `first-service` _Service_. For example, we can, instead, define an _inline_ _Policy_ in our _Service_ to allow anybody whose email belongs to our domain `example.com` to access `first-service` as follows: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: HTTP 6 config: 7 upstream: 8 url: https://example.com 9 authorization: 10 inlinePolicies: 11 - spec: 12 rules: 13 - effect: ALLOW 14 condition: 15 match: ctx.user.spec.email.endsWith("@example.com")` As you can see, you are free to either define your access control rules through inline _Policies_ or standalone, reusable _Policies_ that can be attached to any _Service_, _Namespace_, _User_, _Group_, _Device_ or _Session_. Here is how to re-define the above inline _Policy_ as a standalone _Policy_ that can be used and attached by other resources: `1kind: Policy 2metadata: 3 name: first-policy 4spec: 5 rules: 6 - effect: ALLOW 7 condition: 8 match: ctx.user.spec.email.endsWith("@example.com")` Now we attach it to our _Service_ as follows: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: HTTP 6 config: 7 upstream: 8 url: https://example.com 9 authorization: 10 policies: ["first-policy"]` We can also define a _Policy_ for a whole set of _Users_. This is what a _Group_ is for, among other functionalities (read more about _Groups_ [here](https://octelium.com/docs/octelium/latest/management/core/group) ). Let's define our first _Group_ `friends` and attach `john` to it. `1kind: Group 2metadata: 3 name: friends 4spec: 5 authorization: 6 policies: ["first-policy"]` Now let us add `friends` as one of `john`'s _Groups_ as follows: `1kind: User 2metadata: 3 name: john 4spec: 5 type: HUMAN 6 groups: ["friends"]` Now, any _User_ belonging to the `friends` _Group_ will be automatically subjected to all of its _Policies_ and inline _Policies_' rules. Octelium enables you to seamlessly define dynamic, fine-grained L7-aware _Policies_. For example, you can control access based on the HTTP request path, method, query parameters, and even serialized JSON body content (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http#access-control) ). Here is an example: `1kind: Service 2metadata: 3 name: first-service 4spec: 5 mode: HTTP 6 config: 7 upstream: 8 url: https://example.com 9 authorization: 10 inlinePolicies: 11 - spec: 12 rules: 13 - effect: ALLOW 14 condition: 15 all: 16 of: 17 - match: ctx.request.http.method in ["GET", "POST", "PUT", "DELETE"] 18 - match: ctx.request.http.path.startsWith("/apis") 19 - match: ctx.request.http.uri == "/apis/users?name=john" 20 - match: ctx.request.http.queryParams.name == "john" 21 - match: ctx.request.http.headers["x-custom-header"] == "this-value" 22 - match: ctx.request.http.scheme == "http" 23 - match: string(ctx.request.http.body).toLower().contains("value1") 24 # JSON body map 25 - match: ctx.request.http.bodyMap.key1 == "value1"` Access control is the essence of the zero trust security model. This example is just the simplest use case of what you can do with Octelium's scalable, identity-based, fine-grained, context-aware, L7-aware access control system. Octelium supports defining _Policy_ rules in Common Expression Language (CEL) and Open Policy Agent (OPA), rule priorities, nested conditions and extending access control by adding attributes to your different resources (e.g. _Users_, _Groups_, _Services_, etc...) from information provided by external tools such as IAM platforms, SIEM tools, threat intelligence tools, incident alerting and on-call management tools, etc.... You can read more in detail about _Policies_ and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy) . [What Now?](https://octelium.com/docs/octelium/latest/overview/management#what-now) ------------------------------------------------------------------------------------ This was just a quick guide to show you the main different features of Octelium. Octelium's architecture is designed to be flexible enough to be used as a Zero Trust Network Access (ZTNA) solution, a complete solution for secure tunnels, an API gateway (read more [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/api-gateway) ), an AI gateway (read more [here](https://octelium.com/docs/octelium/latest/management/guide/service/ai/ai-gateway) ) and even can be used as a more advanced Kubernetes ingress/load balancer alternative as well as a self-hosted PaaS-like deployment and hosting platform to deploy, scale and provide secure or public anonymous access for your containerized applications such as Vite.js/Next.js/Astro web apps (see more [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/nextjs-vite) ). --- # Cluster Components - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Cluster Components ================== ### [Vigil](https://octelium.com/docs/octelium/latest/reference/components#vigil) _Vigil_ is the identity-aware proxy (IaP) that intercepts requests sent to the actual protected resource and decides whether the the request should be accepted or denied according to the relevant _Policies_ of that request (read more about _Policies_ and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy) ). _Vigil_ can be called a policy enforcement point (PEP) as the policy decision is actually made in another component called [_Octovigil_](https://octelium.com/docs/octelium/latest/reference/components#octovigil) . ### [Octovigil](https://octelium.com/docs/octelium/latest/reference/components#octovigil) _Octovigil_ is a policy decision point (PDP) that actually does the authentication and authorization. For every new request sent to the identity-aware proxy, [_Vigil_](https://octelium.com/docs/octelium/latest/reference/components#vigil) , the request information (e.g. private WireGuard IP address, application-layer information such as HTTP headers, etc...) is forwarded to _Octovigil_ in order to first identify the _Session_ and its _User_, and then to authorize the request according the _Policies_ relevant to the request (read more about _Policies_ and access control [here](https://octelium.com/docs/octelium/latest/management/core/policy) ). ### [API Server](https://octelium.com/docs/octelium/latest/reference/components#api-server) Octelium's _API Server_ is the interface using which _Users_ can interact with the _Cluster_. The _API Server_ is a gRPC server that implements various APIs (or "services" according to gRPC nomenclature). In order to interact with the API Server, _Users_ must first obtain a valid [_Session_](https://octelium.com/docs/octelium/latest/reference/resources#session) . The _API Server_ currently implements 2 APIs: * **The User API**: Used by any _User_ mainly to connect to/disconnect from the _Cluster_ and discover its _Services_. * **The Core API**: Used by "administrator" _Users_ to control the _Cluster_'s core resources such as _Services_, _Users_, _Groups_, _Sessions_, _Devices_, etc.... note Octelium deliberately does not have a notion of "administrator" or "superuser" _Users_ by default. However, you can explicitly write your _Policies_ to allow certain _Users_ to have access to all or certain methods of the Core API effectively making them "administrators". ### [Gateway Agent](https://octelium.com/docs/octelium/latest/reference/components#gateway-agent) As the name implies, the _Gateway Agent_ is an agent that runs on every Kubernetes node that is part of the data-plane in the Octelium _Cluster_ (i.e. [_Gateway_](https://octelium.com/docs/octelium/latest/reference/resources#gateway) ) and it is deployed as a Kubernetes [daemonset](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) . _Gateway Agents_ are responsible for maintaining the _Gateways_ and their WireGuard/QUIC network interfaces. _Gateways_ are where the tunneled WireGuard/QUIC traffic is terminated and from there the inner traffic is transported to the pod running the destination _Service_. ### [Resource Server](https://octelium.com/docs/octelium/latest/reference/components#resource-server) The _Resource Server_ is a gRPC server that acts as interface between the various _Cluster_ components (e.g. _Nocturne_, _API Server_, etc...) and the primary storage backend, currently PostgreSQL, that stores the _Cluster_ resource objects. The _Resource Server_ offers a CRUD-like API for the different _Cluster_ components to control the _Cluster_ resource objects in a unified and clean way. ### [Nocturne](https://octelium.com/docs/octelium/latest/reference/components#nocturne) _Nocturne_ is the main controller of the _Cluster_'s resources which watches for changes submitted to the Resource Server and acts accordingly (e.g. when you create a new _Service_, _Nocturne_ creates the kubernetes deployment/daemonset that contains the [_Vigil_](https://octelium.com/docs/octelium/latest/reference/components#vigil) instance(s) implementing that _Service_). It also does various management and garbage collection operations for the various resource objects in the _Cluster_. ### [DNS Server](https://octelium.com/docs/octelium/latest/reference/components#dns-server) The _Cluster_ private _DNS Server_ resolves the private FQDN for the _Cluster_'s _Services_. The _DNS Server_ itself runs as a typical _Service_ that is accessible by all _Users_. For the case of _Services_ implemented by multiple replicas (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/overview#scaling) ), the _DNS Server_ automatically does round robin load balancing among the different addresses of such _Services_. ### [Auth Server](https://octelium.com/docs/octelium/latest/reference/components#auth-server) _Auth Server_ is the _Cluster_'s authentication server. It implements the _Auth_ gRPC API for the _Users_ to authenticate themsleves via authentication token _Credentials_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#authentication-tokens) ), re-authenticate their _Sessions_ via _Authenticators_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#authenticators) ), or web identity providers (IdPs) such as Open ID Connect and SAML 2.0 providers (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#web-identity-providers) ). ### [Portal](https://octelium.com/docs/octelium/latest/reference/components#portal) _Portal_ is a `WEB` _Service_ that is exposed publicly (read more about the public BeyondCorp mode [here](https://octelium.com/docs/octelium/latest/management/core/service/clientless) ). _Portal_ is accessible by all `HUMAN` _Users_ and acts as a dashboard for the _Users_ to discover the _Cluster_'s _Services_. ### [Ingress](https://octelium.com/docs/octelium/latest/reference/components#ingress) _Ingress_ is the proxy sitting between the external world (i.e. downstreams coming from the internet), and some Octelium components (currently the _API Server_ and _Portal_). Also _Ingress_ acts as a transparent proxy between _Users_ and BeyondCorp _Services_ (read more about [here](https://octelium.com/docs/octelium/latest/management/core/service/clientless) ). _Ingress_ actually is comprised of two components: the data-plane component which is represented by [Envoy](https://www.envoyproxy.io/) proxies and a control-plane component that controls the Envoy proxies. ### [Genesis](https://octelium.com/docs/octelium/latest/reference/components#genesis) Genesis is the installer that runs from within the hosting Kubernetes cluster as a Kubernetes [job](https://kubernetes.io/docs/concepts/workloads/controllers/job/) to install (read more [here](https://octelium.com/docs/octelium/latest/install/cluster/installing-cluster) ) and upgrade (read more [here](https://octelium.com/docs/octelium/latest/install/cluster/upgrade) ) the Octelium _Cluster_. --- # Scopes - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Scopes ====== Octelium scopes are very similar to OAuth2 scopes. They act as a simple self-imposed authorization mechanism that can be used to further limit the scope of permissions that are already granted by the _Cluster_ via its _Policies_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy) ). It is extremely important to understand that scopes are not a zero trust access control mechanism: they are voluntarily chosen by the _Users_ themselves during the authentication process, not mandated by the _Cluster_'s _Policies_. That said, once set, they are enforced by the _Cluster_ on every request, which can meaningfully shrink the attack surface and prevent unauthorized access in case of a _Session_ access token compromise. Scopes are entirely optional. _Users_ are not required to use them, and _Cluster_ administrators must never treat scopes as a substitute for _Policies_. You can choose to apply one or more scopes. Every scope is simply a string that represents a resource permission. Once your scopes are set for a _Session_ during the authentication process, your _Session_ cannot access anything outside the permissions granted by its scopes even if allowed by the _Cluster_ _Policies_. There are currently 2 types of scopes: _Service_ scopes and API scopes. ### [Service Scopes](https://octelium.com/docs/octelium/latest/user/scope#service-scopes) _Service_ scopes enable you to restrict access to certain _Services_ or _Namespaces_ of _Services_. An individual _Service_ has the scope `service:.` or directly `service:` if it belongs to the `default` _Namespace_. `1export OCTELIUM_DOMAIN=example.com 2octelium login --scope="service:svc1"` An entire _Namespace_ of _Services_ has the scope `service:/*`. Here is an example of adding the _Namespace_ `ns1`: `1export OCTELIUM_DOMAIN=example.com 2octelium login --scope="service:ns1/*"` ### [API Scopes](https://octelium.com/docs/octelium/latest/user/scope#api-scopes) **The _Cluster_ API** scopes enable you to restrict access to certain APIs. For example, you might want to only access the _Core_ API: `1export OCTELIUM_DOMAIN=example.com 2octelium login --scope="api:core"` You can also choose certain methods in a certain API. For example, you might only want to use the `CreateUser` method in the _Core_ API: `1export OCTELIUM_DOMAIN=example.com 2octelium login --scope="api:core.MainService/CreateUser"` Finally, you can also have multiple scopes by using the `--scope` flag multiple times. Here is an example: `1export OCTELIUM_DOMAIN=example.com 2octelium login --scope="api:core.MainService/ListService" --scope="service:nginx" --scope="service:production/*"` --- # How Octelium Works - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links How Octelium Works ================== [Introduction](https://octelium.com/docs/octelium/latest/overview/how-octelium-works#introduction) --------------------------------------------------------------------------------------------------- Octelium is a **unified** zero trust architecture (ZTA) that is built to be generic enough to operate as a zero-config remote access VPN, a Zero Trust Network Access (ZTNA)/BeyondCorp platform, ngrok alternative, an API gateway, an AI/LLM gateway, an infrastructure for MCP gateways and A2A architectures/meshes, a PaaS-like platform, a Kubernetes gateway/ingress alternative and even as a homelab infrastructure. A single Octelium system is called a _Cluster_ and is defined and addressed by its domain (e.g. `example.com`, `octelium.example.com`, etc...). The _Cluster_ provides secure secretless access, for _Users_, both humans and workloads used by non-human entities, to any private/internal resource behind NAT in any environment as well as to publicly protected resources such as SaaS APIs and databases, via identity-based, context-aware, application-layer (L7)-aware access control on a per-request basis. An Octelium _Cluster_ runs on top of Kubernetes. The _Cluster_ can run on a single-node Kubernetes cluster that is installed on top of a single cheap EC2 or DigitalOcean VM instance (see the quick installation guide [here](https://octelium.com/docs/octelium/latest/overview/quick-install) ). In a typical production-grade environment, however, the _Cluster_ should typically run on top of a scalable on-prem or a managed Kubernetes cluster. It's noteworthy that even though Octelium operates on top of Kubernetes, you don't really need to have experience with Kubernetes to manage, operate or use Octelium. Each resource that is protected by the _Cluster_ is represented by a _Service_. A _Service_ is implemented by an identity-aware proxy (IaP) abstracting all dynamic network-layer details of the protected resource (i.e. upstream) behind it. _Users_ access protected resources through _Services_ via two zero-trust network access (ZTNA) modes: * **Client-based** where _Users_ use a lightweight client (namely the `octelium` CLI tool) to connect to the _Cluster_ through WireGuard tunnels (as well as QUIC-based tunnels) and access _Services_. This mode simply acts as a zero-config VPN from the _User_'s perspective where _Users_ can address _Services_ via stable private FQDNs and hostnames assigned by the _Cluster_. You can read more in detail about connecting to _Clusters_ [here](https://octelium.com/docs/octelium/latest/user/cli/connect) . * **Clientless** (also called BeyondCorp) where _Users_ can access _Services_ through an internet facing reverse proxy without the need for any client to be installed at their side. Not only does this mode enable human _Users_ to access web-based _Services_ via their browsers, but it also enables workload _Users_ to directly access any HTTP-based _Service_ such as APIs, Kubernetes clusters, gRPC services, etc... via standard OAuth2 client credentials flow (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#oauth2-client-credentials) ) as well as directly via bearer access tokens (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#access-tokens) ). In other words, your applications written in any programming languages can securely access such _Services_ without having to use any additional client or special SDK. You can read more about the clientless BeyondCorp mode [here](https://octelium.com/docs/octelium/latest/management/core/service/clientless) . Moreover, Octelium can also provide public anonymous access (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/anonymous-access) ) that can be useful for hosting use cases, for example. The _Cluster_ is designed to be managed in a centralized, declarative as well as programmatic way that is very similar to the way Kubernetes itself is managed. The _Cluster_ administrators can use one command (namely `octeliumctl apply`) to (re)produce the entire state of the _Cluster_, enabling the _Cluster_'s administrators to define the _Cluster_ resources in YAML files and store them in Git repositories where the entire state can be updated/rolled back effortlessly in a similar way to other GitOps friendly systems such as Kubernetes (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview) ). The _Cluster_ consists of various [components](https://octelium.com/docs/octelium/latest/reference/components) which can be classified into a data-plane and a control-plane. In a typical production multi-node Kubernetes environment, the _Cluster_ should have at least one Kubernetes node dedicated to the control-plane. The _Cluster_ uses one or more kubernetes nodes for its data-plane. Each data-plane Kubernetes node is used as a [_Gateway_](https://octelium.com/docs/octelium/latest/reference/resources#gateway) by the _Cluster_ acting as a host for the _Services_ running on it. [Data Plane Overview](https://octelium.com/docs/octelium/latest/overview/how-octelium-works#data-plane-overview) ----------------------------------------------------------------------------------------------------------------- Human _Users_ can authenticate themselves using OpenID Connect or SAML IdP _IdentityProviders_ (read more about _IdentityProviders_ [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers) ) and workload _Users_ can authenticate themselves via authentication tokens (read more [here](https://octelium.com/docs/octelium/latest/management/core/credential#authentication-tokens) ) or federated OpenID Connect-based assertions (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#oidc-assertion) ). Once authenticated, a _Session_ is created for that _User_ and is tied to a short-lived (4 hours by default but it is configurable via the _ClusterConfig_) access token credential representing the _Session_, which enables access to protected resources through _Services_ if the request is authorized (read more [here](https://octelium.com/docs/octelium/latest/management/core/session) ). Now let's understand how the flow of a request from a _User_ to a protected resource through its _Service_ is done. User Human Browser Workload OAuth2 / Bearer octelium CLI client-based Octelium Cluster Ingress Gatewayk8s node Service · apiService · sshService · db Upstream SaaS API / DB directly reachable Remote upstream via a connected User Managed container PaaS on Kubernetes ### [From the User to the Service](https://octelium.com/docs/octelium/latest/overview/how-octelium-works#from-the-user-to-the-service) When a _User_ starts accessing a _Service_, the data-plane flow takes different but equivalent paths to reach the _Service_ depending on the mode ( i.e whether privately using the client-based mode via the `octelium` CLI tool or publicly via the clientless mode) as follows: * In the client-based mode (i.e. via the `octelium connect` command as illustrated [here](https://octelium.com/docs/octelium/latest/user/cli/connect) ), a _User_ is connected to the _Cluster_ through WireGuard/QUIC tunnels to all of its _Gateways_. Whenever the _User_ accesses a _Service_, the request traffic is carried from the _User_'s side over the internet through the tunnel to the _Gateway_ hosting the _Service_ depending on the _Service_'s private address, and once it reaches the _Cluster_'s side of the tunnel (i.e. the _Gateway_), the inner traffic is de-encapsulated and forwarded to the corresponding _Service_ according to its private IP address. * In the clientless BeyondCorp mode, the request is carried out by addressing the _Service_ using its public FQDN like any public resource with a public DNS entry, the request reaches the _Cluster_ through its frontend reverse-proxy component called [_Ingress_](https://octelium.com/docs/octelium/latest/reference/components#ingress) which forwards the requests to the corresponding _Service_ based on its FQDN. ### [At the Service](https://octelium.com/docs/octelium/latest/overview/how-octelium-works#at-the-service) A _Service_ is implemented by an identity-aware proxy (IAP) via a component called [_Vigil_](https://octelium.com/docs/octelium/latest/reference/components#vigil) that runs as a Kubernetes pod inside a _Gateway_ (i.e. a data-plane Kubernetes node). Each _Service_ belongs to a _Namespace_ which acts as the parent of its _Services_ according to a common functionality (e.g. project names, environments such as production or staging, etc...) as well as being the parent domain name for such _Services_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/overview#dns) ). You can read in detail about _Namespaces_ [here](https://octelium.com/docs/octelium/latest/management/core/namespace) . For every new request coming from the _User_, _Vigil_ builds up the request context, which is simply the information required to authenticate and identify the _User_'s _Session_ as well as other information that is tied to the request such as application-layer specific information (e.g. HTTP request headers, path, method, etc...), _Vigil_ then forwards such information to another component called [_Octovigil_](https://octelium.com/docs/octelium/latest/reference/components#octovigil) . _Octovigil_ is a policy decision point (PDP); it authenticates and then authorizes the request through evaluating all _Policies_ required to control the access of that specific request. Once _Octovigil_ computes the decision as to whether request is allowed or denied, it forwards the decision back to _Vigil_. If the request is allowed, _Vigil_ proceeds with the request to the actual protected upstream resource. You can read in detail about access control and _Policy_ management [here](https://octelium.com/docs/octelium/latest/management/core/policy) . Octovigil PDP Request Vigil Identity-aware proxy Upstream Unlike in VPNs which operate and enforce access control at layer-3 using segmentation, Octelium's application-layer awareness enables it to understand various layer-7 protocols such as HTTP-based _Services_ including web apps, APIs, gRPC services and Kubernetes clusters, as well as SSH, DNS and PostgreSQL-based and MySQL-based databases. Application-layer awareness simply unlocks new capabilities across 4 key areas: * **Access control** _Vigil_ is capable of extracting layer-7 information that can be taken into account in your _Policies_. For example, in HTTP-based _Services_, this can include access control by request headers, method, path, serialized JSON body content, etc... (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http#access-control) ). For Kubernetes, this can include access control by the resource, namespace, verb, etc... (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/kubernetes#access-control) ). For PostgreSQL and MySQL, this can include access control by users, databases and queries (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/postgres#access-control) and [here](https://octelium.com/docs/octelium/latest/management/core/service/mysql#access-control) ). Octelium provides you, via [_Octovigil_](https://octelium.com/docs/octelium/latest/reference/components#octovigil) , the policy-decision-point (PDP), a modern, centralized, scalable, fine-grained, dynamic, context-aware, layer-7 aware, attribute-based access control system (ABAC) on a per-request basis using modular and composable _Policies_ that enable you to write your policy-as-code using [CEL](https://cel.dev/) as well as [OPA](https://www.openpolicyagent.org/) (Open Policy Agent). You can read in detail about _Policy_ management [here](https://octelium.com/docs/octelium/latest/management/core/policy) . It's also noteworthy that Octelium intentionally has no notion whatsoever of an "admin" or "superuser" _User_. In other words, zero standing privileges are the default state and all permissions including those to the API Server can be restricted via _Policies_ and are time/context-bound on a per-request basis. * **Secretless access to upstreams** _Vigil_ is capable of injecting application-layer specific credentials required by the upstream protected resource on-the-fly, thus eliminating the need to share and manage such typically long-lived and over-privileged credentials as well as having to distribute them to _Users_ who, in turn, must carry the burden of managing and storing them securely. For example, in HTTP-based _Services_ this can be API keys and access tokens obtained from OAuth2 client credentials flows (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http#secretless-access) ), in Kubernetes this can be kubeconfig files (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/kubernetes#secretless-access) ), in SSH it can be passwords or private keys (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/ssh#secretless-access) ), in Postgres-based and mySQL-based databases this can be passwords (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/postgres#secretless-access) and [here](https://octelium.com/docs/octelium/latest/management/core/service/mysql#secretless-access) ). _Vigil_ can also inject mTLS keys used by any generic upstream that requires mTLS. This mechanism also allows you to grant access on a per-request basis to _Users_ only via your _Policies_ regardless of the permissions granted to the injected application-layer specific credentials used to access the upstream. You can read in detail about secretless access [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) . * **Dynamic configuration and routing** Octelium's application-layer awareness enables you to dynamically route to different upstreams (e.g. an API with multiple versions where each version is served by a different upstream), set different upstream L7 credentials corresponding to different upstream accounts and/or permissions, as well as set other layer-7 specific configurations depending on the mode (You can read more [here](https://octelium.com/docs/octelium/latest/management/core/service/dynamic-config) ). Furthermore, Octelium enables advanced L7-aware request/response manipulation for HTTP-based _Service_ via extensible Lua and Envoy ExtProc plugins (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/http-plugins) ). * **Visibility and auditing** _Vigil_ is built to be [OpenTelemetry](https://opentelemetry.io/) ready and emits in real-time access logs which not only clearly identify the subject (i.e. the _User_, their _Session_ and _Device_ if available) and resource represented by the _Service_, but can also provide you with application-layer specific details of the request (e.g. HTTP request such as paths and methods, PostgreSQL and MySQL database queries, etc...). You can read in detail about visibility and access logs [here](https://octelium.com/docs/octelium/latest/management/core/visibility) . It's noteworthy to point out the mindful decision of separating _Vigil_, the policy enforcement point (PEP) from the _Octovigil_, the policy decision point (PDP). This architecture enables both components to horizontally scale independently from one another. Since the PDP needs to locally store possibly an immense amount of information about the subjects (i.e. _Sessions_, _Users_, _Groups_ and _Devices_) and resources (i.e. _Services_ and _Namespaces_) as well as the need to evaluate complex logic set in _Policies_, it could be very impractical in terms of resource usage to embed all such information inside every _Vigil_ instance at scale. ### [From the Service to the Upstream](https://octelium.com/docs/octelium/latest/overview/how-octelium-works#from-the-service-to-the-upstream) Once the request is authorized by the _Service_, it proceeds to the protected resource whose address can be either: * A static IP/FQDN private/public address that is directly reachable from within the _Cluster_ (e.g. a Kubernetes service/pod running on the same cluster, a private resource running in the same private network (e.g. same AWS VPC) as the _Cluster_, a public SaaS API protected by an access token, etc...). * A static IP/FQDN private/public address that is remotely reachable through a connected _User_ assigned to serve the _Service_. This opens the door to serving _Services_ from anywhere outside the direct reach of the _Cluster_ (e.g. private resources hosted by your laptop behind a NAT, Docker containers from anywhere, Kubernetes pods from other clusters, resources in multiple private clouds, etc...). In such case, the request proceeds from the _Service_ to the address of the connected client whose [_Session_](https://octelium.com/docs/octelium/latest/reference/resources#session) is serving the resource over the corresponding WireGuard/QUIC tunnel. You can read more [here](https://octelium.com/docs/octelium/latest/management/core/service/overview#remotely-via-a-connected-user) . * The Octelium _Cluster_ is also capable of acting as PaaS-like deployment platform by reusing the underlying Kubernetes infrastructure to automatically deploy and scale Dockerized images/containerized applications and serve them as _Service_ upstreams. You can read in detail about managed containers [here](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers) . It is noteworthy that upstreams need to know absolutely nothing about the existence of the _Cluster_. From the upstream point of view, it's just another request coming from within its own network. That means that the entire resource-intensive process of access control as well as visibility is completely done within the _Cluster_. [A Platform on top of Kubernetes](https://octelium.com/docs/octelium/latest/overview/how-octelium-works#a-platform-on-top-of-kubernetes) ----------------------------------------------------------------------------------------------------------------------------------------- So far, we have explained the data-plane flow from the _User_ to the _Service_'s upstream. However, to automate, manage and scale this process for a system with an arbitrary number of _Services_ and _Users_ we need to have a control-plane. This is somewhat similar to what Kubernetes does by building a control plane around containers but in our case the identity-aware proxy, Vigil, is the elementary unit in the platform instead of containers in the case of Kubernetes. Gateway 1 VigilVigil Gateway 2 VigilVigil Kubernetes2 nodes node 1 node 2 The Octelium _Cluster_ uses Kubernetes as an infrastructure for itself to seamlessly operate as a scalable and reliable distributed system without any manual intervention from the _Cluster_ administrators. For example, the _Cluster_ administrators don't need to bother about how to deploy the identity-aware proxy components whenever they need to add a new _Service_. In other words, creating a _Service_ using the Octelium _Cluster_ APIs or via the `octeliumctl` CLI will automatically deploy all the underlying Kubernetes resources (e.g. pods that run _Vigil_ containers) implementing that _Service_. This automatic orchestration provided by Kubernetes enables the _Cluster_ administrators to forget about the operational side where the _Cluster_ components can be managed, run and scaled up/down solely via the abstract Octelium _Cluster_ APIs. Moreover, using Kubernetes as infrastructure seamlessly enables Octelium _Clusters_ to operate at any scale. For example, horizontally scaling _Services_ translates to scaling Kubernetes _Vigil_ pods/containers; adding a new _Gateway_ to increase the overall traffic and throughout is automatically done by just adding a new Kubernetes node. Finally, using Kubernetes as an infrastructure platform for Octelium enables it to reuse the same infrastructure and effortlessly deploy your containerized applications and serve through typical Octelium _Services_ without any manual Kubernetes management effectively providing PaaS-like capabilities (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers) ). --- # CLI Tools - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links CLI Tools ========= Octelium comes with 3 CLI tools: `octelium`, `octeliumctl` and `octops`. Let's quickly see what these CLI tools are for. note You can read in detail on how to install and upgrade Octelium CLIs [here](https://octelium.com/docs/octelium/latest/install/cli/install) . [octelium](https://octelium.com/docs/octelium/latest/overview/cli#octelium) ---------------------------------------------------------------------------- `octelium` is the CLI that can be used by any _User_ mainly to connect to the _Cluster_ and access its _Services_. You can read more about connecting to the _Cluster_ [here](https://octelium.com/docs/octelium/latest/user/cli/connect) . Some examples: `1export OCTELIUM_DOMAIN=example.com 2 3# List available Services 4octelium get service 5# Connect to the Cluster via the detached mode 6octelium connect -d 7# Disconnect from the Cluster 8octelium disconnect` [octeliumctl](https://octelium.com/docs/octelium/latest/overview/cli#octeliumctl) ---------------------------------------------------------------------------------- `octeliumctl` is used by the _Cluster_'s administrators to control the _Cluster_'s resources (e.g. _Services_, _Namespaces_, _Users_, _Sessions_, etc...). You can read more about the _Cluster_ management [here](https://octelium.com/docs/octelium/latest/management/core/overview) . Here are some examples: `1export OCTELIUM_DOMAIN=example.com 2# Apply declaratively all your Cluster resources 3octeliumctl apply /path/to/directory 4# List Services 5octeliumctl get service 6# List Users 7octeliumctl get user` [octops](https://octelium.com/docs/octelium/latest/overview/cli#octops) ------------------------------------------------------------------------ `octops` is a tool that helps you to install, upgrade and uninstall Octelium _Clusters_. You can read more about installing production _Clusters_ [here](https://octelium.com/docs/octelium/latest/install/cluster/installing-cluster) . Here is an example: `1octops init octelium.example.com --bootstrap /path/to/bootstrap_file.yaml` --- # Zero Trust in Octelium - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Zero Trust in Octelium ====================== Zero trust is a security model in which network location does not create implicit trust. Access to protected resources is explicitly authenticated and authorized according to least privilege, using identity, resource state, device posture, and other contextual signals rather than assuming that a request is trustworthy because it originates from an internal network. [NIST SP 800-207](https://csrc.nist.gov/pubs/sp/800/207/final) formalizes the main principles and logical architecture of zero trust. Zero trust is not a product category or a single protocol. It is a security model that can be implemented through different architectures and enforcement mechanisms. This page maps the principles and logical architecture described by NIST SP 800-207 to concrete Octelium mechanisms. Each section links to the relevant documentation so that the architecture and behavior can be examined directly. trusted networkclientVPN gatewaypostgresapisshk8s flow logs (L3) conn 10.0.0.5 -> 10.8.0.0/24 established Octovigil (PDP)clientVigilVigilVigilVigilpostgresapisshk8s access logs (L7, per request) … [How Octelium Applies Zero Trust](https://octelium.com/docs/octelium/latest/overview/zero-trust#how-octelium-applies-zero-trust) --------------------------------------------------------------------------------------------------------------------------------- * **Resources are protected directly.** Protected applications, APIs, SSH servers, databases, Kubernetes clusters, DNS services, TCP/UDP applications, protected public resources, and managed containers are represented by _Services_. Access is authorized against the _Service_ and its request context rather than inferred from access to the network containing the upstream resource. Read more about _Services_ [here](https://octelium.com/docs/octelium/latest/management/core/service/overview) . * **Network location does not create implicit trust.** Connecting to an Octelium _Cluster_ or reaching a _Service_ does not itself grant access. Human and workload subjects are represented as _Users_ and access the _Cluster_ through _Sessions_. Human _Users_ can authenticate through OpenID Connect or SAML 2.0 _IdentityProviders_ and built-in _Authenticators_, while workloads can authenticate through OAuth2 client credentials, bearer access tokens, authentication tokens, or OIDC assertions from external workload identity systems such as GitHub Actions, cloud providers, and Kubernetes clusters. Read more about _IdentityProviders_ [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers) , _Credentials_ [here](https://octelium.com/docs/octelium/latest/management/core/credential) , and _Sessions_ [here](https://octelium.com/docs/octelium/latest/management/core/session) . * **Communication is secured regardless of network location.** Private client-based access is carried through encrypted WireGuard or QUIC tunnels, while public clientless access uses HTTPS and standard web authentication flows. The same _Service_, identity, _Policy_, and audit model applies whether the request originates from a private client connection or a public clientless access path. Read more about how Octelium works [here](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) . * **Access is explicitly authorized through a policy enforcement and decision architecture.** Requests pass through the _Service_'s identity-aware proxy, [_Vigil_](https://octelium.com/docs/octelium/latest/reference/components#vigil) , which acts as the policy enforcement point (PEP). Vigil builds the request context and sends it to [_Octovigil_](https://octelium.com/docs/octelium/latest/reference/components#octovigil) , which acts as the policy decision point (PDP), for an authorization decision. This architecture maps directly to the logical PEP/PDP model described by NIST SP 800-207. Read more about the request lifecycle [here](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) . * **Access decisions use dynamic context.** _Policies_, written in [CEL](https://cel.dev/) or [OPA](https://www.openpolicyagent.org/) , can evaluate the _User_, _Group_ memberships, _Session_, _Device_, authentication state, _Service_, _Namespace_, geolocation, request context, and arbitrary attributes supplied by external systems such as SIEM, threat intelligence, on-call management, and other security or operational tools. Read more about _Policies_ [here](https://octelium.com/docs/octelium/latest/management/core/policy) and extending access control with attributes [here](https://octelium.com/docs/octelium/latest/management/core/policy#extending-access-control) . * **Device state and posture can contribute to authorization.** When a _Session_ is associated with a _Device_, _Policies_ can use current Device information as part of the access decision. Where posture information is available, policy decisions can also incorporate signals from device-management, endpoint-security, or posture systems rather than relying only on user identity. Read more about _Devices_ [here](https://octelium.com/docs/octelium/latest/management/core/device) . * **Authentication and authorization are continuously reevaluated.** _Session_ access tokens are not treated as sufficient stateless proof of authorization. Octelium resolves current _Session_, _User_, _Group_, _Device_, and policy state during authorization, so rejecting or deleting a _Session_, disabling a _User_, or changing _Policies_ can affect subsequent access without waiting for a long-lived token to expire. Authentication strength is tracked through authenticator assurance levels (AAL), and _Users_ can be required to re-authenticate using FIDO2/WebAuthn/Passkey, TPM 2.0, or TOTP _Authenticators_. Read more about _Sessions_ [here](https://octelium.com/docs/octelium/latest/management/core/session) and _Authenticators_ [here](https://octelium.com/docs/octelium/latest/management/core/authenticator) . * **Access activity is continuously logged and exported.** Octelium emits structured access _Logs_ for allowed and denied access at the granularity supported by each _Service_ mode. Logs can identify the _User_, _Session_, _Device_, _Service_, authorization result, matching _Policy_ and rule, and protocol-specific request or connection information such as HTTP paths and methods, database queries, Kubernetes operations, SSH session information, DNS requests, and TCP/UDP flow metadata. Logs are emitted in real time to OpenTelemetry OTLP receivers for integration with observability, logging, and SIEM systems. Read more [here](https://octelium.com/docs/octelium/latest/management/core/visibility) . [Additional Least-Privilege Mechanisms](https://octelium.com/docs/octelium/latest/overview/zero-trust#additional-least-privilege-mechanisms) --------------------------------------------------------------------------------------------------------------------------------------------- The following Octelium capabilities are not separate NIST tenets, but they further reduce authorization scope, standing access, and credential exposure. * **Application-layer-aware authorization.** Because many _Services_ are implemented as application-aware identity-aware proxies, _Policies_ can authorize requests using protocol-specific context. This can include HTTP method, path, headers, query parameters, and serialized JSON body fields; database query context; Kubernetes API verb, resource, namespace, and API version; SSH user; DNS request information; and other mode-specific fields. Read more about L7-aware Policies [here](https://octelium.com/docs/octelium/latest/management/core/policy#l7-aware-policies) . * **Dynamic secretless access.** _Users_ can access protected APIs, SSH servers, PostgreSQL and MySQL databases, Kubernetes clusters, and mTLS-protected resources without receiving the upstream API key, password, private key, kubeconfig, or client certificate private key. Upstream credentials are stored as _Secrets_ and used dynamically by the _Service_ when authenticating to the upstream, so long-lived upstream application credentials do not need to be distributed to _Users_ or workloads. Read more [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) . * **No inherent superuser or implicit administrative privilege.** Octelium intentionally has no built-in "admin" or "superuser" _User_. Access to every _Service_, including the API Server itself, must be explicitly granted through _Policies_ and can be constrained by identity, time, authentication state, device state, resource context, and request context. Read more [here](https://octelium.com/docs/octelium/latest/management/core/user#privileged-users) . * **Context-aware dynamic configuration and routing.** Authorization is not the only behavior that can be selected from request context. Octelium can dynamically choose upstreams, upstream accounts and credentials, protocol-specific configuration, and routing behavior using CEL or OPA expressions evaluated from the current request context. Read more about dynamic configuration [here](https://octelium.com/docs/octelium/latest/management/core/service/dynamic-config) . * **Sandboxed execution with identity-based access through Cordium.** [Cordium](https://octelium.com/docs/cordium/latest/overview/intro) is an open-source, self-hosted sandbox platform built on Octelium. Processes running inside Cordium _Workspaces_, including developer tools, automated workloads, and AI agents, can access authorized Octelium _Services_ through Workspace identity without distributing upstream API keys, SSH keys, database passwords, or other application credentials into the sandbox. [What Zero Trust Is Not](https://octelium.com/docs/octelium/latest/overview/zero-trust#what-zero-trust-is-not) --------------------------------------------------------------------------------------------------------------- Zero trust is not defined by a single technology or product label. * **Network segmentation alone is not zero trust.** Segmentation and microsegmentation can be useful enforcement mechanisms inside a zero trust architecture, but network location or membership in a network segment must not by itself create implicit trust. * **MFA alone does not create a zero trust architecture.** Strong authentication is an important input to access decisions, but successful authentication should not automatically grant broad or unrelated access. Authorization still needs to be explicit, least-privileged, and based on the resource and current context. * **VPN connectivity alone is not zero trust.** A secure tunnel can be one transport mechanism inside a zero trust architecture, but establishing the tunnel should not itself grant broad network access. Octelium uses encrypted tunnels for private client-based access while still authorizing access against individual _Services_ and _Policies_. [Where to Go Next](https://octelium.com/docs/octelium/latest/overview/zero-trust#where-to-go-next) --------------------------------------------------------------------------------------------------- * **See the architecture:** [How Octelium Works](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) walks through the identity-aware proxy model, the request lifecycle, the PEP/PDP separation, private and clientless access paths, and the control plane. * **See the enforcement model:** [_Policies_ and access control](https://octelium.com/docs/octelium/latest/management/core/policy) documents the policy-as-code model, request context, Policy evaluation behavior, and L7-aware authorization. * **Understand the resource model:** [_Services_](https://octelium.com/docs/octelium/latest/management/core/service/overview) , [_Users_](https://octelium.com/docs/octelium/latest/management/core/user) , [_Sessions_](https://octelium.com/docs/octelium/latest/management/core/session) , and [_Devices_](https://octelium.com/docs/octelium/latest/management/core/device) document the resources used in access decisions. * **Try it yourself:** the [quick installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) installs a full _Cluster_ on a Linux VM, and the implementation is available in the [Octelium source repository](https://github.com/octelium/octelium) . --- # Resources - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Resources ========= [Core Resources](https://octelium.com/docs/octelium/latest/reference/resources#core-resources) ----------------------------------------------------------------------------------------------- ### [ClusterConfig](https://octelium.com/docs/octelium/latest/reference/resources#clusterconfig) _Cluster_ configuration, or simply _ClusterConfig_, acts as the sole source of truth for all global configurations and settings of the _Cluster_. You can read more about managing _ClusterConfig_ [here](https://octelium.com/docs/octelium/latest/management/core/cluster-config) . ### [Service](https://octelium.com/docs/octelium/latest/reference/resources#service) Each protected resource is represented in the _Cluster_ by a _Service_. A _Service_ is implemented by an identity-aware proxy (IaP) called [_Vigil_](https://octelium.com/docs/octelium/latest/reference/components#vigil) abstracting all dynamic network-layer details of the protected resource behind it and is capable of providing access control and visibility the application-layer for various protocols including HTTP, SSH, PostgreSQL, MySQL, among others. A protected resource can be running in any private network (e.g. on prem, private cloud, your own laptop behind a NAT, etc...). A protected resource can also be a protected public resource such as SaaS APIs, databases and SSH servers. You can read in detail about _Service_ management [here](https://octelium.com/docs/octelium/latest/management/core/service/overview) . ### [User](https://octelium.com/docs/octelium/latest/reference/resources#user) An Octelium _User_ denotes to the entity that interacts with the Octelium _Cluster_ and access its _Services_. A _User_ can be `HUMAN` (used by humans) or `WORKLOAD` (used by non-human entities such as containers, servers, programmable environments, etc...). In order for _Users_ to be able to interact with an Octelium _Cluster_, they must first obtain a valid [_Session_](https://octelium.com/docs/octelium/latest/reference/resources#session) . During the installation of the Octelium _Cluster_, Octelium automatically creates a _User_ called `root` with full permissions to control the _Cluster_. The _User_ `root` or other _Users_ created later having Administrator permissions can create more _Users_. A _User_ may belong to one or more Octelium [_Groups_](https://octelium.com/docs/octelium/reference/resources#group) . A _User_ can be managed both interactively using the `octeliumctl create user` and declaratively (which is the recommended way) using `octeliumctl apply`. Here is an example of a _User_ resource. You can know more about the _User_ resource from the API reference [here](https://octelium.com/docs/octelium/reference/api/corev1.mdx#user) . `1kind: User 2metadata: 3 name: user-1 4spec: 5 type: HUMAN 6 email: john@example.com` ### [Group](https://octelium.com/docs/octelium/latest/reference/resources#group) A _User_ may belong to one or more _Groups_. A _Group_ is simply a way to collect _Users_ in order to enforce rules and policies to a whole set of _Users_ instead of applying them to each one (read more about access control [here](https://octelium.com/docs/octelium/management/policy.mdx) ). A _Group_ can be managed both interactively using the `octeliumctl create group` and declaratively (which is the recommended way) using `octeliumctl apply`. Here is an example of a _Group_ resource. You can know more about the _Group_ from the API reference [here](https://octelium.com/docs/octelium/reference/api/corev1.mdx#group) . `1kind: Group 2metadata: 3 name: group-1 4spec: {}` ### [Session](https://octelium.com/docs/octelium/latest/reference/resources#session) A _User_ can interact with the Octelium _Cluster_ and access its _Services_ **only** through a valid _Session_ that is automatically created upon a successfull authentication. Once the _Session_ expires it gets automatically deleted by the _Cluster_. A _Session_ can also be deleted manually either by the authenticated _User_ using the `octelium logout`/ `octeliumctl logout` commands or by the _Cluster_ administrators using the `octeliumctl delete session` command. ### [Namespace](https://octelium.com/docs/octelium/latest/reference/resources#namespace) An Octelium _Namespace_ provides a mechanism for isolating groups of _Services_ within the _Cluster_ according to the needs of the _Cluster_ administrators. A _Service_ belongs to one _Namespace_ and thus the name of the _Service_ must be unique among all _Services_ within a _Namespace_. There are no practical limits as to how many _Namespaces_ that can be created. By default, the _Cluster_ creates a default _Namespace_ with the name `default` upon the _Cluster_'s installation, when you do not explicitly set a _Service_ to a user-defined _Namespace_, the _Service_ automatically belongs to the `default` _Namespace_. A _Namespace_ can be managed both interactively using the `octeliumctl create namespace` and declaratively (which is the recommended way) using `octeliumctl apply`. Here is an example of a _Namespace_ resource. You can know more about the _Namespace_ resource from the API reference [here](https://octelium.com/docs/octelium/reference/api/corev1.mdx#namespace) . `1kind: Namespace 2metadata: 3 name: ns1 4spec: {}` ### [Secret](https://octelium.com/docs/octelium/latest/reference/resources#secret) A _Secret_ is very similar to Kubernetes secrets. A _Secret_ is a type dedicated for storing sensitive data such as API tokens and passwords where they can be used and referenced by other _Cluster_ resources by the _Secret_'s name in order to not store sensitive data along with other _Cluster_ configurations which can stored in git repositories for example. You can read in detail about _Secret_ management [here](https://octelium.com/docs/octelium/latest/management/core/secret) . _Secrets_ are used by various other _Cluster_ resources such as _Services_ for example to provide secretless access(read more [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ). ### [Device](https://octelium.com/docs/octelium/latest/reference/resources#device) A _Device_ is a representation by the _Cluster_ of a _User_'s machine. A _Device_ can be optionally registered/enrolled by a logged-in _User_ via the command `octelium auth device register` or simply `octelium auth dev register` (read more [here](https://octelium.com/docs/octelium/latest/user/cli/authentication#device-authentication) ). However, it's up to access control to allow or deny a _User_ based on their _Device_ information. You can read more about _Device_ management [here](https://octelium.com/docs/octelium/latest/management/core/device) . ### [Credential](https://octelium.com/docs/octelium/latest/reference/resources#credential) A _Credential_ is simply a credential issued by the _Cluster_ to a certain _User_ in the form of a JWT-like token in order to be used later for authentication. A _Credential_ can have one of the 3 types: authentication tokens, OAuth2 client credentials and access tokens. You can read in detail about _Credential_ management [here](https://octelium.com/docs/octelium/latest/management/core/credential) . ### [Gateway](https://octelium.com/docs/octelium/latest/reference/resources#gateway) Each Kubernetes node that is part of the data-plane of the _Cluster_ acts as a _Gateway_ and a host for the _Services_ running on that Kubernetes data-plane node. A _Gateway_ primarily maintains the WireGuard/QUIC tunnel interfaces via a component called the [_Gateway Agent_](https://octelium.com/docs/octelium/latest/reference/components#gateway-agent) . ### [IdentityProvider](https://octelium.com/docs/octelium/latest/reference/resources#identityprovider) An _IdentityProvider_ represents an identity provider (IdP) that is used by the _Cluster_ to authenticate and re-authenticate the _Users_ in order for them to obtain and keep a valid _Session_ to be able to interact with the _Cluster_ and access its _Services_. An _IdentityProvider_ has one of the following types: `github`, `oidc`, `saml`, and `oidcIdentityToken`. Read more about managing _IdentityProviders_ [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers) . ### [Region](https://octelium.com/docs/octelium/latest/reference/resources#region) A single Octelium _Cluster_ is designed to run on top of a single Kubernetes cluster or be distributed over multiple Kubernetes clusters. Each Kubernetes cluster acts as a single _Region_ of the _Cluster_. The initial Kubernetes cluster represents the `default` _Region_ upon which _Services_ are deployed by default. You, however, can explicitly specify which _Region_ a _Service_ should be deployed on for better latency or other reasons (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/overview#region) ). --- # Quick Installation Guide - Cordium Docs Search Docs Quick Links Quick Installation Guide ======================== This is a quick guide for you to install a full-fledged single-node Cordium Cluster on any cheap Linux machine, VM or cloud VPS (e.g. DigitalOcean droplet, Hetzner, AWS EC2, etc...). This single-node Cluster is good enough for development, personal, or undemanding production use cases. note To install a production, scalable multi-node Cluster over a typical cloud-based or on-premise Kubernetes installation, we recommend referring to this guide [here](https://octelium.com/docs/cordium/latest/install/cluster) . [Fresh Installation](https://octelium.com/docs/cordium/latest/overview/quick-install#fresh-installation) --------------------------------------------------------------------------------------------------------- This guide uses the exact same steps and exact same installer script used for the Octelium Cluster [quick installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) as it installs an Octelium Cluster, and then it automatically installs the Cordium package at the end via the `--cordium` flag. To install the Cordium Cluster, simply SSH into your VPS/VM as the Linux `root` user and install the Cluster by running the following commands: `1curl -o install-cluster.sh https://octelium.com/install-cluster.sh 2chmod +x install-cluster.sh 3 4# IMPORTANT: Replace with your actual domain/subdomain to be used as the Cluster domain 5./install-cluster.sh --domain --cordium` The script should take a few minutes depending on your VM's capabilities to finish. note It's absolutely recommended to read the Octelium Cluster [quick installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) to understand how to install and initialize the Cluster correctly. [Installation on an Existing Octelium Cluster](https://octelium.com/docs/cordium/latest/overview/quick-install#installation-on-an-existing-octelium-cluster) ------------------------------------------------------------------------------------------------------------------------------------------------------------- If you already have a running Octelium Cluster that was installed via the [quick installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) , you only need to label the Kubernetes node as follows: `1# This is the kubeconfig path inside the k3s cluster machine 2export KUBECONFIG="/etc/rancher/k3s/k3s.yaml" 3 4kubectl label nodes --all octelium.com/node-mode-cordium=` And then install the Cordium package as follows: `1octops install-package --package cordium 2# Or with an explicit kubeconfig path 3octops install-package --package cordium --kubeconfig /path/to/kueconfig` [What Now?](https://octelium.com/docs/cordium/latest/overview/quick-install#what-now) -------------------------------------------------------------------------------------- Once you authenticate to the Cluster via the `octelium login` command shown to you at the end of the Cluster installation, you can now simply run your first Workspace as follows: `1cordium run` You can also visit the Cordium web portal via your web browser at `https://cordium.` and run Workspaces and terminals from there. --- # Introduction - Cordium Docs Search Docs Quick Links Introduction ============ [What Is Cordium?](https://octelium.com/docs/cordium/latest/overview/intro#what-is-cordium) -------------------------------------------------------------------------------------------- Cordium is a free and open source, self-hosted, identity-based, horizontally scalable sandbox platform built on [Kubernetes](https://kubernetes.io/) and [Octelium](https://octelium.com/docs/octelium/latest/overview/intro) . It provides isolated, reproducible sandboxes for humans, AI agents, and automated workloads. Cordium is designed around two tightly integrated purposes that most platforms treat as separate concerns: * **General-purpose sandboxed execution**: a platform for running both long-lived workloads (remote development environments, persistent coding sessions, running servers) and short-lived tasks (AI agent runs, CI/CD jobs, automated scripts) inside isolated, reproducible sandboxes accessible via a web browser, SSH, the `cordium` CLI, or a gRPC-based SDK. * **Identity-based zero-trust secretless remote access**: a platform that leverages Octelium ZTNA capabilities to provide secretless, policy-driven access to infrastructure resources (SSH servers, databases, internal HTTP APIs, mTLS services) from within Workspaces, without exposing, distributing, or managing upstream application-layer credentials (e.g. API keys and access tokens, SSH private keys, database passwords, etc.). This works for both human users opening a browser-based terminal and AI agents executing programmatically inside a Workspace. Cordium is 100% free and open source. It is designed for single-tenant self-hosting and built on standard Kubernetes infrastructure with no proprietary cloud control plane and no vendor lock-in. [Main Features](https://octelium.com/docs/cordium/latest/overview/intro#main-features) --------------------------------------------------------------------------------------- * **Unified platform for humans and AI agents.** The same **Workspace** (synonymous with a sandbox) can be accessed interactively through a browser-based terminal, via SSH, through the CLI, or programmatically via gRPC-based SDKs. This makes Cordium equally suitable as a remote development environment for engineers (comparable to GitHub Codespaces) and as an execution sandbox for AI agents, and automated workloads. Workspaces support both long-lived runs (remote development, persistent servers) and short-lived runs (AI agent tasks, build jobs, scripted automation). * **Highly customizable sandbox environments.** Workspace filesystems can be built from OCI/Docker images, Dockerfiles, git repositories, and devcontainers. Multi-repository cloning, including private repositories with authentication. Workspace configurations are fully declarative via YAML files and can be instantiated through the `cordium` CLI or managed programmatically via the gRPC API. Each running Workspace supports full root access within the sandbox, allowing users to run containers, install system packages, and run privileged services. **Templates** support pre-building for fast Workspace instantiation. **Spaces** provide namespacing for Workspaces, Templates, Secrets, and GitProviders. Secrets can be referenced in environment variables and repository authentication configurations. Workspace storage can be persistent or ephemeral. Resource limits (memory, CPU, and storage) can be defined at the Workspace, Space, and Cluster level. * **Rootless container-based sandboxing on standard Kubernetes.** No bare-metal nodes or specialized hardware are needed. Workspaces run efficiently on any Kubernetes cluster. * **Zero-trust platform on Octelium.** Cordium is built on Octelium, inheriting its zero-trust infrastructure as a foundational layer to provide the following capabilities: * **Dynamic secretless access.** Octelium's layer-7 awareness enables Users to seamlessly access resources protected by application-layer credentials without exposing, managing, or distributing such secrets (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ). This works for HTTP APIs without sharing API keys and access tokens, SSH servers without sharing passwords and private keys, Kubernetes clusters, PostgreSQL/MySQL databases, and any L7 protocol protected by mTLS. * **Modern, dynamic, fine-grained access control.** Octelium provides a centralized, scalable, fine-grained, dynamic, context-aware, layer-7-aware, attribute-based access control system (ABAC) evaluated on a per-request basis (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy) ) with policy-as-code using [CEL](https://cel.dev/) and [OPA](https://www.openpolicyagent.org/) (Open Policy Agent). Octelium has no notion of an "admin" user, enforcing zero standing privileges by default. * **Continuous strong authentication.** A unified authentication system for both human and workload Users, supporting any web identity provider (IdP) that uses OpenID Connect or SAML 2.0, as well as GitHub OAuth2 (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#web-identity-providers) ). It also supports secretless authentication for workloads via OIDC-based assertions (read more [here](https://octelium.com/docs/octelium/latest/management/core/identity-providers#workload-identity-providers) ). Built-in support for MFA, re-authentication, and login via FIDO2/WebAuthn/Passkey, TOTP, and TPM 2.0 Authenticators. * **OpenTelemetry-native auditing and visibility.** Real-time, identity-based, L7-aware visibility and access logging. Every request is logged and exported to your OpenTelemetry OTLP receivers for integration with log management and SIEM providers. * **Kubernetes-native pluggable storage.** Cordium leverages Kubernetes-native storage for Workspace persistence and integrates with any Kubernetes CSI driver and VolumeSnapshot provider. This includes Longhorn, AWS EBS, GCP Persistent Disk, Azure Disk, Ceph/Rook, OpenEBS, and any other CSI-compliant storage solution. Storage class and volume snapshot class selection is policy-driven via CEL expressions, allowing operators to route different Workspace types to different storage backends. * **Ready for agentic AI.** Cordium is not only a sandbox for isolated long-lived and short-lived process execution by sandboxed AI agents. It leverages Octelium's zero-trust infrastructure to provide identity-based, fine-grained, L7-aware, context-aware, ABAC-based access to resources (e.g. remote private/internal resources behind NAT, publicly protected SaaS resources such as APIs and databases, etc.) of any type from within Workspaces. This includes **secretless access** for resources that require application-layer credentials (API keys, access tokens, SSH passwords and private keys, database passwords, and mTLS private keys) without exposing, distributing, or sharing such credentials with the sandboxed AI agent. Credential mappings and privilege scopes can be dynamically assigned to specific agents based on identity and context on a per-request basis. * **Open source and designed for self-hosting.** Cordium, like Octelium itself, is fully open source and designed for single-tenant self-hosting. There is no proprietary cloud-based control plane, and this is not a limited open source version of a separate fully functional paid SaaS product. Cordium can be deployed on a single-node Kubernetes cluster running on a low-cost cloud VM/VPS, or on production-grade multi-node Kubernetes installations, cloud-based or on-premises, with no vendor lock-in. [The Problem Cordium Solves](https://octelium.com/docs/cordium/latest/overview/intro#the-problem-cordium-solves) ----------------------------------------------------------------------------------------------------------------- Modern development and automation workflows require isolated, reproducible execution environments that can be provisioned on demand, accessed from anywhere, and decommissioned cleanly. At the same time, those environments need access to infrastructure: databases, internal APIs, source code repositories, SSH targets. Managing that access (distributing credentials, rotating secrets, scoping permissions) is operationally expensive and a persistent source of security incidents. Existing approaches address one side or the other. Remote development platforms (GitHub Codespaces, Coder, Gitpod) solve the execution environment problem but leave credential management entirely to the user. Most sandbox platforms for AI agents focus primarily on execution isolation and SDK ergonomics, while infrastructure access and credential governance are usually handled separately. Modern identity-aware proxy-based zero trust access platforms solve the credential problem but are not designed as execution environments. Cordium unifies these. A Workspace is simultaneously an isolated execution environment and a first-class identity in the Octelium Cluster system. Processes running inside a Workspace can access any authorized Octelium-managed resource (e.g. a PostgreSQL/MySQL database, an SSH server, an internal HTTP API, a generic TCP/UDP workload, etc...) through their Workspace identity alone, with no credential injection, no static API keys, and no secrets in environment variables. The Workspace's access scope is determined based on identity and context on a per-request basis via policy-as-code using CEL and OPA expressions. --- # Cluster - Cordium Docs Search Docs Quick Links Cluster ======= A Cordium Cluster runs on top of an existing Octelium Cluster. Before installing Cordium, you must have a working Octelium Cluster running on Kubernetes. See the [Octelium installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) for instructions. [Preparing Kubernetes Nodes](https://octelium.com/docs/cordium/latest/install/cluster#preparing-kubernetes-nodes) ------------------------------------------------------------------------------------------------------------------ Cordium Workspaces run inside ordinary Kubernetes pods managed by the Cordium controllers. Nodes that are allowed to host Workspaces must be explicitly labeled. For example, to allow a node named `node-1` to host Cordium Workspaces: `1kubectl label nodes node-1 octelium.com/node-mode-cordium=` In other words, Cordium only schedules Workspaces onto nodes explicitly labeled with `octelium.com/node-mode-cordium`. You can repeat this operation for multiple nodes or node pools if you want to dedicate several nodes to Workspaces. This separation is intentional and allows operators to isolate Workspaces from Cordium control plane components, as well as Octelium control-plane and data-plane components running on the same Kubernetes cluster. [Installing the Cordium Package](https://octelium.com/docs/cordium/latest/install/cluster#installing-the-cordium-package) -------------------------------------------------------------------------------------------------------------------------- After preparing the Kubernetes nodes, you can install Cordium as an Octelium package using the `octops install-package` command as follows: `1octops install-package --package cordium` You can override the kubeconfig path explicitly: `1octops install-package --package cordium --kubeconfig /path/to/kubeconfig` [Storage](https://octelium.com/docs/cordium/latest/install/cluster#storage) ---------------------------------------------------------------------------- Cordium uses Kubernetes persistent storage for Workspace filesystems. Storage is provisioned via a CSI driver and a `StorageClass`. There are two distinct storage requirements with different levels of necessity. ### [StorageClass](https://octelium.com/docs/cordium/latest/install/cluster#storageclass) Every Workspace, persistent or ephemeral, uses a `PersistentVolumeClaim`. A `StorageClass` capable of dynamic PVC provisioning is required for Cordium to function. Workspace PVCs use `ReadWriteOnce` access mode, since each Workspace attaches its PVC to a single pod. Suitable drivers include Longhorn, AWS EBS CSI, GCP Persistent Disk CSI, Azure Disk CSI, Rook-Ceph with RBD, and OpenEBS with block storage. If the cluster has multiple `StorageClasses`, Cordium selects the one to use for a given Workspace through a CEL expression configured in `ClusterConfig`. The expression receives the Workspace spec and context and returns a `StorageClass` name. This allows different storage tiers to be assigned to different Workspace types. For example, you can dynamically use fast NVMe-backed storage for interactive development Workspaces and standard block storage for ephemeral agent runs. ### [VolumeSnapshotClass](https://octelium.com/docs/cordium/latest/install/cluster#volumesnapshotclass) Template pre-builds work by snapshotting the fully initialized storage of a completed build Workspace and restoring from that snapshot on subsequent Workspace starts. This requires a CSI driver that implements the Kubernetes `VolumeSnapshot` API and a corresponding `VolumeSnapshotClass` installed in the cluster. Without snapshot support, Cordium installs and operates normally but Template pre-builds are unavailable. Every Workspace starts from scratch regardless of whether a pre-build has been triggered. Block storage drivers that support `VolumeSnapshot` include Longhorn, AWS EBS CSI, GCP Persistent Disk CSI, Azure Disk CSI, and Rook-Ceph with RBD. As with `StorageClass`, you can also dynamically choose `VolumeSnapshotClass` on a per-Template basis via CEL expressions. --- # AI Agents - Cordium Docs Search Docs Quick Links AI Agents ========= Unlike generic container runtimes or traditional "AI sandbox" products that primarily focus on filesystem and process isolation, Cordium treats AI agents as first-class infrastructure principals with identities, policies, sessions, scoped infrastructure access, and observable runtime behavior. A Cordium Workspace is not merely an isolated execution environment, but it also has a dedicated Octelium Session identity, policy-controlled access to infrastructure resources, and full observability through OpenTelemetry-native auditing. This architecture allows AI agents to access infrastructure such as remote private resources behind NAT, AI models, publicly protected SaaS resources such as SaaS APIs and databases without requiring direct distribution of long-lived and/or over-privileged credentials into the runtime environment. note You can read various example guides for AI agents such as [Codex](https://octelium.com/docs/cordium/latest/examples/codex) and [Claude Code](https://octelium.com/docs/cordium/latest/examples/claude) . [The Problem with Existing Approaches](https://octelium.com/docs/cordium/latest/overview/ai-agents#the-problem-with-existing-approaches) ----------------------------------------------------------------------------------------------------------------------------------------- Most current AI-agent execution approaches rely on running the agent directly on developer laptops or CI runners, inside generic containers or ephemeral VMs, with infrastructure credentials injected directly into the environment, with broad API tokens or cloud credentials granted to the runtime, or with infrastructure-level isolation but no application-layer identity and authorization. These approaches share a common failure mode: the runtime environment accumulates credentials in environment variables, shell history, mounted files, git credential stores, cloud SDK configurations, kubeconfigs, SSH keys, CI secrets, or application configuration files. AI agents can unintentionally leak such credentials through logs, generated code, prompts, telemetry, external API calls, or unintended tool invocations. Traditional container isolation does not solve the core access-control problem. A container with a mounted production credential effectively becomes a highly privileged execution environment regardless of how isolated the filesystem or kernel namespace may be. Most existing "AI sandbox" systems also lack a unified identity and policy model for infrastructure access, placing the authorization boundary at the credential itself rather than at the workload identity. Here is an example for an Octelium Service (read more about Octelium Services [here](https://octelium.com/docs/octelium/latest/management/core/service/overview) ) of a SaaS HTTP API that uses bearer authentication: `1kind: Service 2metadata: 3 name: my-gemini 4spec: 5 mode: HTTP 6 isPublic: true 7 config: 8 upstream: 9 url: https://generativelanguage.googleapis.com 10 auth: 11 bearer: 12 fromSecret: gemini-api-key` You can read more detailed secretless access example guides for Octelium as an [API gateway](https://octelium.com/docs/octelium/latest/management/guide/service/http/api-gateway) , [AI gateway](https://octelium.com/docs/octelium/latest/management/guide/service/ai/ai-gateway) , [MCP gateway](https://octelium.com/docs/octelium/latest/management/guide/service/ai/self-hosted-mcp) , [SaaS API gateway](https://octelium.com/docs/octelium/latest/management/guide/service/http/zero-trust-saas-api) , [S3 gateway](https://octelium.com/docs/octelium/latest/management/guide/service/http/s3-zero-trust-secretless-access) and [AWS Lambda gateway](https://octelium.com/docs/octelium/latest/management/guide/service/http/lambda-zero-trust-secretless-access) . note Read in detail about secretless access [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) . [Identity-Based Agent Execution](https://octelium.com/docs/cordium/latest/overview/ai-agents#identity-based-agent-execution) ----------------------------------------------------------------------------------------------------------------------------- Every Cordium Workspace receives its own Octelium Session identity. That identity becomes the security principal used for infrastructure access. Instead of distributing credentials into the Workspace, infrastructure access is mediated through Octelium's identity-aware proxies and secretless access architecture totally out of reach of the Workspace. Inside the Workspace, agents use standard tools and protocols (e.g. `curl`, `psql`, `ssh`, etc.) without having to possess the upstream credentials used to authenticate against those resources. The Octelium identity-aware proxy, Vigil, injects the appropriate application-layer credentials dynamically at the identity-aware proxy based on the agent identity and context. The AI agent is allowed to perform an action because the Workspace identity is authorized to perform it, not because the runtime environment contains static credentials with broad privileges. This means infrastructure access becomes policy-driven rather than credential-driven. Access scopes can be changed without rotating secrets or rebuilding environments. Different Workspaces running the same Template can receive different access levels based on identity and context. Compromised or misbehaving agents cannot extract credentials that were never present inside the runtime. This model extends naturally to HTTP APIs, SSH, Kubernetes APIs, PostgreSQL, MySQL, mTLS-protected services, internal AI gateways, and any other application-layer protocol supported by Octelium's secretless access. Every Workspace is owned by an Octelium User (read more [here](https://octelium.com/docs/octelium/latest/management/core/user) ) and Session (read more [here](https://octelium.com/docs/octelium/latest/management/core/session) ). Here is an example for an Octelium User that can be used by an AI agent: `1kind: User 2metadata: 3 name: agent-1 4spec: 5 type: WORKLOAD 6 groups: ["agents", "dev", "ops"] 7 authorization: 8 inlinePolicies: 9 - spec: 10 rules: 11 - effect: ALLOW 12 condition: 13 all: 14 of: 15 - match: ctx.namespace.metadata.name in ["staging", "production"] 16 - match: ctx.service.spec.mode == "HTTP" 17 - match: ctx.request.http.method in ["GET", "POST", "PUT", "DELETE"] 18 - match: ctx.request.http.path.startsWith("/apis") 19 - match: ctx.request.http.uri == "/apis/users?name=john" 20 - match: ctx.request.http.queryParams.name == "john" 21 - match: ctx.request.http.headers["x-custom-header"] == "this-value" 22 - match: ctx.request.http.scheme == "http" 23 - match: string(ctx.request.http.body).toLower().contains("value1") 24 - match: ctx.request.http.bodyMap.key1 == "value1"` note Policy rules can be defined per User, Group, Session, Device, Service and Namespace. Read in detail about Octelium's access control and Policies [here](https://octelium.com/docs/octelium/latest/management/core/policy) . AI agents identities should be managed `WORKLOAD` Octelium Users that can authenticate to the underlying Octelium Cluster via the following methods: * [Authentication tokens](https://octelium.com/docs/octelium/latest/management/core/credential#authentication-tokens) . * [OAuth2 client credentials](https://octelium.com/docs/octelium/latest/management/core/credential#oauth2-client-credentials) . * [Access tokens](https://octelium.com/docs/octelium/latest/management/core/credential#access-tokens) . * [OIDC-based assertions](https://octelium.com/docs/octelium/latest/management/core/identity-providers#oidc-assertion) which can be used for secretless authentication from within GitHub actions, cloud providers, Kubernetes clusters, etc. AI agents can authenticate and interact with the Cordium Cluster via CLIs (read more [here](https://octelium.com/docs/cordium/latest/use/cli) ) or via the gRPC-based API SDK (read more [here](https://octelium.com/docs/cordium/latest/use/api) ). [Isolation Model](https://octelium.com/docs/cordium/latest/overview/ai-agents#isolation-model) ----------------------------------------------------------------------------------------------- Agents frequently need to install packages, compile code, run language runtimes, execute test suites, build containers, spawn subprocesses, interact with databases, use package managers, run browsers, or execute arbitrary developer tooling. For this reason, Workspaces intentionally provide what appears to be full root capability from inside the sandbox environment. Internally, however, the Workspace runs as a rootless container inside an outer, restricted supervisor container. [Ephemeral and Reproducible Execution](https://octelium.com/docs/cordium/latest/overview/ai-agents#ephemeral-and-reproducible-execution) ----------------------------------------------------------------------------------------------------------------------------------------- Cordium is designed around reproducible Workspace creation. Templates define the image, repositories, startup tasks, limits, runtime configuration, variables, and initialization logic declaratively. Pre-built Templates can be snapshotted and restored within seconds using Kubernetes CSI snapshots. This allows AI-agent workloads to start from deterministic environments with pre-installed dependencies, cached package trees, cloned repositories, language toolchains, and runtime frameworks already prepared ahead of time. An ephemeral Workspace run starts from a clean state and is fully destroyed afterward. This prevents state bleed between runs, limits persistence opportunities for compromised agents, and makes execution behavior easier to reason about operationally. Persistent Workspaces remain available for human-assisted development sessions, long-running automation, collaborative debugging, or agents that intentionally maintain local state over time. [Observability and Auditability](https://octelium.com/docs/cordium/latest/overview/ai-agents#observability-and-auditability) ----------------------------------------------------------------------------------------------------------------------------- All infrastructure access performed by Workspaces is audited through Octelium's OpenTelemetry-native application-layer L7-aware visibility. This includes HTTP and gRPC API requests (e.g. request path, method, query argume), database queries, full SSH sessions, Kubernetes API operations, etc. note Read in detail about Octelium visibility [here](https://octelium.com/docs/octelium/latest/management/core/visibility) . Because every Workspace has a dedicated Session identity, infrastructure activity can be correlated directly back to the Workspace, the Template, the originating User, the Space, and the specific Session performing the operation. This becomes particularly important for AI-agent workloads where reproducibility, traceability, and post-incident analysis are operationally critical. --- # Accessing and Serving Octelium Services - Cordium Docs Search Docs Quick Links Accessing and Serving Octelium Services ======================================= One of the core capabilities of Cordium is the ability for Workspaces to securely access infrastructure resources through Octelium Services without exposing long-lived credentials inside the Workspace itself. Every Workspace automatically operates as an authenticated Octelium identity. This means that tools such as `octelium`, `octeliumctl`, `kubectl`, `ssh`, `psql`, `mysql`, `curl`, and other standard clients can directly communicate with authorized infrastructure resources through the Octelium Cluster. Unlike traditional sandbox or CI environments where credentials are injected into environment variables, mounted as secrets, or stored inside repositories, Octelium provides identity-aware, policy-driven, secretless access to infrastructure resources including HTTP APIs, PostgreSQL/MySQL databases, Kubernetes clusters, SSH targets, etc... The Workspace itself only receives access permissions. Infrastructure credentials such as API tokens, database passwords, kubeconfigs, SSH private keys, and TLS client certificates remain managed at the Octelium gateway layer instead of being exposed directly to processes running inside the Workspace. This page demonstrates real-world Workspace configurations and practical examples for accessing Octelium Services from within Cordium Workspaces. note Read mor about accessing Octelium Services [here](https://octelium.com/docs/octelium/latest/user/cli/access) . Here is an example: `1spec: 2 image: 3 registry: 4 url: ghcr.io/octelium/workspace-base:ubuntu-24.04 5 6 runtime: 7 octelium: 8 serveServices: 9 - my-api 10 - my-api.staging 11 12 13 tasks: 14 - name: install 15 run: npm ci 16 type: ON_CREATE 17 workingDir: /home/ubuntu/my-project 18 onFailure: ON_FAILURE_ABORT 19 20 - name: verify-connectivity 21 type: ON_START 22 run: | 23 curl http://payments-api/healthz 24 curl http://internal-auth.staging/api/v1/me 25 curl http://internal-gateway.production/api/version 26 27 - name: inspect-db 28 type: ON_START 29 run: | 30 psql -h postgres-prod -c '\l' 31 32 psql -h postgres-prod \ 33 -c 'SELECT NOW();' 34 35 - name: inspect-host 36 type: ON_START 37 run: | 38 ssh aws-eu-1 hostname 39 ssh aws-eu-2 uptime 40 ssh gcp-eu-1.gcp systemctl status nginx 41 42 - name: serve-service 43 run: npm run start 44 type: ON_START 45 workingDir: /home/ubuntu/my-project 46 isBackground: true 47 limits: 48 cpu: 49 millicores: 2000 50 51 memory: 52 megabytes: 4096` --- # Introduction - Octelium Docs [NEW\ \ Introducing Cordium — Identity-based Sandboxes for Developers & AI Agents](https://octelium.com/cordium) Search Docs Quick Links Introduction ============ [What is Octelium?](https://octelium.com/docs/octelium/latest/overview/intro#what-is-octelium) ----------------------------------------------------------------------------------------------- Octelium is a free and open source, self-hosted unified zero trust secure access platform. Octelium replaces VPNs, tunnels, gateways, reverse proxies, bastion hosts, and other remote access tools with a unified, modern, scalable zero trust architecture. Octelium provides secure access for humans and workloads to private and internal resources behind NAT, protected public resources such as SaaS APIs and databases, and containerized applications, via a common model for identity management, client-based and clientless access, application-layer aware access control via policy-as-code, dynamic secretless access, and real-time auditing and visibility. Depending on the deployment and use case, Octelium can serve as a remote access VPN, ZTNA/BeyondCorp platform, secure tunnel infrastructure, API, AI or MCP gateway, infrastructure AI agentic systems, Kubernetes ingress alternative, application deployment platform, or homelab infrastructure. Human clientless browser access Workload / Human client-based access over WireGuard / QUIC AI Agent clientless access via OAuth2 / bearer token Unified identity for humans, workloads & AI agents Clientless BeyondCorp access Private cloud AWS, GCP, Azure Databases internal & SaaS APIs internal & SaaS Kubernetes internal & SaaS SSH internal & public Resources behind NAT laptops, IoT, on-prem Overview of an Octelium Cluster. On the left, three kinds of clients connect: a human over clientless browser access, a workload or human over client-based access via WireGuard or QUIC, and an AI agent over clientless access via OAuth2 or bearer token. All traffic flows into the central Octelium Cluster, whose rotating capabilities include unified identity for humans, workloads and AI agents, short-lived fine-grained access tokens, per-request ABAC, L7-aware access control and dynamic routing, secretless access, zero-config WireGuard and QUIC access, clientless BeyondCorp access, OpenTelemetry-native visibility, and policy-as-code. On the right, the Cluster securely reaches upstreams: private cloud resources, internal and SaaS databases, APIs, Kubernetes, SSH, and resources behind NAT on laptops, containers and IoT devices. note Want to see Octelium in practice? The [first steps guide](https://octelium.com/docs/octelium/latest/overview/management) walks through creating a _Service_, applying identity-based access control, connecting to the _Cluster_, and accessing the protected resource. [How is Octelium Different?](https://octelium.com/docs/octelium/latest/overview/intro#how-is-octelium-different) ----------------------------------------------------------------------------------------------------------------- * **A modern, unified, secure access platform** Octelium is built around identity-aware proxies rather than broad network access. Its unified architecture brings together three concerns that are commonly handled by separate systems: * **Unified access platform for humans and workloads** Human and workload _Users_ share the same identity management, authentication, access control and visibility model. Humans authenticate via your OpenID Connect or SAML 2.0 identity providers as well as native FIDO2/WebAuthn/Passkey, TOTP and TPM 2.0, while workloads authenticate via standard OAuth2 client credentials, authentication tokens or secretless OIDC-based assertions (e.g. from GitHub Actions, Azure, Kubernetes clusters, etc...). * **Unified architecture for client-based and clientless access** Both private zero-config client-based access over WireGuard/QUIC tunnels, and public clientless BeyondCorp access, via browsers for humans and via standard OAuth2 and bearer authentication for workloads, without any agents, clients or SDKs. * **Unified access to private, protected public, and containerized applications** Any private resource behind NAT in any environment (e.g. on-prem, private clouds, your own laptop, IoT devices, etc...), protected public resources such as SaaS APIs and databases, as well as containerized applications (via [managed containers](https://octelium.com/docs/octelium/latest/management/core/service/managed-containers) ) deployed and scaled by the Octelium _Cluster_ itself. * **Dynamic secretless access** _Users_ access protected HTTP APIs, SSH servers, PostgreSQL and MySQL databases, Kubernetes clusters, RDP servers and mTLS-protected resources without ever holding the API key, password, private key, kubeconfig or certificate. Such credentials are stored in the _Cluster_ as _Secrets_ and injected on a per-request basis at the identity-aware proxy without having to share, manage, rotate, and distribute such credentials to _Users_ (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/secretless) ). * **Dynamic application-layer aware access control with policy-as-code** Octelium provides centralized, fine-grained attribute-based access control (ABAC) on a per-request basis via policy-as-code using [CEL](https://cel.dev/) as well as [OPA](https://www.openpolicyagent.org/) (Open Policy Agent). This L7-aware access control includes HTTP request path, method, serialized JSON body, etc..., database queries, Kubernetes verbs and namespaces (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy#l7-aware-policies) ). * **Zero standing privileges** Octelium intentionally has no notion whatsoever of an "admin" or "superuser" _User_. Every permission, including access to the API Server itself, must be explicitly granted by a _Policy_ and is evaluated on a per-request basis, which means that access can be tied to time, context and attributes (read more [here](https://octelium.com/docs/octelium/latest/management/core/policy) ). * **Sandboxed development and AI agent execution with Cordium** [Cordium](https://octelium.com/docs/cordium/latest/overview/intro) is an open-source, self-hosted sandbox platform built on Octelium. Cordium _Workspaces_ provide isolated execution environments for developers, AI agents, and automated workloads, and can be accessed through browser-based terminals, SSH, the `cordium` CLI, or gRPC-based SDKs. Processes running inside a _Workspace_ can access authorized Octelium _Services_ through the Workspace identity without distributing upstream API keys, SSH keys, database passwords, or other application credentials into the sandbox. * **Declarative, GitOps-friendly management** A _Cluster_ is administered like Kubernetes: you define your resources in YAML files, store them in a Git repository, and a single `octeliumctl apply` command is enough to (re)produce the entire _Cluster_ state anywhere. Management is centralized via the _Cluster_'s gRPC-based APIs, which means you never SSH into servers to set up configurations, and the entire _Cluster_ is programmable via SDKs (read more [here](https://octelium.com/docs/octelium/latest/management/core/overview) ). * **OpenTelemetry-ready, application-layer aware auditing and visibility** Access logs identify the _User_, _Session_ and _Device_ as well as the application-layer details of the request (e.g. HTTP paths, database queries, SSH session recordings, etc...) and are emitted in real time to your OpenTelemetry OTLP receivers, where they can be exported to your log management and SIEM tools (read more [here](https://octelium.com/docs/octelium/latest/management/core/visibility) ). * **Built on Kubernetes for seamless horizontal scalability and high availability** An Octelium Cluster uses Kubernetes as an infrastructure to deploy and scale its control-plane and data-plane components, place _Service_ proxies across _Gateways_, restart failed components, and run containerized applications deployed by the _Cluster_. This allows the same architecture to run on a single-node Kubernetes installation for small deployments or scale across multi-node managed and on-prem Kubernetes environments. * **Context-aware, identity-based, L7 aware dynamic configuration and routing** Octelium can select upstreams, upstream accounts and credentials, protocol-specific settings, and routing behavior dynamically from request context. These decisions can be expressed with policy-as-code via CEL or OPA and evaluated on a per-request basis. * **No change in your infrastructure is needed** Your upstream resources don't need to be aware of Octelium at all. They can be listening to any behind-NAT private network, even to localhost. No public gateways, no need to open ports behind firewalls to serve your resources wherever they are. Connected clients only need outbound internet connectivity. * **Avoiding traditional VPN networking problems altogether** Each _Service_ is assigned stable private dual-stack addresses and an automatically managed private DNS name within a single stable route. There are no injected routes for remote networks, no routing conflicts, and no NAT64/DNS64 pain, regardless of what the upstreams themselves support (read more [here](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) ). * **Open source and designed for self-hosting** No proprietary cloud-based control plane or paid SaaS. Octelium _Clusters_ are meant to be self-hosted. You can host a _Cluster_ on top of a single-node Kubernetes cluster running on a cheap cloud VM/VPS, and you can also host it on scalable cloud-based or on-prem multi-node Kubernetes installations with no vendor lock-in. [Use Cases](https://octelium.com/docs/octelium/latest/overview/intro#use-cases) -------------------------------------------------------------------------------- **Secure access:** * **Modern Remote Access VPN:** Zero-config, layer-7 aware client-based and clientless access. See the quick installation guide [here](https://octelium.com/docs/octelium/latest/overview/quick-install) . * **Zero Trust Access to SaaS APIs:** Secretless access without distributing long-lived API keys. See examples for a generic API [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/zero-trust-saas-api) , AWS Lambda [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/lambda-zero-trust-secretless-access) and AWS S3 [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/s3-zero-trust-secretless-access) . * **API Gateway:** A self-hosted, scalable and secure API gateway for microservices. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/api-gateway) . * **AI Gateway:** Identity-based access control, routing and visibility for any LLM provider. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/ai/ai-gateway) . * **MCP Gateways and AI Agent-based Architectures:** Identity management, authentication, access control and visibility for [MCP](https://modelcontextprotocol.io/introduction) gateways and AI agent architectures and agentic meshes. See an example [here](https://octelium.com/management/guide/service/ai/self-hosted-mcp.mdx) . **Deployment and hosting:** * **Self-Hosted Secure Tunnels:** An ngrok/Cloudflare Tunnel alternative for identity-based as well as anonymous access. See an example [here](https://octelium.com/docs/octelium/latest/management/guide/service/http/open-source-self-hosted-ngrok-alternative) . * **Self-Hosted PaaS:** Deploy, scale and host containerized applications, similar to Vercel or Netlify. See an example for [Next.js/Vite apps](https://octelium.com/docs/octelium/latest/management/guide/service/http/nextjs-vite) . * **Kubernetes Ingress Alternative:** Route to any Kubernetes service via dynamic, L7-aware policy-as-code. * **Homelab:** Securely access all your resources behind NAT from anywhere, and privately or publicly host your websites, APIs and heavy containers (e.g. Ollama, ClickHouse, Pi-hole, etc...). See examples for [remote VSCode](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/remote-vscode-code-server) and [Pi-hole](https://octelium.com/docs/octelium/latest/management/guide/service/homelab/pihole) . [Where to Go Next](https://octelium.com/docs/octelium/latest/overview/intro#where-to-go-next) ---------------------------------------------------------------------------------------------- * **Try it in your browser:** Spin up a full _Cluster_ inside a GitHub Codespace via the [playground](https://github.com/octelium/playground) with zero installation. * **Install a Cluster in minutes:** The [quick installation guide](https://octelium.com/docs/octelium/latest/overview/quick-install) installs a full single-node _Cluster_ on any cheap VM/VPS using your own domain. * **Understand the architecture first:** [How Octelium Works](https://octelium.com/docs/octelium/latest/overview/how-octelium-works) walks through the identity-aware proxy model, the request lifecycle and the control plane. --- # Concepts - Cordium Docs Search Docs Quick Links Concepts ======== This page explains the core resource types in Cordium, how they relate to each other, and the design principles behind them. ![Cordium hierarchy](https://octelium.com/assets/cordium-hierarchy-k-2W_obH.webp) [Spaces](https://octelium.com/docs/cordium/latest/overview/concepts#spaces) ---------------------------------------------------------------------------- A **Space** is the top-level namespace in Cordium. It groups Templates, Workspaces, Secrets, and GitProviders under a single organizational unit. Each User can own one or more Spaces. A `default` Space is created automatically on first Workspace creation. Additional Spaces can be created to separate projects or environments. A Space can define runtime configuration (environment variables, lifecycle tasks) that cascades down to every Workspace within it regardless of Template. It can also define default and maximum resource limits: defaults apply when a Workspace or Template does not specify its own limits, and maximums are hard caps that no Workspace in the Space can exceed. [Workspaces](https://octelium.com/docs/cordium/latest/overview/concepts#workspaces) ------------------------------------------------------------------------------------ A **Workspace** (synonymous with sandbox) is the fundamental execution unit in Cordium. It is an isolated, rootless container-based environment that can be used interactively or programmatically via web-based console, `cordium` CLI, standard SSH, and gRPC-based APIs. Workspaces are automatically assigned short randomly generated names (3 to 6 lowercase alphanumeric characters, e.g. `abc`, `x7k2`) by the Cordium Cluster. Every Workspace belongs to exactly one Template and one Space and is owned by an Octelium User. When a Workspace starts, Cordium creates a dedicated Octelium Session bound to that run. This Session is the Workspace's identity for secretless access to infrastructure via a running `octelium` process inside the Workspace. When the Workspace stops, the Session is deleted. A **persistent** Workspace preserves its storage across stops and restarts. The filesystem resumes exactly where it left off. Only `POST_START` tasks re-run on subsequent starts. An **ephemeral** Workspace deletes its storage on stop. Every start provisions a fresh volume and runs the full initialization sequence from scratch. Ephemeral Workspaces are suited for AI agent tasks, disposable build environments, and any workload where state accumulation between runs is undesirable. A Workspace is configured through its spec, which is merged from the Template spec, Space runtime config, UserConfig, and Cluster defaults at initialization time. A somewhat minimal Workspace configuration can look as follows: `1spec: 2 image: 3 registry: 4 url: python:3.11-slim 5 runtime: 6 envVars: 7 - key: API_KEY 8 fromSecret: my-api-key 9 tasks: 10 - name: install 11 run: pip install -r requirements.txt 12 type: ON_CREATE 13 workingDir: /workspace/repo` note Read in detail about Workspace configuration [here](https://octelium.com/docs/cordium/latest/use/config) . You can use the YAML spec definitions with `cordium run` or `cordium create workspace` commands. You can also use inline flags (e.g. `--image`) to run Workspaces without using YAML files. Here are some examples: `1# From a YAML file 2cordium run --file workspace.yaml 3 4# Inline specification of image, repo, and a secret-sourced env var 5cordium run \ 6 --image node:20-bookworm \ 7 --repository https://github.com/myorg/api-service \ 8 --env-from-secret DATABASE_URL=dev-db-url \ 9 --port web:3000:default` Workspace state has a lifecycle that can be described as follows: | State | Description | | --- | --- | | `STOPPED` | The Workspace is not running. Storage is preserved if persistent. | | `INIT_REQUEST` | A start request has been accepted by the API server. | | `INITIALIZING` | Nocturne is provisioning the Kubernetes pod and waiting for the supervisor to become ready. | | `PULLING_IMAGE` | The container image is being pulled from the registry. | | `BUILDING_IMAGE` | The container image is being built from a Dockerfile or devcontainer spec. | | `STARTING_RUNTIME` | The Workspace container has started and the agent is initializing. | | `PREPARING` | The agent is running lifecycle setup: repository cloning, `ON_CREATE` tasks, dotfiles, devcontainer features. | | `RUNNING` | The Workspace is fully initialized and ready for use. | | `STOPPING_REQUEST` | A stop request has been received. | | `STOPPING` | The Workspace is shutting down gracefully, running `PRE_STOP` tasks. | Failure at any stage is captured with a structured failure type (image pull failure, build failure, clone failure, task failure, health check failure, startup timeout) and is observable through the `WatchWorkspace` streaming RPC. [Templates](https://octelium.com/docs/cordium/latest/overview/concepts#templates) ---------------------------------------------------------------------------------- A **Template** defines a reusable Workspace configuration within a Space. When a Workspace is created, it is initialized from the selected Template's spec. Every Space has a `default` Template created automatically. A Template's spec shares most of Workspace spec (image, runtime, etc.) as well as an optional GitProvider association. ### [Pre-Builds](https://octelium.com/docs/cordium/latest/overview/concepts#pre-builds) A pre-build creates a Kubernetes VolumeSnapshot of a completed build Workspace. Subsequent Workspaces restore from this snapshot and start with all dependencies, compiled artifacts, and cloned repositories already in place. This can reduce startup time from minutes to seconds for dependency-heavy Templates. Pre-building is triggered via `cordium build