Skip to content

feat(auth): add scopes tracking, extensible auth commands, standalone module walk - #49

Merged
jpage-godaddy merged 4 commits into
mainfrom
auth-scopes-registry
Jul 16, 2026
Merged

feat(auth): add scopes tracking, extensible auth commands, standalone module walk#49
jpage-godaddy merged 4 commits into
mainfrom
auth-scopes-registry

Conversation

@jpage-godaddy

Copy link
Copy Markdown
Collaborator

Summary

  • Add scopes: Vec<String> to Credential and AuthStatusEntry, populated from granted_scopes(token) in PkceAuthProvider::build_credential, so auth status can report which OAuth scopes are currently granted (DEVEX-886).
  • Add CliConfig::auth_extra_commands / with_auth_extra_commands — an additive extension point that lets a consumer mount sibling commands under the builtin auth group (login/status/logout) without losing the builtins or duplicating ensure_auth_command's clap-tree assembly.
  • Add cli_engine::build_module_group(&Module) -> RuntimeGroupSpec — materializes a module's command tree standalone (a throwaway Middleware, same construction path Cli::new uses), so a consumer can walk its own commands' .metadata().scopes to derive a live scope→command registry, with no duplicated command declarations (DEVEX-891).

Together these unblock a gddy auth scopes command (in the cli repo) 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 --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --all-targets

Manual 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 manual cli-side build was needed for this PR since all three changes are additive with no existing behavior altered. The cli repo's consumption of these APIs (gddy auth scopes, auth status scopes field) will be a separate PR once this is published.

… 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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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> to Credential and AuthStatusEntry, and populate scopes in PkceAuthProvider::build_credential.
  • Add CliConfig::auth_extra_commands + with_auth_extra_commands, and mount these extra commands under the built-in auth group.
  • Add build_module_group(&Module) -> RuntimeGroupSpec and 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.

Comment thread src/cli.rs
Comment thread src/cli.rs
Comment thread src/auth/commands.rs
Comment thread src/module.rs
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 AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread src/cli.rs Outdated
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

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread src/cli.rs
Comment thread src/auth/credential.rs
Comment thread src/auth/commands.rs

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

@jpage-godaddy
jpage-godaddy merged commit bebe5bb into main Jul 16, 2026
4 checks passed
@jpage-godaddy
jpage-godaddy deleted the auth-scopes-registry branch July 16, 2026 16:25
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`)
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.

3 participants