Skip to content

Auth: conflicting key inputs (constructor + env) silently prefer one without warning #249

Closed

Description

@TexasCoding

Summary

Two places where the SDK silently picks one credential source when the caller passes two:

  1. Constructor: if both private_key_path= and private_key= are passed, the path wins and the PEM string is silently ignored.
  2. Environment: if both KALSHI_PRIVATE_KEY and KALSHI_PRIVATE_KEY_PATH are exported (common during CI key-rotation or dev/prod overlap), the inline PEM wins.

In either case the caller cannot tell which key is actually in use, which complicates key-rotation incident response: 401/403 failures look like a Kalshi-side credential issue when they are really an SDK precedence accident.

Location

  • kalshi/client.py:73-80 — sync constructor elif chain
  • kalshi/async_client.py:73-80 — async mirror
  • kalshi/auth.py:168-184 — from_env env-var pickup
  • kalshi/auth.py:200-217 — try_from_env

Evidence

# client.py constructor:
elif key_id and private_key_path:
    self._auth = KalshiAuth.from_key_path(key_id, private_key_path)
elif key_id and private_key:
    self._auth = KalshiAuth.from_pem(key_id, private_key)
else:
    self._auth = None

# auth.py env path:
pem_string = os.environ.get("KALSHI_PRIVATE_KEY")
if pem_string:
    return cls.from_pem(key_id, pem_string, password=resolved_password)
key_path = os.environ.get("KALSHI_PRIVATE_KEY_PATH")
if key_path:
    return cls.from_key_path(key_id, key_path, password=resolved_password)

Recommended fix

  • Constructor: raise ValueError("Provide either private_key_path or private_key, not both.") when both are non-None.
  • Env: raise KalshiAuthError naming both env-var names when both are populated to non-empty values.

Add regression tests for both cases.

Severity & category

medium / api-design, security

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsecuritySecurity-related concern

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions