Citrix SecurSpaces™

Trust boundaries

Where a Citrix SecurSpaces™ deployment separates one level of trust from another, what enforces each separation, and which side of it you own. This page supports network security review and architecture assessment.

It describes the boundaries the platform implements. It is not a threat model: it does not enumerate adversaries, abuse cases, or risk ratings.

Summary

Boundary Enforced by Owner
Your network to the cluster Ingress controller, TLS termination You
Ingress to SecurSpaces services Kubernetes NetworkPolicy, TLS SecurSpaces
SecurSpaces services to the database Kubernetes NetworkPolicy SecurSpaces
Workspace to workspace Kubernetes NetworkPolicy SecurSpaces
Workspace to the internet A Kubernetes NetworkPolicy confines the workspace to the proxy service, which then enforces the SecurSpaces network policy attached to it SecurSpaces, configured by you
Platform to the Kubernetes API Kubernetes RBAC SecurSpaces
Cluster to the nodes and the host Your cluster configuration You

Important:

Every in-cluster boundary on this page is a Kubernetes NetworkPolicy, so it holds only if your cluster runs a network plugin that implements the networking.k8s.io/v1 NetworkPolicy API. If it does not, these policies are accepted by the API server and silently do nothing. See Requirements.

The perimeter

Traffic reaches the deployment through the ingress controller. TLS terminates there, so the permitted TLS versions and cipher suites are part of your ingress configuration rather than something SecurSpaces sets.

The load balancer in front of the ingress controller operates at Layer 4 and does not terminate TLS.

For the ports that must be reachable, see Ports and protocols.

Inside the cluster

SecurSpaces labels its pods by type and ships NetworkPolicies that act on those labels.

Pod type Label
Platform services strong.network/type: service
Database strong.network/type: database
Workspaces and secure browsers strong.network/type: workspace, strong.network/type: browser
Workspaces with a network policy attached strong.network/hardened: no_egress

Important:

Do not rename these labels. The NetworkPolicies select on them, and a renamed label produces a policy that matches nothing, with no error.

Service pods accept traffic from anywhere

The NetworkPolicy for service pods accepts ingress from any source. This is deliberate — they are the entry point for the deployment — but it means the perimeter around the platform services is your ingress configuration, not a NetworkPolicy.

The database policy

SecurSpaces ships a NetworkPolicy that restricts ingress to pods labeled database, accepting connections only from pods labeled service.

Important:

A NetworkPolicy only covers pods that carry the label it selects on. Whether your database pods carry it depends on how the database is deployed, and a database running outside the cluster is not covered at all. Confirm the label is present on your database pods before treating this policy as the control that isolates them, and apply your own network controls where it is not.

Workspaces accept traffic only from the workspace API

Pods labeled workspace or browser accept ingress only from the workspace API pod.

This is what isolates workspaces from each other. One workspace cannot open a connection to another, and this holds whether or not a network policy is attached, because it is enforced on the receiving side.

Workspace egress depends on the attached policy

Two different mechanisms share the name network policy, and both are involved here.

A workspace carries the label strong.network/hardened: no_egress only while a SecurSpaces network policy is attached to it. A Kubernetes NetworkPolicy selects pods with that label and permits them to send traffic only to service pods, which leaves the SecurSpaces proxy service as the workspace’s only route out. The proxy service then allows or refuses each destination according to the SecurSpaces network policy.

So the Kubernetes NetworkPolicy decides that a workspace may talk only to the proxy service. The SecurSpaces network policy decides where the proxy service will carry it.

Important:

A workspace with no network policy attached is not labeled as hardened, so this NetworkPolicy does not apply to it and its outbound traffic is not restricted by the platform. Egress restriction is something you turn on by attaching a policy. See Network policies.

Platform access to the Kubernetes API

The workspace API manages workspace lifecycle through the Kubernetes API, using a service account scoped to the release namespace.

Scope Access
Namespace Pods, services, secrets, persistent volume claims, config maps, service accounts, events, jobs, deployments and stateful sets, pod logs, and a named lease
Cluster-wide Storage classes and persistent volumes, read-only. Nodes and node metrics, read-only.

