Skip to content

feat: suggest Azure built-in roles for required permissions (#36) - #300

Open
Brian Gordon Davis (bgdnext64) wants to merge 2 commits into
mainfrom
feature/36-suggest-builtin-roles
Open

feat: suggest Azure built-in roles for required permissions (#36)#300
Brian Gordon Davis (bgdnext64) wants to merge 2 commits into
mainfrom
feature/36-suggest-builtin-roles

Conversation

@bgdnext64

Copy link
Copy Markdown
Collaborator

Summary

Implements #36 — suggest Azure built-in role(s) that cover the minimum permissions discovered by MPF.

After MPF determines the minimum required permissions for a deployment, this feature optionally matches those permissions against the subscription's Azure built-in role definitions and prints:

  • Single-role matches — built-in roles that individually cover every required permission, ranked least-privilege first.
  • Minimal combination — a greedy set-cover of built-in roles when no single role covers everything.
  • Uncovered permissions — any required permissions not covered by a built-in role (candidates for a custom role).

The feature is opt-in via a new global flag --suggestRoles (env MPF_SUGGESTROLES) and works across the arm, bicep, and terraform subcommands. Output honors the existing --jsonOutput flag.

Behavior

  • Roles are ranked by specificity so least-privilege options appear first. Roles granting the global wildcard (*, e.g. Owner/Contributor) are deprioritized and rank last.
  • Wildcard action patterns (e.g. Microsoft.Storage/*) are matched case-insensitively against required permissions, and NotActions exclusions are respected.
  • Role suggestion failures are logged non-fatally so they never break the core permission-finding flow.

Changes

  • pkg/domain/roleSuggestion.go — pure role-matching and ranking logic (wildcard matching, greedy set cover, specificity scoring) with unit tests.
  • pkg/usecase/roleSuggester.goBuiltInRoleProvider interface.
  • pkg/infrastructure/roleDefinitionManager/ — fetches built-in role definitions via RoleDefinitionsClient, with an opt-in read-only integration test.
  • pkg/infrastructure/azureAPI/azureApiClient.go — adds and initializes RoleDefinitionsClient.
  • pkg/presentation/roleSuggestionFormatter.go — text and JSON output, with tests.
  • cmd/--suggestRoles flag and wiring into the arm/bicep/terraform commands.
  • docs/commandline-flags-and-env-variables.md — documents the new flag.

Testing

  • go build ./..., go vet ./..., and the full unit suite pass.
  • Verified end-to-end against a live Azure subscription: deployed a storage-account sample and confirmed the suggested roles included Storage Account Contributor, with Owner/Contributor correctly deprioritized.

Closes #36

Add a --suggestRoles flag that, after MPF computes the minimum permissions, queries Azure built-in role definitions and suggests role(s) covering them.

- domain: SuggestBuiltInRoles with wildcard-aware matching, NotActions handling, least-privilege breadth-score ranking, and greedy minimal set cover

- infrastructure: RoleDefinitionManager fetches built-in roles via RoleDefinitionsClient

- presentation: text and JSON formatting of suggestions

- wired into arm, bicep, and terraform commands

- unit tests for matching/ranking and formatter; opt-in read-only Azure integration test
@bgdnext64
Brian Gordon Davis (bgdnext64) requested a review from a team as a code owner July 15, 2026 16:39

Copilot AI left a comment

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.

Pull request overview

Adds an opt-in “built-in role suggestion” feature to MPF that, after discovering minimum required permissions, fetches Azure built-in role definitions and suggests least-privilege role(s) (single-role matches, greedy combinations, and uncovered permissions) in text or JSON form.

Changes:

  • Introduces domain logic to match required permissions to built-in roles (wildcard + NotActions support) and rank suggestions by specificity, with unit tests.
  • Adds infrastructure for enumerating Azure built-in role definitions and wires role suggestion into ARM/Bicep/Terraform commands behind --suggestRoles.
  • Adds presentation formatting (text + JSON) and documents the new CLI flag/environment variable.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/usecase/roleSuggester.go Defines BuiltInRoleProvider interface used for role enumeration.
pkg/domain/roleSuggestion.go Implements role matching, greedy set cover, and specificity scoring.
pkg/domain/roleSuggestion_test.go Unit tests for wildcard matching, ordering, combinations, and edge cases.
pkg/infrastructure/azureAPI/azureApiClient.go Adds RoleDefinitionsClient initialization for role enumeration.
pkg/infrastructure/roleDefinitionManager/roleDefinitionManager.go Implements built-in role listing and conversion into domain model.
pkg/infrastructure/roleDefinitionManager/roleDefinitionManager_integration_test.go Read-only integration test for listing built-in roles and running suggestion.
pkg/presentation/roleSuggestionFormatter.go Adds text/JSON formatting for role suggestions.
pkg/presentation/roleSuggestionFormatter_test.go Tests for text output cases, JSON output, and single-match capping.
cmd/rootCmd.go Adds --suggestRoles persistent flag.
cmd/roleSuggestion.go Implements end-to-end “fetch → suggest → display” flow for role suggestions.
cmd/armCmd.go Calls role suggestion after displaying ARM MPF results.
cmd/bicepCmd.go Calls role suggestion after displaying Bicep MPF results.
cmd/terraformCmd.go Calls role suggestion after displaying Terraform MPF results.
docs/commandline-flags-and-env-variables.md Documents --suggestRoles / MPF_SUGGESTROLES and behavior.

Comment thread cmd/roleSuggestion.go
Comment on lines +60 to +64
suggestion := domain.SuggestBuiltInRoles(requiredPermissions, builtInRoles)

if err := presentation.DisplayRoleSuggestion(os.Stdout, suggestion, flgJSONOutput); err != nil {
log.Errorf("Error displaying role suggestion: %v", err)
}
Comment on lines +284 to +306
func actionMatchesPattern(pattern string, action string) bool {
if pattern == "" {
return false
}
if !strings.Contains(pattern, "*") {
return strings.EqualFold(pattern, action)
}

var sb strings.Builder
sb.WriteString("(?i)^")
for _, segment := range strings.Split(pattern, "*") {
sb.WriteString(regexp.QuoteMeta(segment))
sb.WriteString(".*")
}
// Remove the trailing ".*" added after the final segment and anchor the end.
regexStr := strings.TrimSuffix(sb.String(), ".*") + "$"

re, err := regexp.Compile(regexStr)
if err != nil {
return false
}
return re.MatchString(action)
}
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.

Add feature to suggest built-in role/s for the required permissions

2 participants