feat(cli): add named auth profile management#12529
Open
anticorrelator wants to merge 4 commits intomainfrom
Open
feat(cli): add named auth profile management#12529anticorrelator wants to merge 4 commits intomainfrom
anticorrelator wants to merge 4 commits intomainfrom
Conversation
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
@arizeai/phoenix-cli
@arizeai/phoenix-client
@arizeai/phoenix-evals
@arizeai/phoenix-mcp
@arizeai/phoenix-otel
commit: |
Contributor
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
mikeldking
reviewed
Apr 4, 2026
mikeldking
reviewed
Apr 4, 2026
yfrigui2
reviewed
Apr 13, 2026
anticorrelator
added a commit
that referenced
this pull request
Apr 13, 2026
…tance errors Addresses PR #12529 review feedback from yfrigui2: - Remove --show-secrets from auth profile list/create/delete/switch. Output is always masked so agents invoking these commands never pull plaintext API keys into their context. Users needing the raw value can read ~/.px/profiles.json directly. - Validate --endpoint is a parseable absolute URL at profile create time so typos surface immediately instead of silently creating a broken profile. - Throw ProfileResolutionError when --profile or PHOENIX_PROFILE explicitly names a profile that does not resolve. Previously fell through to defaults, risking mutations against the wrong Phoenix instance. Forgiving fallback is preserved for the "no profile requested" path so unrelated commands aren't blocked. - printBanner swallows resolution errors so `px` with no command never crashes from a stale PHOENIX_PROFILE; the actual command invocation still surfaces the error cleanly.
yfrigui2
approved these changes
Apr 13, 2026
Adds persistent named authentication profiles to the Phoenix CLI, enabling multi-account and multi-host workflows without juggling environment variables. - New commands: `px auth profile list|create|delete` for profile CRUD and `px auth switch <name>` to change the active profile. - Config resolution now a 4-tier merge: CLI flags > env vars > active profile > built-in defaults. Fully backward-compatible. - Profiles stored as JSON at `~/.px/profiles.json` (or `$XDG_CONFIG_HOME/px/profiles.json` when set). File is written `0o600` so API keys are never world-readable. - Parsing/validation via Zod schemas (ProfileEntrySchema, ProfilesFileSchema) with strict and forgiving load modes. - `auth status` now displays the active profile name. - `--show-secrets` is intentionally absent from all profile commands so agents invoking these never pull plaintext API keys into their context; users needing the raw value can read the JSON file. - `--endpoint` validated as an absolute URL at create time. - Explicit `--profile` / `PHOENIX_PROFILE` that names a missing profile raises ProfileResolutionError (INVALID_ARGUMENT) so we never silently point commands at the wrong instance.
6bf3711 to
f6be16c
Compare
Collaborator
|
should be singular profile |
Collaborator
|
use --current to set the current one |
Collaborator
|
switch command is confusing - px profile use |
Promotes profile commands to top-level `px profile {list,create,edit,use,show,delete}`
(dropping `auth profile`/`auth switch`), drops persisted `apiKey` in favor of
env-only `PHOENIX_API_KEY`, and adds a deny-by-default permission allowlist
(`resource.operation`) enforced via openapi-fetch middleware in
`createPhoenixClient`. `assertDeletesEnabled()` and
`PHOENIX_CLI_DANGEROUSLY_ENABLE_DELETES` are retired.
Adds a generated JSON Schema at `schemas/profile.schema.json` (emitted from the
zod source of truth via zod v4's `toJSONSchema`), a CI diff check workflow,
`$schema` support in the config file for editor autocompletion, and shipping
the schema in the npm `files` whitelist.
The package is ESM ("type": "module"), so the inline require() in
spawnEditorSync threw 'require is not defined' at runtime, making
`px profile edit` fail before the editor could open.
When permissions are not passed explicitly, the factory now resolves the active profile (via --profile arg, PHOENIX_PROFILE env, or file.activeProfile) and attaches the permission middleware with that profile's effective scope list. With no active profile, no middleware is attached — users who have not opted into the profile model keep their prior behavior. This closes the last wiring gap so profiles that declare `permissions` actually gate destructive calls across all command handlers, without touching each of the 22+ createPhoenixClient call sites. Also isolates delete.test.ts from the developer's real ~/.px/profiles.json by pointing XDG_CONFIG_HOME at a temp dir per describe block.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #12000
Resolves #12001
Summary
px auth profiles list|create|deletefor profile CRUD,px auth switch <name>for switching the active profile~/.px/profiles.json(or$XDG_CONFIG_HOME/phoenix/profiles.jsonwhen set)auth statusnow displays the active profile nameArchitecture
Implementation
Profile storage (
profiles.ts): New module with types (ProfileEntry,ProfilesFile), config path resolution (~/.pxdefault,$XDG_CONFIG_HOME/phoenixwhen set), file I/O (loadProfiles/saveProfiles), and pure validation helpers.loadProfilessupports strict mode (throwsProfilesFileErroron corrupt files — used by mutation commands) and forgiving mode (returns empty state with stderr warning — used by config resolution so a corrupt file never blocks unrelated commands).Config resolution (
config.ts):loadConfigFromEnvironment()refactored to only return explicitly-set env vars (previously mixed inDEFAULT_PHOENIX_ENDPOINTunconditionally). NewgetBuiltInDefaults()andloadConfigFromProfile()functions.resolveConfig()now performs a 4-tier merge:{ ...defaults, ...profile, ...envVars, ...cliFlags }.Commands (
auth.ts): Three-level nesting (auth profiles list|create|delete) is new for the CLI but structurally sound with Commander.js.auth switchis a direct peer ofauth status— local-only, no network call.auth profiles createrequires--endpoint;--api-keyand--projectare optional (profiles are partial by design, participating in the merge chain). API keys masked in pretty output, unmasked in JSON/raw for scripting.Key design choices:
PHOENIX_CLIENT_HEADERSparsingPHOENIX_PROFILEenv var follows the existingPHOENIX_PROJECTpattern;--profilescoped to auth commands only (other commands gain profile support transparently viaresolveConfig())version: 1field for future migration supportRecord<string, ProfileEntry>keyed by name — enforces uniqueness without extra validationTest plan
px auth profiles create staging --endpoint https://staging.example.com --api-key sk-xxx --set-defaultcreates profile and sets as activepx auth profiles listshows profiles with masked API keys and*active indicatorpx auth profiles list --format jsonoutputs full (unmasked) JSONpx auth switch stagingsets active profile with local confirmationpx auth statusshowsProfile: staginglinePHOENIX_HOST=http://override:6006 px auth status— env var overrides profile endpoint (backward compat)profiles.jsondoes not blockpx auth statusor non-auth commands (forgiving mode)px auth profiles create/delete/switcherror clearly on corrupt file (strict mode)