-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: expand documentation for secrets #3605
Merged
lorenzo-cavazzi
merged 12 commits into
release-0.52.x
from
build/secrets-in-sessions-docs
May 16, 2024
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
900e06d
chore: add images
lorenzo-cavazzi 56790fe
docs: add UI documentation
lorenzo-cavazzi 6f35c10
add technical details
Panaetius 1b07f68
fix spelling
Panaetius 2ddd153
update wording
Panaetius 8f6ed84
chore: add missing files
lorenzo-cavazzi 023e1f0
update docs with comments from the review
lorenzo-cavazzi 63a176b
more comments from the review
lorenzo-cavazzi c187e4a
chore: update changelog
lorenzo-cavazzi 7fcd977
change wording around k8s secrets
e8a07cd
chore: fix docs
lorenzo-cavazzi df19a33
Merge branch 'release-0.52.x' into build/secrets-in-sessions-docs
lorenzo-cavazzi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.. _secrets_topic_guides: | ||
|
||
Secrets | ||
======= | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
secrets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
.. _secrets: | ||
|
||
Secrets in RenkuLab | ||
=================== | ||
|
||
What are secrets? | ||
----------------- | ||
|
||
Secrets are sensitive data that you need in sessions but should | ||
not be stored in a repository. | ||
This includes passwords you might need for accessing a database, API keys | ||
for external services, or any other sensitive information. | ||
|
||
You can create, replace, and delete secrets from the RenkuLab interface. | ||
They are securely stored in our systems and are only available in sessions | ||
that you launch. They will be mounted as files in the session container in | ||
a path you can customize when starting a new session. | ||
Each secret is stored with a unique name, which will be used for the | ||
corresponding file name. | ||
|
||
Keep in mind that secrets are currently defined per user. They cannot be | ||
shared with other users, nor scoped down to a single project. You can select | ||
which secrets to use in a session when starting it, so you don't need | ||
to worry about accidentally mounting secrets into a session that you | ||
do not need. | ||
|
||
Add and change secrets | ||
---------------------- | ||
|
||
To add a new secret, go to the User Secrets page in the RenkuLab interface. | ||
You can find it in the user settings menu on the top right. | ||
|
||
.. image:: ../../_static/images/secrets_page.png | ||
:width: 85% | ||
:align: center | ||
:alt: User Secrets page | ||
|
||
Click on the ``Add New Secret`` button and fill in the ``Name`` and | ||
``Value`` fields. | ||
|
||
The name is a unique identifier for the secret, used for the file name in | ||
sessions. It cannot be empty and must follow these validation rules: | ||
you can include only letters, numbers, dots (.), underscores (_), | ||
and dashes (-). | ||
|
||
Values can be any non-empty string, including special characters. The length | ||
cannot exceed 5'000 characters. Should you need to store a longer value, | ||
consider splitting it into multiple secrets. | ||
|
||
.. image:: ../../_static/images/secrets_add_new.png | ||
:width: 85% | ||
:align: center | ||
:alt: Add a new secret | ||
|
||
Once you add a secret, you cannot see its value again for security | ||
reasons. You can still change it by clicking on the ``Replace`` button, | ||
or remove it by clicking on the ``Delete`` button. The name cannot be changed; | ||
should you need to rename a secret, please delete it and create a new one | ||
with the new name. | ||
|
||
Use secrets in sessions | ||
----------------------- | ||
|
||
To use secrets in a session, you need to click on the Start dropdown menu and | ||
select ``Start with options``. Quick-start sessions do not support secrets. | ||
|
||
Once on the "Start with options" page, you can select the secrets you want to | ||
include from the ``User Secrets`` section towards the bottom of the page. | ||
Click on the chevron on the right to expand the secrets list and click on | ||
every secret you want to include. You can customize the path where the | ||
secrets will be mounted in the session container by adjusting the | ||
``Mount path`` input. The default path is ``/secrets``. Mind that this is | ||
an absolute path; if you leave the default value, you will not find the folder | ||
in your repository and it might not be immediately accessible on the session | ||
file browser (E.G. JupyterLab). | ||
|
||
.. image:: ../../_static/images/secrets_selection.png | ||
:width: 85% | ||
:align: center | ||
:alt: Select secrets to mount in a new session | ||
|
||
Click on the ``Start Session`` button to start the session with the selected | ||
secrets. You can now access the secrets in the session container at the | ||
specified path. The secrets will be stored in files with the same name. | ||
|
||
.. note:: | ||
|
||
Secrets will be mounted with the value stored at the session start time. | ||
If you change the value of a secret after starting the session, you will | ||
need to restart the session to apply the changes. | ||
|
||
Security Model | ||
-------------- | ||
|
||
.. image:: ../../_static/images/secrets_encryption_decryption.gif | ||
:width: 85% | ||
:align: center | ||
:alt: Secrets encryption scheme | ||
|
||
Renku stores secrets in its database, doubly encrypted, ensuring that no part | ||
accessible from the internet other than the session has access to decrypted | ||
secrets. All secrets are encrypted at rest. | ||
|
||
Threat models we address are: | ||
- One of our public-facing services being breached | ||
- A malicious actor getting a copy of our database (for instance from a backup) | ||
|
||
We explicitly do not guard against: | ||
- Someone stealing your login details or login token | ||
- You starting a malicious session with secrets, as we can't control the code | ||
that runs within a session. | ||
|
||
The Renku ``data service`` uses symmetric Fernet encryption with a key only it | ||
knows to ensure all data is encrypted at rest in its database. | ||
For each user, a unique ``user key`` is generated. In addition, there is a | ||
dedicated ``secret storage service`` which has an RSA 2048 bit ``public key`` | ||
and a ``private key``, the latter of which is only known to this service. This | ||
service is not accessible to the public internet. | ||
|
||
When a user stores a secret, it is first symmetrically encrypted with the | ||
``user key``, using Fernet. We then generate a random ``secret key`` that is | ||
encrypted using the ``public key`` and passed to the ``secret storage | ||
service``, meaning only it can decrypt the ``secret key``. The users secret is | ||
then encrypted again using this ``secret key`` and stored in the database. | ||
At this point, the ``data service`` can't decrypt the user's secret anymore, as | ||
it does not know the ``secret key``. | ||
|
||
To decrypt a secret, ``secret storage service`` gets a request from ``notebooks | ||
service`` that a user would like to start a session with some secret mounted. | ||
It uses its ``private key`` to get the ``secret key`` and uses this to decrypt | ||
the outer layer of encryption of the secret. It then creates a Kubernetes | ||
secret with the (now encrypted once) user secret, which gets mounted in an | ||
init container in the user session. | ||
On session start, that init container reads the mounted secrets, and uses the | ||
``user key`` to undo the inner encryption. It then creates files inside the | ||
user session with the decrypted secret values. | ||
|
||
Note that, although we take many precautions to decrypt secrets only when | ||
necessary, they are in plain text inside a session. This means that they are | ||
visible to whoever has access to the infrastructure where the session is running. | ||
If your data is extra sensitive, consider putting already encrypted values into | ||
lorenzo-cavazzi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Renku and manually decrypting them once inside the session, with 3rd party | ||
encryption. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May I nitpick a bit ?
The Kubernetes secret is in fact only mounted in the init container that will decrypt its content. The session (if we are talking about the main container) will only see the volume containing the decrypted secrets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll let @Panaetius answer this technical aspect 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed the description a bit (I think this comment meant to address the previous paragraph, not this one)