-
Notifications
You must be signed in to change notification settings - Fork 28
Open
Description
Summary
API keys and other sensitive credentials are currently displayed in plain text in the Web UI's provider settings screens. This applies to:
- Custom Models modal — The API key input field uses
type="text", and the backend GET endpoints return the full API key in JSON responses. - Notification Channels modal — Sensitive config fields like Discord webhook URLs are similarly displayed as plain text inputs.
This means API keys are visible on screen, in browser DevTools network logs, and in any client-side state.
Current Behavior
ModelsModal.tsxrenders the API key in atype="text"input (line 391)- The
GET /api/custom-modelsendpoint returns the fullapi_keyvalue in the JSON response (toModelAPIincustom_models.go) - When editing an existing model, the full key is loaded from the API response into the form
- Discord webhook URLs in
NotificationsModal.tsxare rendered as regular text inputs
Suggested Approach
Here's one possible direction — happy to discuss alternatives:
Backend
- Mask API keys in GET responses: Modify
toModelAPI()to return a masked version of the key (e.g.sk-a••••xZ9f— first 4 + last 4 characters). This prevents the full key from ever reaching the client on read operations. - Preserve existing keys on update: The update handler already supports keeping the existing key when
api_keyis empty. This could be extended to also detect when the masked value is sent back unchanged. - Notification channels: Add a
sensitiveflag toConfigFieldand apply the same masking pattern to sensitive config values (e.g. Discord webhook URLs). The update handler would need to merge sensitive fields so that masked values sent back from the client are replaced with the stored originals.
Frontend
- Use
type="password"for sensitive inputs: Switch the API key input totype="password". When editing, start with the field empty and use a placeholder like "Leave blank to keep current key". - Relax edit-mode validation: Currently
handleSaverequiresapi_keyeven when editing. This could be changed to only require it for new models, since the backend preserves the existing key when the field is empty. - Notification channels: Use the
sensitiveflag fromConfigFieldmetadata to dynamically render sensitive fields as password inputs with the same empty-on-edit pattern.
Existing patterns that help
handleUpdateModelalready preserves the existing key whenapi_keyis empty (line 216-220 ofcustom_models.go)handleTestModelalready acceptsmodel_idto look up the stored key server-side, so testing works without sending the key from the clienthandleDuplicateModelcopies the key server-side — the frontend never sends it
Affected Files
server/custom_models.goserver/notification_channels.goui/src/components/ModelsModal.tsxui/src/components/NotificationsModal.tsxui/src/services/api.ts
Thank you for building Shelley.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels