tools.manage_secrets module
Per-user secrets management.
Users can store named secrets (passwords, auth tokens, private keys, etc.) encrypted per-user. Other tools can reference secrets by name using the secret:name prefix in credential parameters; the registry resolves these transparently before the handler runs.
Redis key: stargazer:user_secrets:{user_id} Secrets are encrypted at rest (AES-256-GCM) with per-user keys in SQLite.
- async tools.manage_secrets.resolve_user_secret(user_id, secret_name, *, redis_client=None, config=None)[source]
Decrypt and return one of a user’s stored secrets, or None if absent.
This is the public read path other tools use to dereference a
secret:namecredential before their handler runs. It validates the name, reads the ciphertext field from the user’s Redis secrets hash, and decrypts it with the per-user key derived from the master key. Designed to fail soft: any missing secret, unconfigured master key, or decryption error yieldsNonerather than raising, so credential resolution never crashes a caller.Issues
HGETagainst the hash named by_redis_key()(stargazer:user_secrets:{user_id}) via the supplied Redis client. A legacy plaintext value (failingapi_key_encryption.is_encrypted()) is returned as-is. Otherwise it resolves the master key withresolve_master_key(), derives the user key viaget_or_create_user_key()(reading the SQLite store atconfig.api_key_encryption_db_pathor_DEFAULT_ENCRYPTION_DB_PATH), and runs the blockingdecrypt()in a worker thread. Failures are logged vialogger.exception/logger.warning.Called by
_get_secret()in this module and, more importantly, by thesecret:nameresolution path intools/__init__.py(which importsSECRET_REF_PREFIXandresolve_user_secretto rewrite credential parameters before dispatching a tool handler).- Parameters:
- Returns:
The decrypted secret value, or
Noneif it is missing, the inputs are incomplete, the master key is unset, or decryption fails.- Return type: