Skip to content
13 changes: 8 additions & 5 deletions config/clusters/nasa-cryo/enc-prod.secret.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ basehub:
GitHubOAuthenticator:
client_id: ENC[AES256_GCM,data:ilEVTmjN83Y3YnOlBKjA9EOfUuM=,iv:C8143cwC6pB0sFueQq7T1XbbmABAHu6kiLnxbZy9hVc=,tag:Jc34Po9xZZShfq5l/2CEbQ==,type:str]
client_secret: ENC[AES256_GCM,data:cSq7uA39SxQ9wIXAWp2FkEkGuzPXHCixp6iwRnkya9YngnUhufpIYg==,iv:dSXXOKhEt/ipOD1bWhcghks+Mjpn2oUexzJhjwEt6ek=,tag:8woToirTzLvX1WqHjbLpGw==,type:str]
singleuser:
extraEnv:
OPENAI_API_KEY: ENC[AES256_GCM,data:ulPwQMrB/YKEuQXBtUqkP+jV2sLZekcL6+FqcfJELclaOhs=,iv:LYLQe7s7d+1Kk8qL33KelhHQeegkDJgpQ0fohDmPVCU=,tag:7d6ytBPtAjhBjOnxoEjSHg==,type:str]
sops:
gcp_kms:
- resource_id: projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs
created_at: '2022-10-19T12:21:15Z'
- created_at: '2022-10-19T12:21:15Z'
enc: CiQA4OM7eHhdeYFpxkSDTcwgJSCnGcXyuW+RXURXZyqVtBExJLgSSQDuy/p8cJdVxnALmGegCdGggKwgIqy27Dtr97EyJnjFxmQMGDQsWh3vL/2xXyL4Gw8E1cYoxh7r+ecwI4YmBOO+q6rBIM2fS4I=
lastmodified: '2026-03-31T14:55:21Z'
mac: ENC[AES256_GCM,data:wwlczyiNjirxU0QTDLo5qrcxjdRJPqyvzL0FW62iL2bSIMTB0vR8fAeo9aLfEIG6jA1Z7cgG49qJ/78vN5rhZc4H3rpHlWo8UlY4dbekGTJEw8U2bG8mH8flG/5tLovFXtdjowk+VlN9iMQaserHBiOA7LOkqp/Zz5CLdnOXjzY=,iv:/koEBxl1OdlmEupIvbvXjWrzXmwwQ33R+dfLOOeLWJ0=,tag:wfTHzQZq2zyDeMmx8m6YrA==,type:str]
resource_id: projects/two-eye-two-see/locations/global/keyRings/sops-keys/cryptoKeys/similar-hubs
lastmodified: '2026-08-19T22:17:09Z'
mac: ENC[AES256_GCM,data:PPNMIh49USEArsmFKPifQDLSIA5UBD3cmFQ0GSuJgD6SFIrLe+zyrwBq/3BP/89hAKAL8r0NxYL3bWKtN+NB0lvO4JSQhkbuwafYSHfhT6KZRz+3hugUryTA5GonFDfJkAsZy5X1Ho7Oki5eUAFL4USYm8y/fhj6QVbtretYeX8=,iv:vOh/v4CUGbh3DRaEf6rUUC1iPt7pppQrQ72dhHmQ2yc=,tag:I6zmo5y6wfeK3jiEJtiZEQ==,type:str]
unencrypted_suffix: _unencrypted
version: 3.11.0
version: 3.13.3
48 changes: 48 additions & 0 deletions config/clusters/nasa-cryo/prod.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,54 @@ basehub:
SCRATCH_BUCKET: s3://nasa-cryo-scratch/$(JUPYTERHUB_USER)
PANGEO_SCRATCH: s3://nasa-cryo-scratch/$(JUPYTERHUB_USER)
PERSISTENT_BUCKET: s3://nasa-cryo-persistent/$(JUPYTERHUB_USER)
OPENCODE_CONFIG: /etc/opencode-default/opencode.json
extraFiles:
# Opencode config for the NRP model provider.
# opencode itself is installed by the CryoCloud AI image, I think that's here:
# https://github.com/CryoInTheCloud/image-cryo-python-AI/blob/e80c8f17fbfcac53ddf1cd1c51f515915b31441c/appendix#L26-L29

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not totally clear to me how users are meant to use the image that has opencode etc - are you just going to ask people to use the dynamic image builder UI to past the link to the repo themselves? We should document where that repo is in the config - I took a stab at this but you should confirm that I'm right

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would use the Custom image profile option, and paste the Docker image string.

opencode:
mountPath: /etc/opencode-default/opencode.json
data:
$schema: https://opencode.ai/config.json
model: nrp/kimi
disabled_providers:
- opencode
provider:
nrp:
npm: '@ai-sdk/openai-compatible'
name: NRP
options:
baseURL: https://ellm.nrp-nautilus.io/v1
apiKey: '{env:OPENAI_API_KEY}'

@choldgraf choldgraf Aug 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried that putting the key to an env variable would make the API visible to all users of a hub (not on github, but in an authenticated user session), which feels like a security risk, but it seems like something we already do for other communities so I'm assuming it's fine - eg JupyterHealth has the same pattern:

https://github.com/search?q=repo%3A2i2c-org%2Finfrastructure+openai&type=code

@tsnow03 should probably know about this though! I think any user of the cryocloud hub will be able to view and potentially exfiltrate this key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is a risk. I'd like to find better ways to handle API keys, but it would likely require us to support something like using a Hub as an OIDC provider (which isn't yet supported).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there is a general purpose application that I think will benefit the JupyterHub community that is an auth proxy that allows JupyterHub tokens to be used to access a REST API via a proxy which uses a credential to access the upstream API.

But in the absence of that, these shared credential approaches are okay in that you are sharing a single managed credential with all users. I talked to @tsnow03 about this a bit ago, and it's a question of trust and mitigation: to what extent do you trust the users of this hub with that credential (they can absolutely take this and use NRP LLM resources from their home machine), and mitigating that by rotating this key. An NRP LLM token is not the most precious resource because it is not billed and probably most cryocloud users would have access to it themselves if they bothered to go through the process of asking for an account, so there is little benefit to exfiltration in this particular case. If the resource protected by this token were either not likely to be available to most users of the hub and/or if there was a cost risk associated with abuse

Key rotation is not easily facilitated by storing the key in SOPS and requiring 2i2c folks to set the secret value, which Tasha has to retrieve from NRP, so this is likely to be infrequent, but can be done on a time scale Tasha feels is appropriate for mitigating that risk. For example, the hub this is copied from runs with a relatively small number of reasonably trusted users, but when we use it to host a workshop, for example, I rotate the keys immediately afterward.

models:
kimi:
name: kimi
limit:
context: 262144
output: 32768
options:
chat_template_kwargs:
thinking: true
preserve_thinking: true
variants:
instruct:
chat_template_kwargs:
thinking: false
preserve_thinking: false
qwen3:
name: qwen3
qwen3-small:
name: qwen3-small
gpt-oss:
name: gpt-oss
gemma:
name: gemma
gemma-small:
name: gemma-small
glm-5:
name: glm-5
minimax-m2:
name: minimax-m2
jupyterhub-home-nfs:
eks:
volumeId: vol-00b9cf4a258bce8ef
Expand Down
Loading