Skip to content

add auth profiles to wrangler #13975

Open
emily-shen wants to merge 14 commits into
mainfrom
emily/profiles
Open

add auth profiles to wrangler #13975
emily-shen wants to merge 14 commits into
mainfrom
emily/profiles

Conversation

@emily-shen
Copy link
Copy Markdown
Contributor

@emily-shen emily-shen commented May 19, 2026

Supersedes #11780

'Profiles' are essentially just Oauth tokens that you can switch between without re-authing. The main change compared to the earlier PR is that you can now bind a profile to a particular directory. This is similar to account_id in wrangler config, except set at the global context to keep it out of the hands of agents scoped to a particular directory. You can use profiles as an agent guardrail by banning agents from using wrangler login/profiles commands, but setting a profile in the working directory. This will let the agent run commands attached to that account without requiring interactive login, but they shouldn't be able to switch accounts.

New commands

  • npx wrangler profiles create/delete - basically login/logout. intentionally keeping profiles separate from login/out, so if you run wrangler login/out with an active profile, they will error.

NOTE:
I'm not sure if the above is confusing or not, please yell if you think we should have something like npx wrangler login/out --profile=name. This would let you re-login to a profile, but also if you selected a specific account for the token, we can't preserve that when you run the auth flow again - footgun.

  • npx wrangler profiles set <name> —dir, where you can pass in a path or it defaults to cwd. Whenever you’re in that directory, wrangler will default to that profile. You can override this with the env var WRANGLER_PROFILE. (removed the --profile global flag for simplicity, we can it back in a followup if we really want)
  • npx wrangler profiles set <name> (without dir) sets a globally active profile. This applies to any unbound directories. This is useful if you deploy something to multiple accounts.
  • npx wrangler profiles unset (—dir) does the reverse
  • npx wrangler profiles list

TODO in follow up:

  • make it show what accounts each token is associated with in the list command

  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: TODO?

A picture of a cute animal (not mandatory, but encouraged)


Open in Devin Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 19, 2026

🦋 Changeset detected

Latest commit: a699560

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
wrangler Minor
@cloudflare/vite-plugin Patch
@cloudflare/vitest-pool-workers Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@workers-devprod workers-devprod requested review from a team and petebacondarwin and removed request for a team May 19, 2026 16:15
@workers-devprod
Copy link
Copy Markdown
Contributor

workers-devprod commented May 19, 2026

Codeowners approval required for this PR:

  • @cloudflare/cloudchamber
  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/auth-profiles-support.md: [@cloudflare/wrangler]
  • packages/workers-utils/src/environment-variables/factory.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/artifacts.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/containers/registries.test.ts: [@cloudflare/cloudchamber @cloudflare/wrangler]
  • packages/wrangler/src/tests/index.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/logout.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/profile.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/user.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/vpc.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/core/register-yargs-command.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/core/types.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/index.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/auth-variables.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/commands.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/login-shared.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/profiles.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/user.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/user/whoami.ts: [@cloudflare/wrangler]

@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk May 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

✅ All changesets look good

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 19, 2026

create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@13975

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@13975

miniflare

npm i https://pkg.pr.new/miniflare@13975

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@13975

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@13975

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@13975

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@13975

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@13975

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@13975

wrangler

npm i https://pkg.pr.new/wrangler@13975

commit: a699560

@petebacondarwin
Copy link
Copy Markdown
Contributor

@emily-shen - looks like the Ci is not happy and there are some suggestions from Devin.

@petebacondarwin petebacondarwin marked this pull request as draft May 20, 2026 09:38
@petebacondarwin petebacondarwin removed request for a team and petebacondarwin May 20, 2026 09:38
@workers-devprod workers-devprod requested review from a team and penalosa and removed request for a team May 20, 2026 09:38
bimsonz added 7 commits May 20, 2026 11:24
Allow users to be logged into multiple Cloudflare accounts
simultaneously via named profiles stored as separate TOML files.

