Skip to content

feat: add CLI commands for RBAC groups and roles#4208

Merged
forestileao merged 11 commits intosuperplanehq:mainfrom
Vukotije:feat/cli-rbac
Apr 17, 2026
Merged

feat: add CLI commands for RBAC groups and roles#4208
forestileao merged 11 commits intosuperplanehq:mainfrom
Vukotije:feat/cli-rbac

Conversation

@Vukotije
Copy link
Copy Markdown
Collaborator

@Vukotije Vukotije commented Apr 17, 2026

Closes #3687

Summary

  • Adds superplane groups subcommand tree with full CRUD plus nested groups members (list/add/remove).
  • Adds superplane roles subcommand tree with full CRUD (list/get/create/update/delete) mirroring the UI Roles settings.
  • Group create/update accept either inline flags (--display-name, --description, --role) or -f YAML (kind: Group).
  • Role create/update accept -f YAML (kind: Role) supporting the full spec.permissions[] array and optional spec.inheritedRole.
  • Fully independent of the members CLI PR — builds and tests pass against main on its own.

Test plan

  • go test ./pkg/cli/commands/groups/... ./pkg/cli/commands/roles/...
  • go build ./cmd/cli/...
  • superplane groups list and groups create engineers --display-name Engineers --role org_admin
  • superplane groups members add engineers <user-id> and remove
  • superplane roles create -f role.yaml with permissions array
  • superplane roles update -f role.yaml
  • superplane roles delete <name>

Add superplane groups and superplane roles subcommand trees covering
every CRUD action the UI settings pages expose:

- groups list / get / create (inline flags or -f) / update / delete
- groups members list / add / remove
- roles list / get / create -f / update -f / delete

Group create/update accept either inline flags (--display-name,
--description, --role) or a -f YAML file with apiVersion: v1, kind: Group.
Roles follow the same YAML resource pattern with kind: Role, supporting
the full spec.permissions[] array plus spec.inheritedRole.

Includes httptest-based coverage of request paths, methods, query params,
and body shapes — including the PATCH /users/remove route and the PUT
role update endpoint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vukotije <vukanradojevicc@gmail.com>
@superplanehq-integration
Copy link
Copy Markdown

👋 Commands for maintainers:

  • /sp start - Start an ephemeral machine (takes ~30s)
  • /sp stop - Stop a running machine (auto-executed on pr close)

Comment thread pkg/cli/commands/groups/create.go
The -f path of groups create and roles create previously sent the
request without checking that metadata.name was populated in the YAML
file, producing a generic server-side error. Match the validation the
corresponding update commands already perform so users get an actionable
client-side message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vukotije <vukanradojevicc@gmail.com>
@Vukotije Vukotije requested a review from forestileao April 17, 2026 15:53
Comment thread pkg/cli/commands/groups/root.go Outdated
Comment thread pkg/cli/commands/groups/root.go Outdated
Comment thread pkg/cli/commands/roles/root.go Outdated
Comment thread pkg/cli/commands/roles/root.go Outdated
Comment thread pkg/cli/commands/groups/update.go
Comment thread pkg/cli/commands/groups/common.go Outdated
Vukotije and others added 2 commits April 17, 2026 23:13
- Fix misleading --file descriptions on groups and roles create/update.
  Implementation only calls os.ReadFile on a single path — no directory
  or URL support. Update help text to match reality.
- Add tests for the groups update command covering inline partial updates
  (only changed fields reach the wire), inline full updates, file-based
  updates, metadata.name validation on file path, positional+file
  conflict, missing identifier, and no-flag-change refusal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vukotije <vukanradojevicc@gmail.com>
The helper was duplicated verbatim between members and groups — same
logic, same error messages — originally because the two packages were
split into independent PRs so each had to build on its own. Now that
both are on main, consolidate into core.SplitUserIdentifier so a bug
fix or behavior tweak only has to land once.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vukotije <vukanradojevicc@gmail.com>
Comment thread pkg/cli/commands/groups/create.go
Previously passing --display-name, --description, or --role alongside
--file on groups create or update silently ignored the inline flag and
used only the file contents. The user got no indication their input was
dropped.

Treat the combination as an error, matching the existing
positional+--file conflict. Add tests for both create and update.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vukotije <vukanradojevicc@gmail.com>
@Vukotije Vukotije requested a review from forestileao April 17, 2026 21:50
@Vukotije
Copy link
Copy Markdown
Collaborator Author

Vukotije commented Apr 17, 2026

@forestileao finished implementing those, take a look.

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2340d38. Configure here.

Comment thread pkg/cli/commands/groups/common.go Outdated
Vukotije and others added 3 commits April 18, 2026 00:15
The helper was copy-pasted verbatim across groups, roles, members, and
secrets. Consolidate it into core.OrganizationDomainType() to match the
treatment SplitUserIdentifier already received and keep domain-scoping
policy in one place.

Net: 25 files touched, -37/+29 lines, four identical definitions removed.
No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vukotije <vukanradojevicc@gmail.com>
…nType

These helpers moved into pkg/cli/core in the preceding dedup commits,
but the calling tests live in pkg/cli/commands/{members,groups}/ — Go
coverage is per-package so those calls do not count toward core's
percentage. Add a dedicated users_test.go inside core covering all
SplitUserIdentifier branches (including trim and ambiguous-input error)
and OrganizationDomainType, lifting pkg/cli/core coverage from 15.7%
back above the 17.2% baseline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Vukotije <vukanradojevicc@gmail.com>
@forestileao forestileao merged commit 9838185 into superplanehq:main Apr 17, 2026
5 checks passed
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.

CLI should allow to manage RBAC

2 participants