feat(auth): add scopes tracking, extensible auth commands, standalone module walk - #49
Merged
Conversation
… module walk Adds three additive extension points so consumers can build an eager, non-interactive OAuth login: `Credential`/`AuthStatusEntry` now carry the granted `scopes`, `CliConfig::with_auth_extra_commands` lets a consumer mount sibling commands under the builtin `auth` group, and `build_module_group` materializes a module's command tree standalone so a consumer can walk its own commands' declared scopes without duplicating them. DEVEX-886, DEVEX-891
There was a problem hiding this comment.
Pull request overview
This PR extends cli-engine’s auth and module introspection capabilities by (1) tracking granted OAuth scopes on credentials and exposing them via auth status, (2) adding an extension point for consumer-defined auth subcommands without reimplementing the built-in auth group, and (3) providing a helper to materialize a module’s runtime command tree standalone for scope→command discovery.
Changes:
- Add
scopes: Vec<String>toCredentialandAuthStatusEntry, and populate scopes inPkceAuthProvider::build_credential. - Add
CliConfig::auth_extra_commands+with_auth_extra_commands, and mount these extra commands under the built-inauthgroup. - Add
build_module_group(&Module) -> RuntimeGroupSpecand test coverage around command-tree materialization and the new auth extension point.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/foundation.rs | Adds integration/unit tests covering module tree materialization, auth extra commands mounting, and updated auth status JSON shape (now includes scopes). |
| src/module.rs | Introduces build_module_group helper for standalone module command-tree materialization. |
| src/lib.rs | Re-exports build_module_group from the crate root. |
| src/cli.rs | Adds auth_extra_commands to CliConfig, builder method, and mounts the extra commands in Cli::ensure_auth_command. |
| src/auth/pkce.rs | Populates Credential.scopes from stored token scope data. |
| src/auth/credential.rs | Adds scopes field to the public Credential type with serde defaults. |
| src/auth/commands.rs | Adds scopes field to AuthStatusEntry and wires it into status rendering. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Copilot review on #49 flagged four issues: - auth_extra_commands could silently overwrite a built-in login/status/ logout on a name collision (RuntimeGroupSpec::register_commands and clap subcommands are both last-writer-wins); now skipped + warned. - ensure_auth_command never called register_runtime_group_metadata, so an extra command's with_output_schema/with_view never took effect. - AuthStatusEntry.scopes lacked #[serde(default)], breaking Deserialize of legacy JSON missing the field. - build_module_group's doc overclaimed parity with Cli::new — it skips the feature-flag pruning add_module applies. DEVEX-886, DEVEX-891
CI's `cargo doc -D warnings` was failing: two doc comments linked to the private Cli::ensure_auth_command, and module.rs's Cli::new link had no Cli import in scope to resolve against. Reworded the private-item links to plain text and fully-qualified the Cli::new link with crate::Cli::new.
Copilot review flagged that ensure_auth_command only checked new auth_extra_commands entries against the three built-in names, so two extras sharing a name would still silently last-writer-wins (both in the RuntimeGroupSpec::commands map and the clap subtree), contradicting the additive-extension-point guarantee. Track every name seen so far (built-ins + previously-accepted extras) and skip + warn on any repeat, keeping the first. DEVEX-886, DEVEX-891
runruh-godaddy
approved these changes
Jul 16, 2026
jpage-godaddy
pushed a commit
that referenced
this pull request
Jul 16, 2026
🤖 I have created a release *beep* *boop* --- ## [0.4.4](cli-engine-v0.4.3...cli-engine-v0.4.4) (2026-07-16) ### Features * **auth:** add scopes tracking, extensible auth commands, standalone module walk ([#49](#49)) ([bebe5bb](bebe5bb)) ### Bug Fixes * only register --reason when authz/auditor/activity is configured ([#50](#50)) ([81f50b1](81f50b1)) --- 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>
jpage-godaddy
added a commit
that referenced
this pull request
Jul 16, 2026
… status (#52) ## Summary * `AuthLoginResult` never got the `scopes` field `AuthStatusEntry` gained in #49, even though the `Credential` returned from login already carries it — so `gddy auth login`'s output was missing a field that a subsequent `gddy auth status` for the same credential would show. Reported as an output-consistency nit between the two commands. * Add `scopes: Vec<String>` to `AuthLoginResult`, populated from `Credential::scopes` the same way `AuthStatusEntry` is. * Add a `ScopedFakeProvider` test fixture (a credential with fixed non-empty scopes, unlike the existing `FakeProvider` which always returns an empty scopes list) and a test asserting `login_and_build`'s and `to_status_entry`'s scopes agree for the same credential. ## Test plan * `cargo fmt --all --check` * `cargo clippy --all-targets --features pkce-auth -- -D warnings` * `cargo test --all-targets --features pkce-auth` (267 passed in the integration suite) * `RUSTDOCFLAGS='-D warnings' cargo doc --no-deps` (default and `--features pkce-auth`)
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.
Summary
scopes: Vec<String>toCredentialandAuthStatusEntry, populated fromgranted_scopes(token)inPkceAuthProvider::build_credential, soauth statuscan report which OAuth scopes are currently granted (DEVEX-886).CliConfig::auth_extra_commands/with_auth_extra_commands— an additive extension point that lets a consumer mount sibling commands under the builtinauthgroup (login/status/logout) without losing the builtins or duplicatingensure_auth_command's clap-tree assembly.cli_engine::build_module_group(&Module) -> RuntimeGroupSpec— materializes a module's command tree standalone (a throwawayMiddleware, same construction pathCli::newuses), so a consumer can walk its own commands'.metadata().scopesto derive a live scope→command registry, with no duplicated command declarations (DEVEX-891).Together these unblock a
gddy auth scopescommand (in theclirepo) that lists every OAuth scope the CLI can request and which commands need it — letting an agent driving a multi-step workflow discover every scope up front and do a single eager login instead of hitting an interactive step-up prompt mid-workflow.Test plan
cargo fmt --all --checkcargo clippy --all-targets -- -D warningscargo test --all-targetsManual verification
New coverage is exercised entirely by the added unit/integration tests (
build_credential_populates_scopes_from_stored_token,build_module_group_materializes_the_real_command_tree_standalone,auth_extra_commands_are_mounted_as_siblings_without_losing_builtins) — no manualcli-side build was needed for this PR since all three changes are additive with no existing behavior altered. Theclirepo's consumption of these APIs (gddy auth scopes,auth statusscopes field) will be a separate PR once this is published.