Skip to content

Dev-minted LiteLLM keys hit the same foreign-environment noise class in the entitlement reconciler key stage #142

Closed

Description

@sre-helmcode

Context

PR helmcode/nan-cloud-api#292 (0.8.207) fixed the namespace half of the foreign-environment leak: dev platform-api provisions member namespaces into the shared cluster, and the prod reconciler now skips namespaces stamped nan.builders/environment != own environment.

The key stage has the same leak with no equivalent fix: dev's litellm-url points at the shared LiteLLM community proxy, so keys minted by dev QA members (via POST /api/keys) land in the prod LiteLLM_VerificationToken inventory. The reconciler attributes keys via user_id = member.user_uuid and alias = handle against the prod members table — a dev member's key never matches → permanent unattributable key finding, re-alerted every hourly pass.

Why it is not fixed yet

LiteLLM keys carry no free-form metadata axis equivalent to a k8s label that the reconciler could compare against the creating environment (options explored: key_name prefix convention — mutable and not enforced; team_id — dev members inherit the same community teams; LiteLLM metadata column — needs a fork-level change plus reconciler read).

Suggested directions (pick one)

  1. Alias prefix convention enforced in code: dev cloud-api prefixes every minted key alias with dev-; reconciler treats dev--prefixed aliases as foreign-environment (skip like namespaces). Cheap, but a dev QA flow bypassing the prefix reintroduces the leak.
  2. LiteLLM metadata column: stamp environment into the key's metadata at creation (requires the fork — litellm is already forked v1.102.1-spend-fix.1 — or verify 1.10x supports per-key metadata passthrough), reconciler reads it during inventory listing.
  3. Separate LiteLLM instance for dev (cleanest, heaviest): dev points at its own proxy; prod inventory is then fully prod-owned. Note dev's litellm-master-key is currently byte-identical to prod's (see ENTITLEMENT-HARDENING §6.2) — separating also kills that blast radius.

Acceptance

  • A dev QA member minting a key produces zero findings in the prod reconciler digest.
  • A prod member's keys are never skipped by the foreign-environment logic (pinned by test).
  • The majority-unattributable guard denominator stays honest (foreign keys excluded from considered/unresolved, mirroring the namespace fix).

Refs

  • Incident 2026-10-02: member-qa274a / member-qa274c / member-cgutierrez-qa (namespace half, fixed in 0.8.207).
  • platform/cloud-api/docs/ENTITLEMENT-HARDENING.md §F9 documents the accepted sibling risk.

Activity

  1. sre-helmcode commented on Oct 4, 2026

    @sre-helmcode
    ContributorAuthor

    Closed by helmcode/nan-cloud-api#296 (0.8.210, deployed to prod 2026-10-04).

    • Stamp: litellm.Client.Environment → metadata.environment on every generated key (live proxy round-trip verified: /key/generate accepts metadata, /key/list?return_full_object=true returns it).
    • Skip: the reconciler key stage AND the GLM inverse-drift loop silence keys whose metadata.environment differs from the process's own environment — before attribution, outside the majority-guard denominator.
    • No metadata (or non-string value) = legacy = unchanged attribution contract.
    • Ops evidence at close time: zero dev-minted keys in the proxy inventory (DB query by dev member uuids → 0 rows) — the fix is preventive; no legacy remediation needed.
    • Dual adversarial review R2: both APPROVED (round-1 blocker on the GLM loop fixed in e4efc9c).

    Follow-ups live in the issue thread notes: aggregate/Debug the per-key skip log if QA key volume grows; collision-shape test inside the GLM loop specifically.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions