Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 130 additions & 5 deletions providers-sdk/v1/util/permissions/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -635,15 +635,15 @@
// gcpServiceName normalizes GCP service names.
var gcpServiceNameMap = map[string]string{
"compute": "compute",
"cloudresourcemanager": "cloudresourcemanager",
"cloudresourcemanager": "resourcemanager",
"iam": "iam",
"dns": "dns",
"bigquery": "bigquery",
"logging": "logging",
"monitoring": "monitoring",
"container": "container",
"storage": "storage",
"sqladmin": "sqladmin",
"sqladmin": "cloudsql",
"serviceusage": "serviceusage",
"apikeys": "apikeys",
"kms": "cloudkms",
Expand All @@ -653,6 +653,7 @@
"alloydb": "alloydb",
"aiplatform": "aiplatform",
"privateca": "privateca",
"security": "privateca",
"binaryauthorization": "binaryauthorization",
"spanner": "spanner",
"redis": "redis",
Expand Down Expand Up @@ -892,8 +893,57 @@
return false
}

// gcpPermissionOverrides maps (service, method) to the correct IAM permission
// for cases where the automatic derivation produces incorrect results.
var gcpPermissionOverrides = map[string]map[string]string{
"accessapproval": {
"GetAccessApprovalSettings": "accessapproval.settings.get",
},
"binaryauthorization": {
"GetSystemPolicy": "binaryauthorization.policy.get",
},
"cloudkms": {
"GetCryptoKey": "cloudkms.cryptoKeys.get",
"GetIamPolicy": "cloudkms.cryptoKeys.getIamPolicy",
},
"secretmanager": {
"ListSecretVersions": "secretmanager.versions.list",
"GetIamPolicy": "secretmanager.secrets.getIamPolicy",
},
"artifactregistry": {
"GetIamPolicy": "artifactregistry.repositories.getIamPolicy",
},
"serviceusage": {
"GetService": "serviceusage.services.get",
},
}

// gcpSkipMethods lists method names that match isGCPAPIMethod patterns but are
// actually protobuf getter methods or internal helpers, not real API calls.
var gcpSkipMethods = map[string]bool{
"GetConditionAbsent": true,
"GetConditionThreshold": true,
"GetConditionMatchedLog": true,
"GetConditionMonitoringQueryLanguage": true,
}

// gcpMethodToPermission maps a gRPC method to a GCP IAM permission.
func gcpMethodToPermission(service, method string) string {
// Skip known non-API methods
if gcpSkipMethods[method] {
return ""
}

// Strip "Iter" suffix from iterator helper methods (e.g., ListRolesIter -> ListRoles)
method = strings.TrimSuffix(method, "Iter")

// Check for explicit overrides
if overrides, ok := gcpPermissionOverrides[service]; ok {
if perm, ok := overrides[method]; ok {
return perm
}
}

// gRPC methods: ListKeyRings -> cloudkms.keyRings.list
// ListServiceAccounts -> iam.serviceAccounts.list
// GetKeyRotationStatus -> cloudkms.cryptoKeys.get
Expand All @@ -911,7 +961,7 @@
verb = "get"
resource = strings.TrimPrefix(method, "Get")
if resource == "" {
resource = service
return "" // bare Get without resource name is ambiguous
}
} else if strings.HasPrefix(method, "Create") {
verb = "create"
Expand Down Expand Up @@ -952,7 +1002,7 @@
}
verb := ""
switch method {
case "List", "AggregatedList", "Pages":
case "List", "AggregatedList", "Aggregated", "Pages":
verb = "list"
case "Get", "Do":
verb = "get"
Expand Down Expand Up @@ -1197,6 +1247,11 @@
"logic": "Microsoft.Logic",
"msi": "Microsoft.ManagedIdentity",
"frontdoor": "Microsoft.Network",
"datafactory": "Microsoft.DataFactory",
"cosmosforpostgresql": "Microsoft.DBforPostgreSQL",
"batch": "Microsoft.Batch",
"databricks": "Microsoft.Databricks",
"synapse": "Microsoft.Synapse",
}

func azureServiceToARM(service string) string {
Expand All @@ -1210,11 +1265,81 @@
return "Microsoft." + strings.ToUpper(service[:1]) + service[1:]
}

