Files
k7/docs/api/security.mdx
T

135 lines
4.9 KiB
Plaintext

---
title: "Security & networking"
description: "Non-root execution, Linux capabilities, and egress control"
---
This page covers sandbox security posture and how to configure it via the API.
## Non-root execution
- `pod_non_root` (boolean, default false): Run the Pod as non-root (UID/GID/FSGroup 65532). Applies pod-wide filesystem ownership.
- `container_non_root` (boolean, default false): Run the main container as non-root (UID 65532) and disallow privilege escalation.
Guidance:
- Enable both flags for consistent non-root behavior and fewer permission surprises when writing to volumes.
- Some package managers (e.g., Alpine `apk add`) require root. To run `apk add` inside the container, you have options:
- Use `before_script` with a base image that already includes needed tools, or
- Temporarily run the main container with root by leaving `container_non_root` disabled for setup, or
- Build a custom image with dependencies pre-installed (recommended for production reproducibility).
Example (non-root):
```json
{
"name": "nr-example",
"image": "alpine:latest",
"pod_non_root": true,
"container_non_root": true
}
```
Example (install packages first as root, then lock down egress):
```json
{
"name": "setup-then-lock",
"image": "alpine:latest",
"before_script": "apk add --no-cache curl git",
"egress_whitelist": ["203.0.113.0/24"]
}
```
## Linux capabilities
Default policy: drop ALL capabilities. Add back only what you need. If you specify `cap_drop` explicitly, you override the default; to keep `drop ALL` and add back minimal caps, leave `cap_drop` unset and only use `cap_add`.
- `cap_drop` (string[]): Capabilities to drop. If omitted, `ALL` is dropped by default.
- `cap_add` (string[]): Capabilities to add back.
- `allow_privilege_escalation`: always set to `false`.
- Seccomp profile: `RuntimeDefault`.
Examples:
Minimal add-back while still dropping ALL by default:
```json
{
"name": "caps-minimal",
"image": "alpine:latest",
"cap_add": ["CHOWN"],
"cap_drop": null
}
```
Override drop policy (not recommended unless you know why):
```json
{
"name": "caps-custom",
"image": "alpine:latest",
"cap_drop": ["NET_RAW"],
"cap_add": []
}
```
## Network isolation and egress lockdown
### Ingress isolation (Default: Enabled)
**All inter-VM communication is blocked by default** to prevent sandbox-to-sandbox access. This provides strong isolation between different sandboxes running in the same cluster.
**Key points:**
- **Ingress blocking**: VM sandboxes cannot communicate with each other by default
- **Administrative access preserved**: `kubectl exec` and `k7 shell` still work normally (they use the Kubernetes API, not pod networking)
- **System services allowed**: Traffic from `kube-system` namespace is permitted for cluster functionality
- **No configuration needed**: This security feature is enabled by default for all sandboxes
### Egress lockdown and whitelisting
Use `egress_whitelist` to control outbound traffic. The policy is applied after the container becomes Ready so `before_script` runs with open egress.
Behavior:
- Omit `egress_whitelist`: egress open (external internet allowed).
- `[]`: full egress block (no DNS resolution; no outbound IPs).
- `["CIDR", ...]`: allow only listed CIDR blocks; DNS is blocked.
Examples:
Full isolation (no inter-VM communication, no external access):
```json
{ "name": "fully-isolated", "image": "alpine:latest", "egress_whitelist": [] }
```
Partial isolation (no inter-VM communication, but external internet allowed):
```json
{ "name": "partial-isolation", "image": "alpine:latest" }
```
Whitelist specific external services (avoid public DNS resolvers):
```json
{
"name": "egress-restricted",
"image": "alpine:latest",
"egress_whitelist": ["10.0.0.5/32"]
}
```
<Info>
**Network Policy Details:**
- **Ingress**: Blocked by default (inter-VM isolation) - system services and kubectl exec still work
- **DNS**: When egress is locked down, DNS resolution is blocked by default (no CoreDNS exception)
- **Administrative access**: `kubectl exec`, `k7 shell`, and API operations bypass network policies
</Info>
<Warning>
Do not whitelist public DNS resolver IPs (e.g., 1.1.1.1, 8.8.8.8). Because K7's `egress_whitelist` is CIDR-only (no L7/port rules), allowing those IPs enables outbound DNS (UDP/TCP 53) and DNS-over-HTTPS (443), which can be used for exfiltration. If you want an egress deny with whitelisting, prefer whitelisting only your own egress proxy/gateway IP and enforce DNS/DoH policy at that proxy. Later, whenever we integrate Cilium (a roadmap feature), it will be much simpler as you'll be able to whitelist domain names directly.
</Warning>
### Mitigations when DNS is blocked
- Use IP/CIDR whitelisting only (no domains post-lockdown)
- Pre-resolve/fetch in `before_script` (runs before lockdown with open egress)
- If you must allow DNS temporarily, consider an operational override at cluster level (not provided by K7 config)