I would like to place jupyter_myextension_config.py with sensitive config values in the single server filesystem so that it is:
read by the server, but
not accessibly by the user
It seems that singleuser.extraFiles does (or almost does) what I want - I was able to modify the mode of the files in /etc/jupyter to 440 but then upon seeing it belongs to users group I realised that I need 400 assuming that the single server is started by a user with different privilages that the user which accesses it. Two questions:
which OS user spawns the server? How can I check this? If it is the same user as the user that is given to the person who accesses the server, can these two be separated in a way?
after I set the mode to 440 I do not seem to be able to change it to 400. I guess that the Helm chart may not be updating the file permissions even after redeploying/manually restarting pods. Is it correct or am I missing something?
Manually deleting the secret is helpful butit did not solve my problem fully (kubectl delete secret -n namespace singleuser). I saw that the file has 660 despite me requesting 440.
The helm chart code sets mode on the secret:
but I could not find documentation for this key, I only see defaultMode documented here.
The kubernetes documentation helped me by pointing out that in JSON I need to pass decimal rather than octal value. Still, the permissions were not fully respected. It appears that the entire thing has many gotchas.
In particular, it seems impossible to remove the read permission from group when Pod.spec.securityContext.runAsUser is set. I see that exact same issue reported in kubernetes with 33 upvotes:
quote:
Given a defaultMode of 256 the file mode should be 0400 but it is 0440 instead.
Also relevant is the request for kubernetes to support setting ownership on mounted secrets, which has 180 upotes - one of the most requested k8s feature apparently:
It’s going to be tricky to be absolutely sure the user can’t access the secret information, especially since the singleuser-server (i.e. JupyterLab, all kernels, terminals, extensions, etc) run as the same user.
Assuming you’ve got a way of dealing with that, one option is to start the container as root, run some setup steps, and drop to an unprivileged user before starting the singleuser server.
The docker-stacks images have an example of this- you can start the container as root and pass a custom username/uid/etc:
If you set the owner and permissions of a parent directory in the image to root, and mount the secrets into a subdirectory, I think the permissions on the parent directory should prevent the unprivileged user from reaching the mounted secret since they won’t have access to the parent directory.