Skip to content

auth login: allow user-scoped API key without --oid#289

Merged
maximelb merged 1 commit into
refractionPOINT:cli-v2from
lc-cbot:fix/auth-login-user-scoped-api-key
May 7, 2026
Merged

auth login: allow user-scoped API key without --oid#289
maximelb merged 1 commit into
refractionPOINT:cli-v2from
lc-cbot:fix/auth-login-user-scoped-api-key

Conversation

@lc-cbot
Copy link
Copy Markdown

@lc-cbot lc-cbot commented May 6, 2026

Problem

limacharlie auth login --uid X --api-key Y (a user-scoped API key, no org context) is rejected with:

Error: --oid and --api-key are required for API key login.
Suggestion: Use --oauth for browser-based OAuth login, or provide both --oid and --api-key.

…even though --uid is documented as the flag for "user-scoped API keys" and the --ai-help text says "If you are using a user-scoped API key, also pass --uid."

This breaks the bootstrap flow for any brand-new LimaCharlie account that hasn't created an org yet — chicken-and-egg, since the user can't list/create their first org without working CLI auth, can't auth without an OID, and doesn't have an OID until they create an org.

The User API Key itself is fully capable of user-scoped operations — LC_UID + LC_API_KEY env vars already work for auth list-orgs (the only call needed to bootstrap from "I have a User API Key" to "I know my OIDs"). The bug was purely in the auth login validator forcing an --oid constraint that the rest of the CLI doesn't actually need.

Discovered

Live during a workshop where one student chose the email/password signup path (which yields a User API Key). The OAuth-via-Google/Microsoft paths worked fine; the email/password path failed at this validator.

Fix

Rework the validator to accept either of two valid shapes:

  • --oid + --api-key — org-scoped key (existing behavior, plus optional --uid for service accounts)
  • --uid + --api-key — user-scoped key, --oid optional

When neither --oid nor --uid is provided, emit a clear error distinguishing the two key types so users picking the wrong key from the LC web UI get pointed to the right one.

The write_credentials call already handles oid=None correctly (skips writing the field), so no downstream changes are needed.

Tests run locally against a real account

Case Result
auth login --uid X --api-key Y (no --oid) ✓ "Credentials saved"
auth list-orgs against those credentials ✓ Returns the user's orgs
auth login --api-key Y (neither --oid nor --uid) ✓ New clear error, exit 4
auth login --oid X --api-key Y (existing org-scoped path) ✓ Unchanged
auth login --oauth --provider google ✓ Unchanged (verified end-to-end via browser)

Downstream impact

A workshop's setup.sh currently uses a placeholder-OID workaround (--oid 00000000-0000-0000-0000-000000000000 --uid X --api-key Y) to bootstrap users with brand-new accounts. After this lands and ships, that workaround becomes unnecessary — but it'll keep working since the --oid + --api-key + --uid shape stays valid.

The validator currently rejects `auth login --uid X --api-key Y`
with "Error: --oid and --api-key are required for API key login.",
even though `--uid` is documented as the flag for user-scoped API
keys. This makes brand-new accounts un-bootstrappable from the CLI
because they have no organization yet — chicken-and-egg, since the
user can't list/create their first org without working CLI auth,
but can't auth without an OID, but doesn't have an OID until they
create an org.

The User API Key itself is a fully valid credential — env-var auth
(LC_UID + LC_API_KEY) works for `auth list-orgs` already, which is
the only call needed to bootstrap from "I have a User API Key" to
"I know my OIDs". The bug was purely in the `auth login` validator
forcing an --oid constraint that the rest of the CLI doesn't need.

Fix: rework the validator to accept either:
  --oid + --api-key  (org-scoped key — existing behavior)
  --uid + --api-key  (user-scoped key — new path, --oid optional)

When neither --oid nor --uid is provided, emit a clear error
distinguishing the two key types. The `write_credentials` call
already handles oid=None correctly (skips writing the field), so
no downstream changes needed.

Tested:
- `auth login --uid X --api-key Y` (no --oid) → succeeds
- `auth list-orgs` against those credentials → returns the user's orgs
- `auth login --api-key Y` (neither --oid nor --uid) → clear error
- `auth login --oid X --api-key Y` (existing org-scoped path) → unchanged
- `auth login --oauth --provider google` → unchanged
@lc-cbot lc-cbot requested a review from maximelb May 7, 2026 14:13
@maximelb maximelb merged commit 802efed into refractionPOINT:cli-v2 May 7, 2026
7 checks passed
maximelb added a commit that referenced this pull request May 7, 2026
Follow-up to #289. When a user re-runs `auth login --uid X --api-key Y`
in an environment that previously held an `--oid + --api-key` login, the
old `oid` survived in config because `write_credentials` only writes
fields it is given. Subsequent commands would silently pair the new
user-scoped credentials with the stale org context.

Fix it by dropping the `oid` field from the affected env block right
after the write whenever the login was user-scoped (`uid` set, `oid`
unset). Mirrors the post-write cleanup pattern already used by the
OAuth flow for `api_key`.

Also refresh the `--ai-help` text so it advertises the user-scoped
shape (`--uid + --api-key`, no `--oid`) that #289 enabled, and add
unit tests for the validator branches and the stale-oid cleanup --
neither was covered before.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants