Every connection into a Syself Autopilot node proves who it is, and the traffic is encrypted. A node runs on the public internet. It has a public IP and no private network. The cluster trusts a connection based on the identity it carries, not on where it comes from on the network. Most clusters work the other way. Perimeter security puts cluster traffic on a private network. The firewall checks traffic at the edge, and everything inside is trusted. That holds until one service inside is compromised. From there the attacker can reach the others, because inside the perimeter, no service checks the caller's identity. In Syself Autopilot, every part of the cluster checks the caller's identity on each connection, wherever the caller is. That identity is a certificate. The cluster's own certificate authority issues each certificate and checks it. | | Perimeter (private network) | Syself Autopilot (per-connection identity) | | -------------------------------- | ------------------------------- | -------------------------------------------------------------------- | | What makes a connection trusted | It came from inside the network | It presented a valid certificate that was checked on this connection | | After one service is compromised | Attacker moves sideways freely | Each next connection is checked for a valid identity again | | Depends on | The provider's network product | Nothing outside the cluster's own CA | | Where nodes can run | Only behind the perimeter | Directly on the public internet | Syself builds and runs the layers that make this work. Two pages cover how it works: [Networking and Cilium](/docs/hetzner/apalla/concepts/internals/networking) for the firewall and the encrypted paths, [Syself Linux](/docs/hetzner/apalla/concepts/internals/syself-linux) for the immutable operating system. ## Every path in is authenticated Traffic reaches a node along the API path, the SSH path, and the control-plane tunnel. Every inbound path authenticates before the node accepts it. A probe against any other port hits the host firewall and is dropped. ```mermaid flowchart LR SCAN["Internet scanner"] CLIENT["Your kubectl, or the Syself management plane"] LB["Control-plane load balancer"] subgraph NODE["Node: public IP, immutable OS"] FW["Default-deny host firewall"] KG["KubeGate: checks the source policy"] API["API server: local only"] SSH["SSH: key-only"] TUN["Tunnel agent: sandboxed"] end CP["Control plane"] SCAN -->|"probes dropped"| FW CLIENT -->|"API request"| LB LB -->|"only the load balancer is admitted"| KG KG --> API TUN -->|"dials out, both sides prove identity"| CP SCAN -.->|"reachable until you restrict it"| SSH ``` - An API request reaches the API server only through the control-plane load balancer, then through KubeGate. - SSH is key-only. Password login is off. - The tunnel is outbound. The node dials the control plane, so there is no listener for an inbound connection to reach. [Platform components](/docs/hetzner/apalla/concepts/internals/platform-components) covers how KubeGate checks each connection against its policy and how the tunnel agent proves its identity. [Zero trust on public networks](/docs/hetzner/apalla/security/zero-trust-on-public-networks) covers the operational detail: KubeGate's tickets, its opt-in source policy, and how it fails open so a missing load balancer can never lock you out. ## A default-deny firewall on every node Every node runs a default-deny host firewall, keyed to cluster identity rather than network address. A node stays safe on a public IP because only the paths it needs are open, and each open path names who may use it. A compromised pod gets the same treatment as any connection from the internet. The open paths, the identity types, and the mechanism are in [Networking and Cilium](/docs/hetzner/apalla/concepts/internals/networking). ## An immutable OS you can verify Underneath the network layers, the node operating system is immutable. A node runs exactly what Syself shipped, and you can verify it. An attacker who gets root cannot make a change to the OS that survives. [Syself Linux](/docs/hetzner/apalla/concepts/internals/syself-linux) covers how the check runs on every disk read, the partition layout, the trust boundary at the writable boot settings, and why there is no hardware-backed boot check. ## Each control works on its own The firewall, the certificates, and the immutable OS are separate controls. Each runs its own check instead of trusting an earlier one, so if one fails, the others still block the attacker. One failure does not give an attacker the whole node. A scanner that slips past the firewall still cannot use the API server, which checks the caller's identity on every request. A workload that escapes its container still cannot rewrite the OS. ## No private network is needed Syself Autopilot gives you no private network, and none of the zero-trust protection needs one. Every layer authenticates on its own, so a node on a public IP is not exposed. The design assumes every packet crosses the open internet. Adding a private network to a public node changes nothing. The node is still exposed on its public side. A node with only a private network would be easier to secure, because nothing outside could reach it. Syself instead hardens every node in software until the node is safe to expose directly. That hardening is automated and runs per node as part of the node lifecycle. The no-private-network decision, why it makes the design portable, and why Hetzner's private network is not a good fit even if you wanted one are covered in [Minimal provider dependency](/docs/hetzner/apalla/concepts/internals/minimal-provider-dependency). A private network would not encrypt pod-to-pod traffic either, and the cluster is already secure without on-wire encryption between pods. [Networking and Cilium](/docs/hetzner/apalla/concepts/internals/networking) covers why, and the options if you do want it. ## The openings you close The host layer is zero-trust already. The workload layer is not, so you configure it. These are the openings you close. 1. **SSH is reachable until you restrict it.** Administrator login is open to the world and key-only. Limit it to your admin address ranges: [restrict SSH access](/docs/hetzner/apalla/security/restrict-ssh-access). 2. **Pods are default-allow until you segment them.** On a fresh cluster, any pod can reach any other pod in any namespace. One default-deny NetworkPolicy per namespace closes it: [segment with network policies](/docs/hetzner/apalla/security/segment-with-network-policies). > [!WARNING] > If you assume the cluster is zero-trust and change nothing inside it, your pods are still open to each other. The zero-trust posture is at the host layer. Segmenting your pods is the part you configure. Day one is a short checklist. Restrict SSH. Apply a per-namespace default-deny NetworkPolicy. Then decide whether to encrypt the cluster store and whether to ship audit logs off the node for your own records. Everything else already runs before you start your first pod. [What you own, what Syself manages](/docs/hetzner/apalla/concepts/ownership/ownership-and-shared-responsibility) places these on the responsibility line. - The tamper baseline for the writable data area is set when the health service starts, not at build time, so a change made while that service is down is adopted on restart. - Nothing ships logs off the node or keeps an append-only store. Send your system, API, and KubeGate audit logs to your own log system if you want the record to outlive a node: [retrieve audit logs](/docs/hetzner/apalla/security/retrieve-audit-logs). - Encryption of the cluster store on disk is opt-in: [encrypt etcd](/docs/hetzner/apalla/security/encrypt-etcd). - Hardware-backed measured boot is not wired up. The hardware carries a TPM, but Syself does not use it. - Encryption of pod-to-pod traffic between nodes is available but off by default: [encrypt pod traffic with WireGuard](/docs/hetzner/apalla/security/encrypt-pod-traffic-with-wireguard). ## The model from the attacker's side Each row is one attacker position: what stops them, and what stays open from there. | Attacker position | What stops or detects them | Residual | | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | Internet scanner | The default-deny host firewall, where every open path names who may use it. The API server is reachable only through the load balancer, then KubeGate. The tunnel is dialed outward, so there is no listener to find. | SSH is reachable from any address until you restrict it. It is key-only, but still reachable. | | Compromised workload | An enforced security profile and system-call filter on every non-privileged container; unsigned kernel modules rejected; the host firewall keeps the kubelet, the store, and the tunnel away from pods. | Pod-to-pod traffic is allowed by default until you segment it. This row does not cover privileged containers. | | Root on a node | The kernel fails every read of a changed immutable block; there is no package manager to install with; tamper conditions latch on the node's record and survive a disk wipe. | The writable data area stays writable: tamper-evident, not immutable. Recovery is to rebuild the node, not repair it. | | Physical disk or boot-settings access | Below the boot settings, the immutable OS blocks every in-place edit, and the public base hash lets anyone recompute and compare the running boot settings. | No hardware-backed boot check. Whoever controls the boot partition controls that node. | The positions build on each other. A scanner who finds a service becomes a workload attacker; a workload that escapes becomes root on a node. [Threat model](/docs/hetzner/apalla/security/threat-model) covers every position in full, including the supply chain. ## Where to go next These pages cover the mechanism, and the responsibility page covers what you configure. - [What you own, what Syself manages](/docs/hetzner/apalla/concepts/ownership/ownership-and-shared-responsibility) - [Networking and Cilium](/docs/hetzner/apalla/concepts/internals/networking) - [Syself Linux](/docs/hetzner/apalla/concepts/internals/syself-linux) - [Zero trust on public networks](/docs/hetzner/apalla/security/zero-trust-on-public-networks) - [Security at Syself](/docs/hetzner/apalla/security/security-architecture)