tools.manage_api_keys module

Per-user API key management + global/channel API key pools (v4)

Per-user keys follow the user across channels and servers. Pool keys are shared – either globally or scoped to a single channel.

Resolution order: user key -> channel pool -> global pool -> env/config

Redis key patterns:

stargazer:user_api_keys:{user_id} (per-user hash) stargazer:global_api_pool:{service} (global pool hash) stargazer:channel_api_pool:{channel_id}:{service} (channel pool hash)

API keys are encrypted at rest (AES-256-GCM) with per-user keys stored in SQLite.

tools.manage_api_keys.missing_api_key_error(service)[source]

Return a verbose, actionable error message for a missing API key.

Intended to be called by consumer tools when get_user_api_key returns None. The message includes the service display name, signup URL (when known), and the exact set_user_api_key command so the LLM can relay it to the user.

Return type:

str

Parameters:

service (str)

async tools.manage_api_keys.check_default_key_limit(user_id, tool_name, redis_client, daily_limit=20)[source]

Check whether user_id is within the daily default-key usage limit.

Returns (allowed, current_count, daily_limit).

Return type:

tuple[bool, int, int]

Parameters:
  • user_id (str)

  • tool_name (str)

  • daily_limit (int)

async tools.manage_api_keys.increment_default_key_usage(user_id, tool_name, redis_client)[source]

Increment the daily usage counter after a successful default-key call.

Return type:

None

Parameters:
  • user_id (str)

  • tool_name (str)

tools.manage_api_keys.default_key_limit_error(tool_name, current, limit)[source]

Return an error message when the daily default-key limit is exceeded.

Return type:

str

Parameters:
async tools.manage_api_keys.get_gitea_credentials(user_id, *, redis_client=None, channel_id=None, fallback_to_pool=True, config=None)[source]

Return (token, base_url) for Gitea, or None.

Resolution order: user key -> channel pool -> global pool. Parses plain token or JSON {“token”: “…”, “base_url”: “…”}.

Return type:

tuple[str, str] | None

Parameters:
  • user_id (str)

  • channel_id (str | None)

  • fallback_to_pool (bool)

async tools.manage_api_keys.get_pool_api_key(service, *, redis_client=None)[source]

Pick a random key from the global pool for service, or None.

Return type:

str | None

Parameters:

service (str)

async tools.manage_api_keys.get_channel_pool_api_key(channel_id, service, *, redis_client=None)[source]

Pick a random key from the channel pool for service, or None.

Return type:

str | None

Parameters:
  • channel_id (str)

  • service (str)

async tools.manage_api_keys.get_user_api_key(user_id, service, *, redis_client=None, channel_id=None, fallback_to_pool=True, config=None)[source]

Return the best available API key for service.

Resolution order: user key -> channel pool -> global pool.

Return type:

str | None

Parameters:
  • user_id (str)

  • service (str)

  • channel_id (str | None)

  • fallback_to_pool (bool)