Write access to persistent volumes is not granted by default. It is enabled only when you turn on the allowPersistentVolumeAccess setting, which the Attach Existing mount point workflow requires.

Host-level changes on workspace nodes

SecurSpaces runs a DaemonSet on nodes that are not labeled as service nodes. Its init container runs as root with privileged: true, in the host network, PID, and IPC namespaces, and mounts /sys from the host.

It sets these kernel parameters on those nodes:

Parameter Value Purpose
kernel.unprivileged_userns_clone 1 Allows unprivileged user namespaces, which rootless containers in workspaces require
user.max_user_namespaces 49152 Raises the user namespace limit for the same reason
fs.inotify.max_user_watches 1524288 Raises the file watch limit that the IDE needs on large repositories
kernel.yama.ptrace_scope 0 Allows a debugger to attach to a running process. Developers need this to debug compiled binaries, such as C and C++, inside a workspace. This relaxes the default restriction on most distributions.
fs.suid_dumpable 0 Prevents core dumps from setuid programs
kernel.core_pattern /dev/null Discards core dumps rather than writing them to disk

These are node-level settings and apply to everything scheduled on those nodes. If you run other workloads on the same nodes, take this into account when you plan node pools.

Working from a local IDE

A developer can work in the Cloud IDE in a browser, or connect a local IDE over SSH. The second is a supported access channel rather than a workaround, but it is not equivalent: a local IDE is software running on the endpoint, so it widens the boundary slightly. This section is what a security reviewer needs to judge by how much.

The development environment itself does not move. Code, execution, and credentials stay in the workspace whichever channel is used; what changes is where the editor renders.

Where each artifact resides

Artifact Resides On the endpoint?
Source code Workspace filesystem No. The local IDE edits it remotely and does not write it to local disk
Repository credentials Brokered by the SecurSpaces proxy service No. Never exposed to the endpoint, and not readable from inside the workspace either
SSH key that opens the tunnel The developer’s endpoint Yes, necessarily. This is the key that authenticates the developer to the workspace
Personal SSH identity, used for any SSH service Held by the platform and presented by the SecurSpaces proxy service when the connection is made No. Not written into the workspace, so a process there cannot copy it
SSH services attached as project resources Held by the platform, injected the same way No
Build artifacts Workspace filesystem No, unless a developer deliberately copies them out, which egress and transfer controls govern
Language package caches, such as npm and pip Workspace filesystem No
AI model context Inside the workspace and the policy boundary, attributed per user, project, and workspace No
IDE extension data Split. Extensions that render UI run on the endpoint; extensions that execute code run in the workspace Partly. The UI extension host is the one part of the IDE that is genuinely local

Note:

The two SSH key roles are easy to conflate and the distinction matters. The key that opens the tunnel is the developer’s own and lives on their machine, like any SSH client key. The key the workspace presents when it connects out — its personal SSH identity, or an SSH service attached as a project resource — is held by the platform and reaches neither the endpoint nor the workspace runtime. See How SSH connections are handled.

What the endpoint can still see

Because the IDE renders locally, a compromised endpoint could still capture keystrokes, screen content, or clipboard data, and the extension host runs local code. Clipboard controls still apply, but they are enforced against the session rather than against the operating system.

This is inherent to any SSH-based remote development model rather than specific to SecurSpaces, and it is a smaller surface than a laptop or a VDI session with a local Linux subsystem, where source code, credentials, and package caches are all genuinely local. It is still larger than the Cloud IDE, which is why remote development over SSH is a setting an administrator turns on deliberately. See Workspace policy.

What you own

SecurSpaces is customer-hosted, so the following are outside the boundary the platform controls:

  • The ingress controller and its TLS configuration.
  • A network plugin that enforces NetworkPolicy. Without one, the in-cluster boundaries above do not hold.
  • Cluster and node hardening, and which workloads share a node pool with workspaces.
  • Encryption at rest for the database, persistent volumes, and etcd.
  • Runtime container scanning and image admission control.
  • Network reachability between the cluster and any external dependency, such as the database, registries, repository providers, and your SIEM.