Skip to content

from_env() eagerly evaluates try_from_env() even when caller passes auth= #316

Closed

Description

@TexasCoding

Problem

KalshiClient.from_env (and the async counterpart) uses kwargs.setdefault("auth", KalshiAuth.try_from_env()). dict.setdefault evaluates its default unconditionally, so try_from_env() runs every time — including reading KALSHI_KEY_ID + KALSHI_PRIVATE_KEY and calling load_pem_private_key on the result.

A CI container with KALSHI_KEY_ID exported and a stale / truncated KALSHI_PRIVATE_KEY lingering from a previous run cannot be unblocked by passing from_env(auth=KalshiAuth.from_pem(...)) — the eager call still raises KalshiAuthError("Invalid PEM private key: ...") before the explicit auth has a chance to win. Also a minor key-hygiene issue: the env PEM is decoded into a cryptography RSAPrivateKey the caller never asked for and immediately discards.

Evidence

  • kalshi/client.py:182
kwargs.setdefault("auth", KalshiAuth.try_from_env())
  • kalshi/auth.py:215-236 — try_from_env always loads and parses the PEM when KALSHI_KEY_ID is set
key_id = os.environ.get("KALSHI_KEY_ID")
if not key_id:
    return None
...
pem_string = os.environ.get("KALSHI_PRIVATE_KEY")
...
if pem_string:
    return cls.from_pem(key_id, pem_string, password=resolved_password)

Suggested fix

Replace the setdefault with an explicit check:

if "auth" not in kwargs:
    kwargs["auth"] = KalshiAuth.try_from_env()

Apply the same edit to AsyncKalshiClient.from_env. Add a regression test that sets a malformed KALSHI_PRIVATE_KEY in the env, passes auth=<explicit> to from_env, and asserts no KalshiAuthError is raised.

Source

Round-3 independent audit (reviewer: security_auth).

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