Making API keys completely write only for the frontend

This commit is contained in:
Cole Medin
2025-09-06 15:43:02 -05:00
committed by Wirasm
parent 926b6f5a7b
commit 192c45df11
4 changed files with 86 additions and 53 deletions

View File

@@ -139,11 +139,12 @@ OPTIONAL_SETTINGS_WITH_DEFAULTS = {
@router.get("/credentials/{key}")
async def get_credential(key: str, decrypt: bool = True):
async def get_credential(key: str):
"""Get a specific credential by key."""
try:
logfire.info(f"Getting credential | key={key} | decrypt={decrypt}")
value = await credential_service.get_credential(key, decrypt=decrypt)
logfire.info(f"Getting credential | key={key}")
# Never decrypt - always get metadata only for encrypted credentials
value = await credential_service.get_credential(key, decrypt=False)
if value is None:
# Check if this is an optional setting with a default value
@@ -162,16 +163,17 @@ async def get_credential(key: str, decrypt: bool = True):
logfire.info(f"Credential retrieved successfully | key={key}")
# For encrypted credentials, return metadata instead of the actual value for security
if isinstance(value, dict) and value.get("is_encrypted") and not decrypt:
if isinstance(value, dict) and value.get("is_encrypted"):
return {
"key": key,
"value": "[ENCRYPTED]",
"is_encrypted": True,
"category": value.get("category"),
"description": value.get("description"),
"has_value": bool(value.get("encrypted_value")),
}
# For non-encrypted credentials, return the actual value
return {"key": key, "value": value, "is_encrypted": False}
except HTTPException:

View File

@@ -303,7 +303,7 @@ class CredentialService:
key = item["key"]
if item["is_encrypted"]:
credentials[key] = {
"encrypted_value": item["encrypted_value"],
"value": "[ENCRYPTED]",
"is_encrypted": True,
"description": item["description"],
}
@@ -330,31 +330,16 @@ class CredentialService:
credentials = []
for item in result.data:
# For encrypted values, decrypt them for UI display
if item["is_encrypted"] and item["encrypted_value"]:
try:
decrypted_value = self._decrypt_value(item["encrypted_value"])
cred = CredentialItem(
key=item["key"],
value=decrypted_value,
encrypted_value=None, # Don't expose encrypted value
is_encrypted=item["is_encrypted"],
category=item["category"],
description=item["description"],
)
except Exception as e:
logger.error(f"Failed to decrypt credential {item['key']}: {e}")
# If decryption fails, show placeholder
cred = CredentialItem(
key=item["key"],
value="[DECRYPTION ERROR]",
encrypted_value=None,
is_encrypted=item["is_encrypted"],
category=item["category"],
description=item["description"],
)
cred = CredentialItem(
key=item["key"],
value="[ENCRYPTED]",
encrypted_value=None,
is_encrypted=item["is_encrypted"],
category=item["category"],
description=item["description"],
)
else:
# Plain text values
cred = CredentialItem(
key=item["key"],
value=item["value"],