diff --git a/docs/how-it-works/policies/network-rules.mdx b/docs/how-it-works/policies/network-rules.mdx index 5b3b366458..bcaba59218 100644 --- a/docs/how-it-works/policies/network-rules.mdx +++ b/docs/how-it-works/policies/network-rules.mdx @@ -353,8 +353,11 @@ OpenShell blocks connections to private network addresses by default to prevent server-side request forgery (SSRF). An endpoint with an exact hostname can still reach the private addresses that its hostname resolves to, unless the endpoint comes from an approved [policy advisor](/how-it-works/policies/advisor) -proposal. Loopback, link-local, and unspecified addresses, including the cloud -metadata address `169.254.169.254`, are always blocked. +proposal. Network policy never authorizes an outbound endpoint whose destination +is loopback, link-local, or unspecified, including the cloud metadata address +`169.254.169.254`. This restriction does not apply to sandbox-local loopback +connections: a workload can reach a service listening on `127.0.0.1` in the +same sandbox. Use `allowed_ips` to limit the addresses an endpoint can reach, or to let a wildcard host such as `*.internal.example` reach private addresses. This rule diff --git a/docs/how-it-works/policies/schema.mdx b/docs/how-it-works/policies/schema.mdx index 505a0a7838..a4801b0b0a 100644 --- a/docs/how-it-works/policies/schema.mdx +++ b/docs/how-it-works/policies/schema.mdx @@ -137,13 +137,16 @@ reach the private addresses they resolve to, unless the endpoint comes from an approved policy advisor proposal. Wildcard and hostless endpoints can reach private addresses only through `allowed_ips`. -Loopback, link-local, and unspecified addresses, including the cloud metadata -address `169.254.169.254`, are always blocked. `openshell policy update` rejects -an `allowed_ips` entry that overlaps them, and in a complete policy such an -entry blocks every connection to the endpoint. OpenShell also blocks the -Kubernetes and etcd control-plane ports 2379, 2380, 6443, 10250, and 10255 on -endpoints that use an exact hostname, an IP address, or `allowed_ips`. A rule -for `host.openshell.internal` can still reach services on the gateway host. +Network policy never authorizes an outbound endpoint whose destination is +loopback, link-local, or unspecified, including the cloud metadata address +`169.254.169.254`. This does not prevent a workload from connecting to a +sandbox-local service listening on loopback. `openshell policy update` rejects +an `allowed_ips` entry that overlaps the blocked ranges, and in a complete +policy such an entry blocks every connection to the endpoint. OpenShell also +blocks the Kubernetes and etcd control-plane ports 2379, 2380, 6443, 10250, +and 10255 on endpoints that use an exact hostname, an IP address, or +`allowed_ips`. A rule for `host.openshell.internal` can still reach services on +the gateway host. #### Inspection Fields diff --git a/docs/observability/logging.mdx b/docs/observability/logging.mdx index b41c40c885..e9b6a03845 100644 --- a/docs/observability/logging.mdx +++ b/docs/observability/logging.mdx @@ -194,7 +194,7 @@ Common reason phrases emitted by the sandbox include: | Reason | Meaning | |---|---| | `no matching policy` | OPA evaluated the request and no allow rule matched. | -| `resolves to always-blocked address` | The destination resolved to loopback, link-local, or unspecified. These ranges are always blocked, even when listed in `allowed_ips`. | +| `resolves to always-blocked address` | An outbound policy endpoint resolved to loopback, link-local, or unspecified. Network policy cannot authorize these destinations, even when they appear in `allowed_ips`; sandbox-local loopback connections do not use this policy path. | | `resolves to which is not in allowed_ips, connection rejected` | The destination resolved to an IP outside the policy's `allowed_ips` allowlist. | | `DNS resolution failed for :` | The proxy could not resolve the destination. | | `port is a blocked control-plane port, connection rejected` | The destination port matches a control-plane port (etcd, Kubernetes API, kubelet) and is always blocked. |