Skip to content

Use /v1/me for CLI auth identity#40

Merged
luanvdw merged 4 commits into
mainfrom
feat/cli-auth-current-principal
May 28, 2026
Merged

Use /v1/me for CLI auth identity#40
luanvdw merged 4 commits into
mainfrom
feat/cli-auth-current-principal

Conversation

@luanvdw
Copy link
Copy Markdown
Member

@luanvdw luanvdw commented May 27, 2026

Summary

Updates auth whoami to resolve the signed-in identity through the Management API /v1/me endpoint.

  • bumps @prisma/management-api-sdk to ^1.34.0, which includes /v1/me
  • calls /v1/me for stored OAuth sessions and PRISMA_SERVICE_TOKEN sessions
  • prints OAuth users as user: email@example.com
  • prints service-token sessions as user: <service token: name> or user: <service token>
  • returns structured user, workspace, and credential in JSON output
  • preserves the existing token-claim/workspace lookup fallback for rollout safety

Validation

  • pnpm --filter @prisma/cli exec vitest run tests/auth-ops.test.ts tests/auth-real-mode.test.ts tests/auth-usecases.test.ts tests/auth.test.ts tests/project-usecases.test.ts
  • pnpm --filter @prisma/cli test
  • git diff --check

Notes

The Management API PR has landed and @prisma/management-api-sdk@1.34.0 has been published, so this PR now consumes the generated /v1/me SDK types directly.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Review Change Stack

Walkthrough

This PR enriches auth state by adding a credential field that tracks whether a user is authenticated via OAuth, service token, or management token. It flows the credential type and identity (id, name) through operations, use cases, and presenters, and updates tests and documentation to match the expanded contract.

Changes

Auth credential field support

Layer / File(s) Summary
Type contracts for credentials and expanded user
packages/cli/src/types/auth.ts
AuthUser adds optional id and nullable name fields. New AuthCredential interface defines credential type (oauth/service_token/management_token) with optional id and name. AuthStateResult adds credential: AuthCredential | null field.
Auth operations with principal lookup and credential handling
packages/cli/src/lib/auth/auth-ops.ts
readAuthState now attempts to fetch principal via /v1/me (with new readCurrentPrincipalAuthState helper), falls back to JWT-claims-based state via buildAuthState. Both paths return credential field. readServiceTokenAuthState refactored to validate workspace via JWT claims. buildAuthState accepts optional client parameter and lazy-initializes when needed.
Auth use case credential population
packages/cli/src/use-cases/auth.ts
resolveCurrentAuthState populates credential field: null when signed-out, OAuth shape with null id/name when authenticated. Expands user to include id, email, and name fields.
Presentation layer for user and credential labels
packages/cli/src/presenters/auth.ts
New helpers authUserLabel, authUserRows, and credentialUserLabel flexibly derive user display from email or credential-based labels. Auth login/whoami outputs now conditionally render user, provider, and workspace rows.
Auth operations unit tests
packages/cli/tests/auth-ops.test.ts
New test covers OAuth principal resolution via /v1/me. Service-token mocking expanded to include credential details. All existing assertions updated to expect credential field in signed-out and authenticated states.
Use case and command tests
packages/cli/tests/auth-usecases.test.ts, packages/cli/tests/auth.test.ts, packages/cli/tests/project-usecases.test.ts
Auth use case tests and whoami command tests updated to include credential field in expected auth state shapes. Project use case test updated to pass credential: null in workspace object.
Real mode integration tests
packages/cli/tests/auth-real-mode.test.ts
New tests verify service-token identity in JSON output and human-readable output. Existing mocked auth states updated to include credential: null.
Command spec documentation
docs/product/command-spec.md
Updated auth whoami --json contract to show expanded user (id, email, name), explicit credential object for OAuth, and service-token/fallback examples with different user/credential combinations.
Dependency update
packages/cli/package.json
Bumped @prisma/management-api-sdk from ^1.33.0 to ^1.34.0.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: integrating the Management API's /v1/me endpoint for CLI auth identity resolution.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly explains the changes: updating auth whoami to use the Management API /v1/me endpoint, including dependency bump, output formatting, structured JSON response, and validation steps.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cli-auth-current-principal
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/cli-auth-current-principal

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@luanvdw
Copy link
Copy Markdown
Member Author

luanvdw commented May 27, 2026

Ran the updated pr-review flow against this CLI PR.

Verdict: conditional pass.

Findings:

  • R1 — Auth result contract: packages/cli/src/types/auth.ts made credential optional even though the documented JSON contract says auth results include credential as an object or null. Optionality would let future code paths accidentally omit the field and drift the structured output contract.
  • R2 — SDK type boundary / merge gate: packages/cli/src/lib/auth/auth-ops.ts currently uses a local CurrentPrincipalClient shim plus cast for /v1/me. That is acceptable while this PR is draft and the Management API SDK has not been regenerated, but before merge this should be replaced by the generated SDK type/version after the API PR lands.
  • M1 — Presenter duplication: packages/cli/src/presenters/auth.ts duplicated the user-vs-credential label branch across login and whoami output, which creates a small drift point for future auth identity formatting.

File-size gate:

  • No changed implementation or test file crosses the 1,000-line threshold.
  • docs/product/command-spec.md is already over 1,000 lines; this PR adds a focused auth-contract section, not a new large code owner.

Validation limit:

  • The repo typecheck currently fails on unrelated pre-existing errors in project presenter/helpers/publish-prep files, so I used tests plus diff hygiene for this pass.

@luanvdw
Copy link
Copy Markdown
Member Author

luanvdw commented May 27, 2026

