Skip to content

Commit

Permalink
fix: add user secret key when using saved secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
olevski committed Nov 8, 2024
1 parent 09b2dfa commit e8be05d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,20 +151,24 @@ def secret(
namespace: str,
labels: dict[str, str] | None = None,
annotations: dict[str, str] | None = None,
user_secret_key: str | None = None,
) -> client.V1Secret:
"""The secret containing the configuration for the rclone csi driver."""
string_data = {
"remote": self.name or base_name,
"remotePath": self.source_path,
"configData": self.config_string(self.name or base_name),
}
if user_secret_key:
string_data["secretKey"] = user_secret_key
return client.V1Secret(
metadata=client.V1ObjectMeta(
name=base_name,
namespace=namespace,
annotations=annotations,
labels={"name": base_name} | (labels or {}),
),
string_data={
"remote": self.name or base_name,
"remotePath": self.source_path,
"configData": self.config_string(self.name or base_name),
},
string_data=string_data,
)

def get_manifest_patch(
Expand Down
20 changes: 19 additions & 1 deletion components/renku_data_services/notebooks/blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
renku_2_make_server_name,
)
from renku_data_services.notebooks.utils import (
get_user_secret,
merge_node_affinities,
node_affinity_from_resource_class,
tolerations_from_resource_class,
Expand Down Expand Up @@ -342,9 +343,26 @@ async def _handler(
secrets_to_create: list[V1Secret] = []
# Generate the cloud starge secrets
data_sources: list[DataSource] = []
user_secret_key: str | None = None
if isinstance(user, AuthenticatedAPIUser) and len(dcs_secrets) > 0:
user_secret_key = await get_user_secret(self.nb_config.data_service_url, user)
for cs_id, cs in dcs.items():
secret_name = f"{server_name}-ds-{cs_id.lower()}"
secrets_to_create.append(cs.secret(secret_name, self.nb_config.k8s_client.preferred_namespace))
secret_key_needed = len(dcs_secrets.get(cs_id, [])) > 0
if secret_key_needed and user_secret_key is None:
raise errors.ProgrammingError(
message=f"You have saved storage secrets for data connector {cs_id} "
f"associated with your user ID {user.id} but no key to decrypt them, "
"therefore we cannot mount the requested data connector. "
"Please report this to the renku administrators."
)
secrets_to_create.append(
cs.secret(
secret_name,
self.nb_config.k8s_client.preferred_namespace,
user_secret_key=user_secret_key if secret_key_needed else None,
)
)
data_sources.append(
DataSource(
mountPath=cs.mount_folder,
Expand Down
19 changes: 19 additions & 0 deletions components/renku_data_services/notebooks/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Utilities for notebooks."""

import httpx

import renku_data_services.crc.models as crc_models
from renku_data_services.base_models.core import AuthenticatedAPIUser
from renku_data_services.notebooks.crs import (
MatchExpression,
NodeAffinity,
Expand All @@ -10,6 +13,7 @@
RequiredDuringSchedulingIgnoredDuringExecution,
Toleration,
)
from renku_data_services.utils.cryptography import get_encryption_key


def merge_node_affinities(
Expand Down Expand Up @@ -95,3 +99,18 @@ def tolerations_from_resource_class(resource_class: crc_models.ResourceClass) ->
for tol in resource_class.tolerations:
output.append(Toleration(key=tol, operator="Exists"))
return output


async def get_user_secret(data_svc_url: str, user: AuthenticatedAPIUser) -> str | None:
"""Get the user secret key from the secret service."""

async with httpx.AsyncClient(timeout=5) as client:
response = await client.get(
f"{data_svc_url}/user/secret_key",
headers={"Authorization": f"Bearer {user.access_token}"},
)
if response.status_code != 200:
return None
user_key = response.json()

return get_encryption_key(user_key["secret_key"].encode(), user.id.encode()).decode("utf-8")
7 changes: 4 additions & 3 deletions components/renku_data_services/utils/cryptography.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC


def _get_encryption_key(password: bytes, salt: bytes) -> bytes:
def get_encryption_key(password: bytes, salt: bytes) -> bytes:
"""Create an encryption key with the password and salt."""
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
Expand All @@ -25,13 +26,13 @@ def generate_random_encryption_key() -> bytes:

def encrypt_string(password: bytes, salt: str, data: str) -> bytes:
"""Encrypt a given string."""
key = _get_encryption_key(password=password, salt=salt.encode())
key = get_encryption_key(password=password, salt=salt.encode())
return Fernet(key).encrypt(data.encode())


def decrypt_string(password: bytes, salt: str, data: bytes) -> str:
"""Decrypt a given string."""
key = _get_encryption_key(password=password, salt=salt.encode())
key = get_encryption_key(password=password, salt=salt.encode())
return Fernet(key).decrypt(data).decode()


Expand Down

0 comments on commit e8be05d

Please sign in to comment.