Configure SecurSpaces for AWS Mount Points
Complete the AWS preparation first. The steps here depend on a file system, its mount targets, and the IAM roles already existing.
Create the StorageClass
You author the StorageClass by hand, one per backing file system. SecurSpaces ships none and creates none. A missing StorageClass is the most common cause of an empty create dialog.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sn-efs-mountpoint
provisioner: efs.csi.aws.com
mountOptions:
- tls
parameters:
provisioningMode: efs-ap
fileSystemId: fs-0abc123
basePath: "/dyn"
directoryPerms: "700"
gidRangeStart: "50000"
gidRangeEnd: "51000"
reclaimPolicy: Delete
volumeBindingMode: Immediate
<!--NeedCopy-->
Required values:
-
provisioner: efs.csi.aws.comfor both backends. -
parameters.provisioningMode—efs-apfor Amazon EFS,s3files-apfor Amazon S3 Files. This parameter, not any option in the interface, selects the backend. Users choose the backend by choosing the StorageClass, so give each class a clear name. -
parameters.fileSystemId— the id of the file system you created. It must be present, and it must match exactly. SecurSpaces also uses these ids to tell the file systems it shares from external ones, so a blank or mistyped value costs more than the one class. Check it before anyone uses the class. -
mountOptions: [tls]— a top-level list, a sibling ofparameters, not a key inside it. -
volumeBindingMode: Immediate— EFS and S3 Files are zoneless. A class set toWaitForFirstConsumercan never bind and the create is rejected.
Optional values include basePath, subPathPattern, directoryPerms, and the pair gidRangeStart and
gidRangeEnd, which bound the POSIX group id the access point enforces. Set both or neither. Keep a custom range
wide enough for every Mount Point planned on that file system, because each access point consumes one group id.
One file system and one StorageClass serve many Mount Points. Add more only when you exceed the access point ceiling, need throughput isolation, or need hard tenant isolation.
Check the file system id
Nothing validates fileSystemId against AWS when you author the class. SecurSpaces accepts whatever you write and
acts on it only when a user creates or attaches a Mount Point. A blank value and a wrong value then fail in
different ways.
A blank value fails closed, and the effect is not limited to the class that carries it. One Mount Point
StorageClass with no fileSystemId makes SecurSpaces treat its whole picture of which file systems it shares as
unreliable, so it refuses rather than guess: the attach mode in which a user types raw coordinates is denied for
every class on the cluster, including attaches onto file systems unrelated to the incomplete one.
A wrong value does not immediately switch the protection off. SecurSpaces recognizes the file systems it shares from two independent signals: the ids declared on your Mount Point StorageClasses, and the file systems it has already provisioned Mount Points on in that region. A typo alone does not un-share the real file system. The risk is the window in which the second signal is empty — a file system SecurSpaces has never provisioned on, or one where every Mount Point it created there failed its post-bind identity check. In that window a wrong id makes the real shared file system look external, and a pre-built volume covering the whole of it becomes attachable by an ordinary user.
Read the id back from AWS before anyone uses the class:
aws efs describe-file-systems --file-system-id <fs-id> --query 'FileSystems[0].FileSystemId'
<!--NeedCopy-->
Encryption in transit
EFS and S3 Files are mounted over NFS on port 2049, and the CSI driver only encrypts that traffic when the mount
carries the tls option. Set it on the StorageClass and on every PersistentVolume you author. Without it, every
byte read or written travels unencrypted.
SecurSpaces keys strictly on the literal tls mount option. It does not accept parameters.encryptInTransit, a
TLS-enabled access point, or an EFS file system policy that enforces SecureTransport as substitutes.
How strictly this is enforced differs by mode:
-
Attach Existing fails closed. At bind time SecurSpaces reads the volume you named and refuses the attach unless it
is an
efs.csi.aws.comvolume whose mount options containtls. -
Create New is best-effort. A StorageClass without
tlsis normally hidden from the Create New list, and naming it anyway is rejected. All of these checks depend on reading the StorageClass from the Kubernetes API.
Warning
The StorageClass read is made by the workspace service. If it cannot read StorageClasses, every Create New encryption check is skipped, a StorageClass without
tlsbecomes usable, and the mount runs unencrypted with no error. This is the one failure in this article that fails in the permissive direction.
Cluster permissions
StorageClasses and PersistentVolumes are both cluster-scoped, so the grant that lets the workspace service read
them has to be a ClusterRole. The chart installs it as a ClusterRole and a ClusterRoleBinding, both named
<release>-workspace-api-clusterwide, bound to the workspace service account <release>-workspace-api. For
everything else the platform reaches on the cluster, see
Trust boundaries.
Mount Points depend on these read permissions:
| Resource | Verbs | What depends on it |
|---|---|---|
storageclasses |
get, list
|
Listing the classes offered in Create New, and the encryption in transit check |
persistentvolumes |
get, list
|
Reading back the volume a new Mount Point was given, and listing the volumes offered by Attach Existing |
Two Helm settings take the grant away. Setting
platform.serviceKubernetesConfig.serviceAccounts.wsAPIServiceAccount to your own service account means the chart
installs none of the workspace service RBAC objects, so you must create and bind the equivalent permissions
yourself. Setting platform.serviceKubernetesConfig.rbac.createWorkspaceClusterRoles to false removes the whole
ClusterRole and its binding: not only the StorageClass read, but the PersistentVolume read, the PersistentVolume
write verbs that allowPersistentVolumeAccess would otherwise add, and read access to nodes and node metrics. The
namespace-scoped Role the chart installs alongside it is not affected by that setting.
Verify each verb separately. Kubernetes list does not imply get:
kubectl auth can-i get storageclasses --as=system:serviceaccount:<namespace>:<release>-workspace-api
kubectl auth can-i list storageclasses --as=system:serviceaccount:<namespace>:<release>-workspace-api
kubectl auth can-i get persistentvolumes --as=system:serviceaccount:<namespace>:<release>-workspace-api
kubectl auth can-i list persistentvolumes --as=system:serviceaccount:<namespace>:<release>-workspace-api
<!--NeedCopy-->
--as impersonates another identity, which needs cluster-admin or an impersonate grant of your own. On a default
install you can also confirm that the objects carrying the grant are present:
kubectl get clusterrole,clusterrolebinding <release>-workspace-api-clusterwide
<!--NeedCopy-->
If you supplied wsAPIServiceAccount, neither of those objects exists and the chart never creates
<release>-workspace-api, so the commands above report no for an account nothing runs under. Substitute the
account you supplied, which you can read from the running pod:
kubectl -n <namespace> get pod -l app=<release>-workspace-api -o jsonpath='{.items[0].spec.serviceAccountName}'
<!--NeedCopy-->
What each missing permission costs:
- Missing
getonstorageclassesskips the encryption checks and allows an unencrypted mount. - Missing
listonstorageclassesbreaks discovery entirely: the create list is empty and the feature disappears. - Missing
getonpersistentvolumeslets every Create New Mount Point reach ready without its volume being read back, so the Mount Point holds no record of the volume it was provisioned on. - Missing
listonpersistentvolumesbreaks the Attach Existing volume picker, which shows Failed to load available volumes and a Retry link. That is a different state from No volumes available to attach, which means the read succeeded and no volume matched the scope label.
Enable the feature
Mount Point Storage is enabled at System Configuration > Integrations > Mount Point Storage. System Configuration is an administrator-only area. A security officer who is not also an administrator cannot enable it.
- The cloud provider is detected, not chosen. SecurSpaces derives whether Mount Points are backed by AWS or Azure from the CSI provisioners of the StorageClasses on the cluster. To expose the AWS options, create AWS Mount Point StorageClasses first.
- Turn on the file storage switch. While it is off, the create flow is hidden from users.
- Use one cloud per cluster. If both an AWS and an Azure Mount Point StorageClass are present, the provider cannot be resolved, the switches are forced off, and the feature is withdrawn. The page explains this and lists the providers it detected. Remove one cloud’s classes and revisit the page. No restart is needed, but allow about 30 seconds for the configuration cache.
-
allowPersistentVolumeAccessgoverns one attach mode. The mode in which a user types raw coordinates and SecurSpaces builds the volume requiresplatform.serviceKubernetesConfig.rbac.allowPersistentVolumeAccess, which defaults tofalse. While it is off, that mode is hidden, but attaching a volume you authored and creating new Mount Points both still work. The change takes effect whenhelm upgradecompletes, with no pod restart.
Note
Only this page explains why Mount Points are unavailable. In the project and workspace views the option is simply hidden. Triage any report of missing Mount Points by opening this page first.
Next
- Author a PersistentVolume, if you publish your own volumes
- Troubleshooting