Follow-up from pr-review: code fixes pushed in 305db4e.

  • R1 fixed: made AuthStateResult.credential required as AuthCredential | null, and updated affected fixtures to keep the null case explicit.
  • R2 accepted/no change for now: the /v1/me SDK shim remains because the Management API SDK release is still upstream of this draft PR. This should be removed when the generated SDK version is available before CLI merge.
  • M1 fixed: centralized auth display labeling so OAuth user email and service/management token labels are formatted through one presenter helper.

Validation run:

  • pnpm --filter @prisma/cli exec vitest run tests/auth-ops.test.ts tests/auth-real-mode.test.ts tests/auth-usecases.test.ts tests/auth.test.ts tests/project-usecases.test.ts
  • pnpm --filter @prisma/cli test passed with local callback-server binding allowed
  • git diff --check origin/main...HEAD

Validation note:

  • pnpm --filter @prisma/cli exec tsc --noEmit --pretty false still fails on unrelated existing errors in src/presenters/project.ts, tests/helpers.ts, and tests/publish-prep.test.ts.

@luanvdw luanvdw marked this pull request as ready for review May 27, 2026 10:58
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/cli/tests/auth-ops.test.ts (1)

82-129: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider explicitly mocking /v1/me for fallback-path clarity.

This test verifies the workspace-lookup fallback, but the mock (line 89–104) doesn't handle /v1/me, so the code must throw and be caught internally. While the test passes, explicitly mocking /v1/me to return null or { data: null } would make the fallback intent clearer and decouple the test from internal error-handling details.

Example explicit fallback mock
 const requireComputeAuth = vi.fn().mockResolvedValue({
   GET: vi.fn().mockImplementation((pathName: string, request?: { params?: { path?: { id?: string } } }) => {
+    if (pathName === "/v1/me") {
+      return { data: null };
+    }
     if (pathName === "/v1/workspaces/{id}" && request?.params?.path?.id === "cmmxlp7ae1251zyfs8mdpnavm") {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/tests/auth-ops.test.ts` around lines 82 - 129, Update the test's
mocked requireComputeAuth GET handler used by readAuthState to explicitly handle
the "/v1/me" endpoint (in addition to "/v1/workspaces/{id}") and return an
explicit null response (e.g., null or { data: null }) so the workspace-lookup
fallback path is clear; modify the vi.fn().mockImplementation for GET inside the
requireComputeAuth mock to check for pathName === "/v1/me" and return the
explicit null-shaped response before throwing for unexpected paths.
packages/cli/src/lib/auth/auth-ops.ts (1)

46-55: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Pass the trimmed service token through the SDK path.

Line 48 normalizes PRISMA_SERVICE_TOKEN, but Line 89 still builds the client from the original env. If the env var carries leading/trailing whitespace, /v1/me and /v1/workspaces/{id} will authenticate with a different value than the JWT fallback parses, so auth whoami can flip between signed-out and signed-in for the same token.

Suggested fix
-    return readServiceTokenAuthState(serviceToken, env);
+    return readServiceTokenAuthState(serviceToken, {
+      ...env,
+      [SERVICE_TOKEN_ENV_VAR]: serviceToken,
+    });

Also applies to: 89-117

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/lib/auth/auth-ops.ts` around lines 46 - 55, The code trims
PRISMA_SERVICE_TOKEN into rawServiceToken -> serviceToken but continues to build
the SDK client from the original env (so whitespace in the env yields different
auth behavior); update the SDK path to use the trimmed token by either assigning
env[SERVICE_TOKEN_ENV_VAR] = serviceToken before constructing the client or by
passing serviceToken directly into the client/auth builder (referencing
SERVICE_TOKEN_ENV_VAR, rawServiceToken, serviceToken, and
readServiceTokenAuthState) so both the JWT fallback and the SDK client use the
identical trimmed token.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/cli/src/lib/auth/auth-ops.ts`:
- Around line 46-55: The code trims PRISMA_SERVICE_TOKEN into rawServiceToken ->
serviceToken but continues to build the SDK client from the original env (so
whitespace in the env yields different auth behavior); update the SDK path to
use the trimmed token by either assigning env[SERVICE_TOKEN_ENV_VAR] =
serviceToken before constructing the client or by passing serviceToken directly
into the client/auth builder (referencing SERVICE_TOKEN_ENV_VAR,
rawServiceToken, serviceToken, and readServiceTokenAuthState) so both the JWT
fallback and the SDK client use the identical trimmed token.

In `@packages/cli/tests/auth-ops.test.ts`:
- Around line 82-129: Update the test's mocked requireComputeAuth GET handler
used by readAuthState to explicitly handle the "/v1/me" endpoint (in addition to
"/v1/workspaces/{id}") and return an explicit null response (e.g., null or {
data: null }) so the workspace-lookup fallback path is clear; modify the
vi.fn().mockImplementation for GET inside the requireComputeAuth mock to check
for pathName === "/v1/me" and return the explicit null-shaped response before
throwing for unexpected paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8f0af90d-ef27-45cd-932e-4fa499f56372

📥 Commits

Reviewing files that changed from the base of the PR and between 64bc9e2 and 1725f7f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • docs/product/command-spec.md
  • packages/cli/package.json
  • packages/cli/src/lib/auth/auth-ops.ts
  • packages/cli/src/presenters/auth.ts
  • packages/cli/src/types/auth.ts
  • packages/cli/src/use-cases/auth.ts
  • packages/cli/tests/auth-ops.test.ts
  • packages/cli/tests/auth-real-mode.test.ts
  • packages/cli/tests/auth-usecases.test.ts
  • packages/cli/tests/auth.test.ts
  • packages/cli/tests/project-usecases.test.ts

@luanvdw luanvdw merged commit de5e017 into main May 28, 2026
5 checks passed
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.

1 participant