// azurePermissionOverrides maps generated permission strings to the correct
// Azure RBAC permission. Many Azure SDK client names don't include parent
// resource paths (e.g., servers/) or use different names than the ARM API.
var azurePermissionOverrides = map[string]string{
// Batch: client names don't match ARM resource types
"Microsoft.Batch/account/read": "Microsoft.Batch/batchAccounts/read",
"Microsoft.Batch/pool/read": "Microsoft.Batch/batchAccounts/pools/read",

// Cache (Redis): sub-resources need redis/ parent path
"Microsoft.Cache/firewallRules/read": "Microsoft.Cache/redis/firewallRules/read",
"Microsoft.Cache/patchSchedules/read": "Microsoft.Cache/redis/patchSchedules/read",

// Cosmos DB for PostgreSQL: SDK package maps to different ARM resource type
"Microsoft.DBforPostgreSQL/clusters/read": "Microsoft.DBforPostgreSQL/serverGroupsv2/read",

// MySQL: sub-resources need servers/ parent path
"Microsoft.DBforMySQL/configurations/read": "Microsoft.DBforMySQL/servers/configurations/read",
"Microsoft.DBforMySQL/databases/read": "Microsoft.DBforMySQL/servers/databases/read",
"Microsoft.DBforMySQL/firewallRules/read": "Microsoft.DBforMySQL/servers/firewallRules/read",

// PostgreSQL: sub-resources need servers/ parent path
"Microsoft.DBforPostgreSQL/configurations/read": "Microsoft.DBforPostgreSQL/servers/configurations/read",
"Microsoft.DBforPostgreSQL/databases/read": "Microsoft.DBforPostgreSQL/servers/databases/read",
"Microsoft.DBforPostgreSQL/firewallRules/read": "Microsoft.DBforPostgreSQL/servers/firewallRules/read",

// Network: client names don't match ARM resource types
"Microsoft.Network/interfaces/read": "Microsoft.Network/networkInterfaces/read",

Check failure on line 1294 in providers-sdk/v1/util/permissions/permissions.go

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not properly formatted (gofmt)
"Microsoft.Network/securityGroups/read": "Microsoft.Network/networkSecurityGroups/read",
"Microsoft.Network/subnets/read": "Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/flowLogs/read": "Microsoft.Network/networkWatchers/flowLogs/read",
"Microsoft.Network/watchers/read": "Microsoft.Network/networkWatchers/read",
"Microsoft.Network/virtualNetworkPeerings/read": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read",
"Microsoft.Network/virtualNetworkGatewayConnections/read": "Microsoft.Network/connections/read",

// SQL: sub-resources need servers/ or servers/databases/ parent paths
"Microsoft.Sql/databases/read": "Microsoft.Sql/servers/databases/read",
"Microsoft.Sql/firewallRules/read": "Microsoft.Sql/servers/firewallRules/read",
"Microsoft.Sql/virtualNetworkRules/read": "Microsoft.Sql/servers/virtualNetworkRules/read",
"Microsoft.Sql/encryptionProtectors/read": "Microsoft.Sql/servers/encryptionProtector/read",
"Microsoft.Sql/backupShortTermRetentionPolicies/read": "Microsoft.Sql/servers/databases/backupShortTermRetentionPolicies/read",
"Microsoft.Sql/longTermRetentionPolicies/read": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies/read",
"Microsoft.Sql/transparentDataEncryptions/read": "Microsoft.Sql/servers/databases/transparentDataEncryption/read",
"Microsoft.Sql/databaseAdvancedThreatProtectionSettings/read": "Microsoft.Sql/servers/databases/advancedThreatProtectionSettings/read",
"Microsoft.Sql/databaseBlobAuditingPolicies/read": "Microsoft.Sql/servers/databases/auditingSettings/read",
"Microsoft.Sql/databaseSecurityAlertPolicies/read": "Microsoft.Sql/servers/databases/securityAlertPolicies/read",
"Microsoft.Sql/databaseUsages/read": "Microsoft.Sql/servers/databases/usages/read",
"Microsoft.Sql/serverAdvancedThreatProtectionSettings/read": "Microsoft.Sql/servers/advancedThreatProtectionSettings/read",
"Microsoft.Sql/serverAzureADAdministrators/read": "Microsoft.Sql/servers/administrators/read",
"Microsoft.Sql/serverAzureADOnlyAuthentications/read": "Microsoft.Sql/servers/azureADOnlyAuthentications/read",
"Microsoft.Sql/serverBlobAuditingPolicies/read": "Microsoft.Sql/servers/auditingSettings/read",
"Microsoft.Sql/serverConnectionPolicies/read": "Microsoft.Sql/servers/connectionPolicies/read",
"Microsoft.Sql/serverSecurityAlertPolicies/read": "Microsoft.Sql/servers/securityAlertPolicies/read",
"Microsoft.Sql/serverVulnerabilityAssessments/read": "Microsoft.Sql/servers/vulnerabilityAssessments/read",

// Storage: client names don't match ARM resource types
"Microsoft.Storage/accounts/read": "Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/blobContainers/read": "Microsoft.Storage/storageAccounts/blobServices/containers/read",

// Web: client names don't match ARM resource types
"Microsoft.Web/environments/read": "Microsoft.Web/hostingEnvironments/read",
"Microsoft.Web/plans/read": "Microsoft.Web/serverfarms/read",
"Microsoft.Web/webApps/read": "Microsoft.Web/sites/read",
}

// azurePermission constructs the RBAC permission string.
func azurePermission(armProvider, resourceType string) string {
// Convert PascalCase to camelCase for the resource type
rt := pascalToCamelCase(resourceType)
return armProvider + "/" + rt + "/read"
perm := armProvider + "/" + rt + "/read"

// Check for overrides where SDK names don't match ARM resource types
if override, ok := azurePermissionOverrides[perm]; ok {
return override
}
return perm
}

func pascalToCamelCase(s string) string {
Expand Down
Loading
Loading