Skip to content

feat: add first-class profile workflows and OAuth login profiles#23

Merged
francoischalifour merged 16 commits into
mainfrom
fc/plan-cli-profile-workflow
Jul 8, 2026
Merged

feat: add first-class profile workflows and OAuth login profiles#23
francoischalifour merged 16 commits into
mainfrom
fc/plan-cli-profile-workflow

Conversation

@francoischalifour

Copy link
Copy Markdown
Member

The CLI previously had basic configuration storage, but profile handling was not strong enough for users who work across multiple organizations, environments, or local development contexts. Users need a clearer way to name, inspect, switch, and export profile state without manually editing config or relying on implicit defaults.

This branch promotes profiles into a first-class CLI workflow. The target model is similar to mature CLIs such as AWS profiles, gcloud configurations, Docker contexts, kubectl contexts, and GitHub CLI account switching: users can keep a sticky active profile, override it per command or shell, switch interactively, and diagnose authentication state.

Proposed solution

Add a complete named-profile workflow around org_env profiles:

  • Derive login profile names from OAuth metadata using the organization and environment.
  • Persist OAuth login metadata into the profile, including organization, environment, principal identity, endpoints, and OAuth expiry.
  • Make altertable login create or reuse the derived profile by default, then switch to it.
  • Add altertable login --replace-profile for users who explicitly want to rename/replace the current profile instead of creating a new one.
  • Make altertable profile create switch to the newly created profile immediately.
  • Add interactive profile switching through altertable profile switch, with labeled profile details so users can distinguish organization, environment, principal, and auth state.
  • Improve altertable profile list with a checkmark active marker and richer columns for org, principal, env, management auth, lakehouse auth, status, OAuth expiry, and data plane.
  • Add shell integration helpers:
    • altertable profile env <name> for shell-local ALTERTABLE_PROFILE usage.
    • altertable profile direnv <name> for .envrc workflows.
  • Add profile status/diagnostic output with optional live verification through altertable profile status --verify.
  • Tighten profile data structures so config keys, auth summaries, snapshots, and metadata updates flow through typed helpers instead of ad hoc branching.
  • Make profile secret migration safer by rolling back partial moves if a target write fails.
  • Expand tests around profile creation, switching, deletion rules, OAuth profile promotion, metadata persistence, and status output.

Preview

image image

User-visible behavior changes

  • altertable login no longer silently overwrites the current profile when OAuth identifies an organization/environment. It creates or reuses the derived profile and activates it.
  • altertable login --replace-profile preserves the old rename-style behavior.
  • altertable profile create ... now activates the created profile.
  • altertable profile delete refuses the active profile, but allows deleting inactive profiles.
  • altertable profile list uses a left-side active checkmark instead of an ACTIVE column.
  • altertable profile switch can run interactively without a profile name.
  • Directory-scoped profile selection is now supported via generated .envrc snippets.

Implementation notes

The profile model now separates:

  • profile config metadata
  • management authentication state
  • lakehouse authentication state
  • derived display summaries
  • inspect/status payloads
  • shell export generation

OAuth login promotion is handled atomically enough to avoid leaving credentials split between profiles during creation, reuse, or replacement. Profile metadata writes are mapped through typed config-key structures so future profile fields are less error-prone to add.

Comment thread cli/src/commands/configure.ts Outdated
Comment thread cli/src/commands/login.ts Outdated
Comment thread cli/src/lib/secrets.ts Outdated
Comment thread cli/src/commands/login.ts Outdated
Comment thread cli/src/lib/secrets.ts Outdated
Comment thread cli/src/commands/login.ts
Comment thread cli/src/commands/login.ts
Comment thread cli/src/commands/profile.ts Outdated
});

const profileInspectCommand = defineValueCommand({
id: "profile.inspect",

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.

inspect / context / status do the same thing?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Got rid of altertable profile inspect. We'll need to converge with altertable profile show/altertable context when reducing the API surface area.

Comment thread cli/src/lib/profile.ts Outdated
};
};

export type ProfileExport = {

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.

Do you have a use-case for export/import?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Figured it'd be useful to "teleport" user context from one env to the other. But let's remove for now.

Clarify login profile selection so OAuth whoami uses the fresh token in memory, then stores credentials once in the selected profile. Make --replace-profile update the current profile instead of renaming it, and persist optional data-plane overrides after a successful login.

Remove the confusing configure --org flag path and hidden profile inspect/export/import commands, leaving profile status as the profile metadata view. Keep rename secret migration scoped to profile code instead of the secrets backend.

Update README and profile/OAuth tests for the smaller profile command surface.
@francoischalifour francoischalifour merged commit 3ce655f into main Jul 8, 2026
4 checks passed
@francoischalifour francoischalifour deleted the fc/plan-cli-profile-workflow branch July 8, 2026 10:33
@github-actions github-actions Bot mentioned this pull request Jul 8, 2026
francoischalifour added a commit that referenced this pull request Jul 9, 2026
🤖 I have created a release *beep* *boop*
---


## 1.0.0 (2026-07-09)


### Features

* add `altertable duckdb` command
([#27](#27))
([e114b11](e114b11))
* add `schema` command
([#21](#21))
([f713a80](f713a80))
* add first-class profile workflows and OAuth login profiles
([#23](#23))
([3ce655f](3ce655f))
* add one-shot shell completion installer
([#9](#9))
([3984fe8](3984fe8))
* auto-provision ephemeral lakehouse credentials after login
([#22](#22))
([d9d815f](d9d815f))
* avoid `--statement` flag for query
([#26](#26))
([23c5dc8](23c5dc8))
* **cli:** add origin-aware CLI update command
([#18](#18))
([5077028](5077028))
* **cli:** support lakehouse upsert endpoint
([#5](#5))
([d6ec3b8](d6ec3b8))
* implement `login` command
([#20](#20))
([1300577](1300577))
* improve human and agent experience
([#8](#8))
([135414f](135414f))
* refine shell completion UX
([#33](#33))
([bd2c605](bd2c605))
* replace `configure` by `profile --configure`
([#28](#28))
([fcf05b5](fcf05b5))


### Bug Fixes

* **api:** normalize api args to ensure the HTTP verb is optional
([#11](#11))
([78b32df](78b32df))
* **api:** prevent wide API tables from soft-wrapping
([#13](#13))
([56fbeb6](56fbeb6))
* **ci:** verify executable step path
([#1](#1))
([4044001](4044001))
* **cli:** remove active context from usage output
([#32](#32))
([9d2a4ad](9d2a4ad))
* **lakehouse:** allow append task without append row flags
([#19](#19))
([6ded957](6ded957))
* main concurrent merge issue
([#37](#37))
([335252c](335252c))
* tighten body validation and stream timeout handling
([#16](#16))
([4c4ce08](4c4ce08))
* validate lakehouse upload files before streaming the payload
([#15](#15))
([0e49b6e](0e49b6e))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Chalifour <francoischalifour@users.noreply.github.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