- Add `wrangler profile list|use|delete` subcommands
- Add `--profile` global flag and WRANGLER_PROFILE env var
- Support `wrangler login --profile <name>` to store credentials
- Namespace account cache per profile to prevent cross-contamination
- Display active profile in `wrangler whoami` output

Profile resolution priority:
  --profile flag > WRANGLER_PROFILE env > profiles.toml > "default"

Profiles stored under ~/.wrangler/config/profiles/<name>.toml.
Default profile path unchanged for full backward compatibility.

Refs: #8956, #11513
Unify login handler to a single code path so the profile success
message and metrics event fire regardless of --scopes usage.

Fix profileExists, deleteProfile, and listProfiles to use
environment-aware paths via getAuthConfigFilePath, so profiles
created in staging are correctly found, listed, and deleted.
Validate WRANGLER_PROFILE and profiles.toml active_profile with
validateProfileName() to prevent invalid profile names from being
used in auth config file path construction.

Also reinitialise auth tokens in clearProfileOverride() to keep
cached credentials in sync when the active profile changes.
deleteProfile() previously used getActiveProfile() to check whether the
deleted profile was active, but getActiveProfile() respects --profile
and WRANGLER_PROFILE overrides. This meant profiles.toml could be left
pointing at a deleted profile when a different override was active.

Extract getActiveProfileFromConfig() to read profiles.toml directly,
ignoring runtime overrides, and use it in deleteProfile().
- Add profile field to whoami --json test expectation
- Update inline snapshots for experimental-commands-api and functions-build
- Add WRANGLER_PROFILE to VariableNames type in workers-utils
- Fix "open-beta" -> "open beta" status enum in profile commands
- Use expect from test context in profile.test.ts (lint rule)
@emily-shen emily-shen force-pushed the emily/profiles branch 2 times, most recently from 28a3ff7 to 206d263 Compare May 20, 2026 16:36
@emily-shen emily-shen marked this pull request as ready for review May 21, 2026 08:52
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

import type { ExpectStatic } from "vitest";

describe("containers registries --help", () => {
runInTempDir();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

have had to do this to a bunch of test files to make sure that running tests locally while you have a profile active doesn't contaminate the snapshots

@emily-shen emily-shen force-pushed the emily/profiles branch 2 times, most recently from 3fbaf9d to bef712f Compare May 21, 2026 10:04
devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 21 additional findings in Devin Review.

Open in Devin Review

Comment on lines +46 to +48
const message = getProfileForDirectory()
? `This directory is bound to the auth profile "${currentProfile}"\n`
: `You are currently using the auth profile "${currentProfile}".\n`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Login error message attributes wrong profile name to directory binding when WRANGLER_PROFILE overrides it

When both WRANGLER_PROFILE and a directory binding are set to different profiles, the error message is factually incorrect. getActiveProfileName() returns the env-var profile (highest priority), but the message checks getProfileForDirectory() to decide the message template and then substitutes currentProfile (from the env var). For example, if WRANGLER_PROFILE=env-profile and the directory is bound to dir-profile, the message says "This directory is bound to the auth profile 'env-profile'" — but the directory is actually bound to dir-profile.

Triggering scenario
  1. Set WRANGLER_PROFILE=env-profile
  2. Bind cwd to a different profile: wrangler profiles set dir-profile --dir .
  3. Run wrangler login
  4. Message incorrectly states: "This directory is bound to the auth profile 'env-profile'"

The fix is to use the return value of getProfileForDirectory() in the directory-binding message branch instead of currentProfile.

Suggested change
const message = getProfileForDirectory()
? `This directory is bound to the auth profile "${currentProfile}"\n`
: `You are currently using the auth profile "${currentProfile}".\n`;
const dirProfile = getProfileForDirectory();
const message = dirProfile
? `This directory is bound to the auth profile "${dirProfile}"\n`
: `You are currently using the auth profile "${currentProfile}".\n`;
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

4 participants