Network isolation
Security
Every Greenlight app runs inside a dedicated Kubernetes namespace with its own NetworkPolicy and resource quota, and there are no per-app overrides.
Read this section carefully, because inbound and outbound are not at the same maturity today. Inbound isolation is enforced now. Outbound restriction is not built yet: an app pod can open a connection to any host, and there is no setting that changes that today. When it ships it will be an IT opt-in, off by default. We would rather tell you that plainly than have you find it in a penetration test.
Enforced today
Section titled “Enforced today”| Direction | Posture |
|---|---|
| Ingress | Default-deny. An app pod is reachable only from the cluster’s ingress controller, which terminates TLS and enforces SSO before traffic reaches the pod. |
| Cross-app | Blocked. An app cannot reach another app’s namespace or the control-plane namespace. |
| Resources | Quota per namespace, so one app cannot starve others. |
| Egress | Allow-all. An app pod can reach any external host. |
The outbound allow-list — planned, not built
Section titled “The outbound allow-list — planned, not built”This is the posture app egress lockdown will establish once it ships, as an IT opt-in that is off by default. None of it exists today: there is no toggle in Settings, no org allowlist to edit, and no way for an agent to request a hole. Outbound is unrestricted, and none of the rows below is a boundary yet. They are here so you can see what is coming and plan against it — not as controls to go looking for.
| Direction | What’s allowed |
|---|---|
| Ingress | From the cluster’s ingress controller only. The controller terminates TLS and enforces SSO before any traffic reaches an app pod. |
| Egress (proxied integrations) | To the Greenlight data proxy. For a proxied integration the app never holds the upstream credential — it calls the proxy, which resolves the grant, swaps in the real credential, and audits the call. App code cannot resolve or reach the upstream itself. |
| Egress (injected integrations) | To the specific host of a granted integration whose credential IT delivers directly into the app’s environment (used for things an HTTP proxy can’t carry — a database connection string, a binary wire protocol). One entry per granted injected host. |
| Egress (own database) | To the app’s own provisioned Postgres on port 5432, inside the cluster network. A database wire protocol can’t ride the HTTP proxy, so the app connects to its own database directly — it still can’t reach any other app’s database. |
| Egress (DNS) | To the cluster’s kube-dns only, for resolving in-cluster service names. No external DNS. |
| Egress (org allowlist) | Hosts or CIDRs IT would add in Settings. Applies to every app in the install. |
| Egress (approved holes) | A host an app’s builder agent would request and IT approve. That app only. |
Under that posture everything else — public-internet egress, raw TCP to arbitrary hosts — is dropped. An injected integration’s host is reachable because IT granted that integration; revoke the grant and the entry goes with it. A hole is reachable because IT approved that request; revoke the hole and that app loses the host, without turning lockdown off for the rest of the org. Cross-namespace traffic is already blocked today, independently of any of this.
What this gives you in practice, today
Section titled “What this gives you in practice, today”Holds now. A compromised app cannot pivot to other Greenlight apps in the cluster — that is cross-namespace isolation, and it is enforced. It cannot be reached from the internet except through the ingress controller, behind SSO. And for a proxied integration it never holds the upstream credential at all: it carries a Greenlight-issued key, and the proxy resolves the grant, swaps in the real credential, and audits the call. So a compromised app can use the integrations it was granted — the same thing the legitimate app could do — and revoking the grant cuts access on the very next call.
Does not hold yet. Because outbound is unrestricted today, a code-injection bug can reach an attacker-controlled host, a hard-coded URL does reach the internet, and SSRF can reach the cloud metadata endpoint. What limits the damage is that there is little in the pod worth taking: no upstream credential for any proxied integration, and no workload identity with a role assignment on your vault or cloud APIs. The exception is an injected integration, whose credential does live in the pod’s environment — that one is a real exposure until outbound restriction ships and an org turns it on, and it is the reason injected delivery is the narrower, more deliberately granted path.
We are describing this gap rather than papering over it because a security review that discovers it later is worse than one that reads it here.
What’s on the control-plane side
Section titled “What’s on the control-plane side”The Greenlight control plane runs in its own namespace inside the customer’s cluster. It is not reachable from app namespaces except through the data proxy — and the proxy rejects requests that don’t match a granted integration.
The control plane’s own egress is restricted to the customer’s IdP, the configured cloud provider APIs, and the cloud-managed secret store. It does not call out to Shift-operated services at runtime. An app pod reaching the control plane still has to present a valid workload key and hit a granted integration; there is no unauthenticated control-plane surface exposed to app namespaces.
What needs new integrations vs extra egress
Section titled “What needs new integrations vs extra egress”If an app needs a governed credential to a SaaS API, IT registers it as an integration — from the built-in catalog of common services, or via the custom path for anything not catalogued. That is still the path that gives the app a proxy URL (or an injected environment variable), an audited credential, and a clean revocation story.
Once lockdown ships, an app that only needs to reach a host — a public data API, a vendor webhook, something that is not worth a full integration — will not invent a NetworkPolicy by hand. IT will either add the host to the org allowlist in Settings, or the builder’s agent will request a hole for that app and IT approve or later revoke it on the same review queue as grants. Neither path is available yet.
What’s enforced where
Section titled “What’s enforced where”- Container runtime: blocks privileged operations, host networking, host PID namespace.
- NetworkPolicy: blocks unauthorized network flows as described above.
- Ingress controller: enforces TLS termination and SSO before traffic reaches an app.
- Data proxy: enforces integration grants and per-call audit at the application layer, for proxied integrations.
- Cloud provider IAM: enforces workload-identity scoping so a compromised workload cannot use its identity outside its app’s role.
Each layer enforces something independent. A bypass would need a real defect in the layer, not just a misconfiguration.