Skip to content

feat(auth): add named profile support for multiple Google accounts#612

Open
joeVenner wants to merge 2 commits intogoogleworkspace:mainfrom
joeVenner:feat/auth-profiles
Open

feat(auth): add named profile support for multiple Google accounts#612
joeVenner wants to merge 2 commits intogoogleworkspace:mainfrom
joeVenner:feat/auth-profiles

Conversation

@joeVenner
Copy link
Contributor

Summary

  • Add named profile support (gws auth profile list|show|create|switch|delete) and global --profile flag for multi-account authentication
  • Each profile gets isolated encrypted credentials, token cache, and AES-256-GCM encryption key under ~/.config/gws/profiles/<name>/
  • Automatic one-time migration from flat config layout to profiles/default/ on first use
  • Profile resolution: --profile flag > GOOGLE_WORKSPACE_CLI_PROFILE env var > active_profile file > "default" fallback

Security

  • ProfileName newtype with strict validation: lowercase [a-z0-9_-], no leading -, no ./.., max 64 chars, no /\% or control chars
  • Per-profile keyring entries (gws-cli / <username>/<profile>) for encryption key isolation
  • Proactive directory creation with create_dir_all (no check-then-create TOCTOU)
  • active_profile file contents validated before use as path component
  • tokio::fs used exclusively in async functions (no blocking I/O)
  • Profile threaded via function parameters (no std::env::set_var)
  • Atomic file writes for active_profile via tempfile + rename
  • 0700 directory / 0600 file permissions on Unix

Files changed

  • src/profile.rs (new) — centralized profile logic, single source of truth
  • src/validate.rsvalidate_profile_name()
  • src/credential_store.rs — per-profile encrypt/decrypt + key management
  • src/token_storage.rs — profile-aware EncryptedTokenStorage
  • src/auth_commands.rs — profile subcommands + threading through handlers
  • src/auth.rs — profile-aware get_token()
  • src/main.rs--profile arg extraction + mod profile
  • src/timezone.rsinvalidate_cache_for_profile()
  • .changeset/add-profile-support.md

Test plan

  • cargo fmt --all — no formatting issues
  • cargo clippy -- -D warnings — zero warnings
  • cargo test — all 825 tests pass (including new profile tests)
  • Manual: gws auth profile create work && gws auth login --profile work
  • Manual: gws auth profile list shows both profiles
  • Manual: gws auth profile switch work && gws auth status shows work profile
  • Manual: verify existing installs auto-migrate to profiles/default/

@joeVenner joeVenner requested a review from jpoehnelt as a code owner March 24, 2026 19:34
@changeset-bot
Copy link

changeset-bot bot commented Mar 24, 2026

🦋 Changeset detected

Latest commit: 356da68

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

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Minor

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the gws CLI by introducing comprehensive support for managing multiple Google accounts through named profiles. This change allows users to seamlessly switch between different authenticated identities, each with its own isolated and securely encrypted credentials. The implementation includes a new profile subcommand for managing these profiles, a global --profile flag for direct selection, and an automatic migration mechanism to transition existing single-account setups to the new profile-based system. The core purpose is to improve usability and security for users who interact with Google Workspace services using multiple accounts.

Highlights

  • Multi-Account Profile Support: Introduced named profile support (gws auth profile list|show|create|switch|delete) and a global --profile flag, enabling users to manage authentication for multiple Google accounts without re-authenticating.
  • Isolated Credentials and Encryption: Each profile now maintains isolated encrypted credentials, a token cache, and a unique AES-256-GCM encryption key, stored under ~/.config/gws/profiles/<name>/ for enhanced security and separation.
  • Automatic Migration: Implemented an automatic one-time migration process that moves existing flat configuration layouts to a profiles/default/ structure upon first use, ensuring a smooth transition for existing users.
  • Robust Profile Resolution and Validation: Established a clear profile resolution hierarchy (CLI flag > environment variable > active_profile file > 'default' fallback) and added strict validation for profile names to prevent security vulnerabilities like path traversal or CLI flag injection.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist
Copy link
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@joeVenner
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for named profiles, allowing users to manage multiple Google accounts with separate credentials and token caches. It adds gws auth profile subcommands (list, show, create, switch, delete) and a global --profile flag. Existing single-account installations are migrated to a default profile. However, there are two critical issues: the manual argument parsing for the global --profile flag is brittle and can lead to incorrect command parsing, and the timezone caching mechanism (read_cache, write_cache, resolve_account_timezone) has not been updated to be profile-aware, which could cause incorrect timezone usage across profiles.

@joeVenner
Copy link
Contributor Author

/gemini review

@jpoehnelt jpoehnelt added the do not merge Indicates a pull request not ready for merge, due to either quality or timing. label Mar 24, 2026
@jpoehnelt
Copy link
Member

I cannot merge this at this time, I will leave open for others to see the fork. Sorry!

@gemini-code-assist
Copy link
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@joeVenner
Copy link
Contributor Author

I cannot merge this at this time, I will leave open for others to see the fork. Sorry!

@jpoehnelt Thanks for the quick feedback ser!

Can I know why we can't merge it ? if possible for sure (^-^)

@jpoehnelt
Copy link
Member

I will add this feature if and when allowed. There is nothing specific to the code here or underlying APIs blocking it.

@jpoehnelt
Copy link
Member

⚠️ Rebase requiredsrc/ has moved to crates/google-workspace-cli/src/ as part of a workspace refactor (#613). Please rebase on main to resolve path conflicts.

Add  subcommands (list, show, create, switch, delete)
and a global  flag so users can authenticate multiple Google
accounts without re-authenticating.

Each profile gets its own encrypted credentials, token cache, and
AES-256-GCM encryption key under ~/.config/gws/profiles/<name>/.
Existing single-account installs are automatically migrated to the
default profile on first use.

Profile resolution priority:
  --profile flag > GOOGLE_WORKSPACE_CLI_PROFILE env > active_profile file > default

Security: validated profile names (lowercase [a-z0-9_-], max 64 chars,
no traversal), per-profile keyring isolation, proactive dir creation
(no TOCTOU), tokio::fs in all async paths, profile threaded via
function parameters (no env::set_var).
…ware

- Validate --profile value is not a flag (prevents --profile --help misparse)
- Make cache_path() resolve active profile so read_cache/write_cache
  operate on the correct profile-specific timezone cache file
@joeVenner joeVenner force-pushed the feat/auth-profiles branch from d4dd78e to 356da68 Compare March 24, 2026 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge Indicates a pull request not ready for merge, due to either quality or timing.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants