# Canonical way of confidentially storing user credentials for databases in JupyterHub

**URL:** <https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890>\
**Category:** JupyterHub\
**Created:** [February 4, 2022, 2:08pm UTC](https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890 "2022-02-04T14:08:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thomas\_Browne](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/thomas_browne/32/6347_2.png) [@Thomas\_Browne](https://discourse.jupyter.org/u/Thomas_Browne)\
**Post date:** [February 4, 2022, 2:08pm UTC](https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890/1 "2022-02-04T14:08:21Z")

</div>

I am deploying JupyterHub for multiple users in my firm, each user has separate database credentials. I want to use these credentials in the spawned JupyterLabs. What is the canonical way of doing this? I don’t want to store plaintext credentials on drive, and user environment variables are not passed through to Jupyter notebooks efficiently ([see my other question](https://discourse.jupyter.org/t/jupyterhub-is-not-reloading-users-jupyter-jupyter-notebook-config-py-files-unless-i-restart-the-whole-hub/12873)) so that’s out of the question too.

So can I “tap in” to the PAMauthenticator, for example, to get a hashed Linux password in order to use that as an encryption key? How do I go about this job of authenticating each user to outside services, without storing plaintext credentials in their home directories?

The outside service, in my case fwiw, is InfluxDB. Ideally I want a user’s credentials “unlocked” when they’re PAM-authenticated by the hub.

---

<div class="post-metadata">

**Author:** ![1kastner](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/1kastner/32/1537_2.png) [@1kastner](https://discourse.jupyter.org/u/1kastner)\
**Post date:** [February 5, 2022, 11:24pm UTC](https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890/2 "2022-02-05T23:24:53Z")

</div>

It pretty much depends on the spawner you use. For a better understanding, please share your configuration (preferably a minimal example).

The spawner often allows to execute some code before the user notebook ui is spawned. You could use that hook. I believe a more canonical approach would be to use something like vault so that no password but just a token is stored on the system.

---

<div class="post-metadata">

**Author:** ![Thomas\_Browne](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/thomas_browne/32/6347_2.png) [@Thomas\_Browne](https://discourse.jupyter.org/u/Thomas_Browne)\
**Post date:** [February 5, 2022, 11:56pm UTC](https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890/3 "2022-02-05T23:56:52Z")

</div>

I am using the a completely standard installation, so whatever the default spawner is for multiple users of a Linux system (PAMauthenticator) is what I am using.

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [February 6, 2022, 2:49pm UTC](https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890/4 "2022-02-06T14:49:23Z")

</div>

You can use `auth_state` to store objects that can be passed to the spawner:  
[https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html#authentication-state](https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html#authentication-state)

---

<div class="post-metadata">

**Author:** ![Thomas\_Browne](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/thomas_browne/32/6347_2.png) [@Thomas\_Browne](https://discourse.jupyter.org/u/Thomas_Browne)\
**Post date:** [February 6, 2022, 10:47pm UTC](https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890/5 "2022-02-06T22:47:18Z")

</div>

Do I have to write a custom authenticator though? Or can this be used in conjunction with the default Linux PAMauthenticator? Ie can I inherit the PAMauthenticator somehow and only override the `.authenticate()` method somehow? Or will I have to write all the authentication plumbing from scratch in order to achieve this?

---

<div class="post-metadata">

**Author:** ![manics](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/manics/32/85_2.png) [@manics](https://discourse.jupyter.org/u/manics)\
**Post date:** [February 8, 2022, 9:24pm UTC](https://discourse.jupyter.org/t/canonical-way-of-confidentially-storing-user-credentials-for-databases-in-jupyterhub/12890/6 "2022-02-08T21:24:17Z")

</div>

You can inherit from an existing authenticator and override just the methods you need.
