From 6188cfaf3eb331301f4ca4b3ec28fd3ea341451f Mon Sep 17 00:00:00 2001 From: vj Date: Tue, 31 Mar 2026 12:16:16 -0600 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=90=9B=20Fix=2021=20incorrect=20GCP?= =?UTF-8?q?=20IAM=20permissions=20in=20auto-generated=20manifest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The permission extraction heuristics produced several invalid GCP IAM permission strings. This fixes the generator and regenerates the manifest. **Service name prefix fixes (gcpServiceNameMap):** - cloudresourcemanager.* → resourcemanager.* (9 permissions) - sqladmin.* → cloudsql.* (2 permissions) - security.* → privateca.* (3 permissions) **Method-to-permission override table (new):** - accessapproval.accessApprovalSettings.get → accessapproval.settings.get - binaryauthorization.systemPolicy.get → binaryauthorization.policy.get - cloudkms.cryptoKey.get → cloudkms.cryptoKeys.get - cloudkms.iamPolicy.get → cloudkms.cryptoKeys.getIamPolicy - secretmanager.iamPolicy.get → secretmanager.secrets.getIamPolicy - secretmanager.secretVersions.list → secretmanager.versions.list - artifactregistry.iamPolicy.get → artifactregistry.repositories.getIamPolicy - serviceusage.service.get → serviceusage.services.get **Non-API method filtering (new skip list):** - monitoring.conditionAbsent.get, monitoring.conditionThreshold.get, monitoring.conditionMatchedLog.get, monitoring.conditionMonitoringQueryLanguage.get (protobuf getters, not real API calls) **Other generator fixes:** - Strip "Iter" suffix from gRPC iterator methods (iam.rolesIter.list → iam.roles.list) - Map REST "Aggregated" verb to "list" (dataflow.jobs.aggregated → dataflow.jobs.list) - Skip bare gRPC Get() calls with no resource qualifier (compute.compute.get) Co-Authored-By: Claude Opus 4.6 (1M context) --- .../v1/util/permissions/permissions.go | 58 +++- providers/gcp/resources/gcp.permissions.json | 299 ++++++++---------- 2 files changed, 186 insertions(+), 171 deletions(-) diff --git a/providers-sdk/v1/util/permissions/permissions.go b/providers-sdk/v1/util/permissions/permissions.go index 844726742c..5ab211f62f 100644 --- a/providers-sdk/v1/util/permissions/permissions.go +++ b/providers-sdk/v1/util/permissions/permissions.go @@ -635,7 +635,7 @@ func classifyGCPImport(path string) *gcpImportInfo { // gcpServiceName normalizes GCP service names. var gcpServiceNameMap = map[string]string{ "compute": "compute", - "cloudresourcemanager": "cloudresourcemanager", + "cloudresourcemanager": "resourcemanager", "iam": "iam", "dns": "dns", "bigquery": "bigquery", @@ -643,7 +643,7 @@ var gcpServiceNameMap = map[string]string{ "monitoring": "monitoring", "container": "container", "storage": "storage", - "sqladmin": "sqladmin", + "sqladmin": "cloudsql", "serviceusage": "serviceusage", "apikeys": "apikeys", "kms": "cloudkms", @@ -653,6 +653,7 @@ var gcpServiceNameMap = map[string]string{ "alloydb": "alloydb", "aiplatform": "aiplatform", "privateca": "privateca", + "security": "privateca", "binaryauthorization": "binaryauthorization", "spanner": "spanner", "redis": "redis", @@ -892,8 +893,57 @@ func isGCPAPIMethod(name string) bool { 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 @@ -911,7 +961,7 @@ func gcpMethodToPermission(service, method string) string { 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" @@ -952,7 +1002,7 @@ func gcpRESTToPermission(service, resource, method string) string { } verb := "" switch method { - case "List", "AggregatedList", "Pages": + case "List", "AggregatedList", "Aggregated", "Pages": verb = "list" case "Get", "Do": verb = "get" diff --git a/providers/gcp/resources/gcp.permissions.json b/providers/gcp/resources/gcp.permissions.json index 804a15dd58..55c0b3f312 100644 --- a/providers/gcp/resources/gcp.permissions.json +++ b/providers/gcp/resources/gcp.permissions.json @@ -1,9 +1,9 @@ { "provider": "gcp", "version": "13.3.0", - "generated_at": "2026-03-27T14:04:41-07:00", + "generated_at": "2026-03-31T14:23:13+02:00", "permissions": [ - "accessapproval.accessApprovalSettings.get", + "accessapproval.settings.get", "aiplatform.datasets.list", "aiplatform.endpoints.list", "aiplatform.featureOnlineStores.list", @@ -13,37 +13,29 @@ "alloydb.clusters.list", "alloydb.instances.list", "apikeys.keys.list", - "artifactregistry.iamPolicy.get", + "artifactregistry.repositories.getIamPolicy", "artifactregistry.repositories.list", "backupdr.backupPlans.list", "backupdr.backupVaults.list", "backupdr.dataSources.list", "backupdr.managementServers.list", "bigtable.appProfiles.list", - "binaryauthorization.systemPolicy.get", + "binaryauthorization.policy.get", "clouddeploy.deliveryPipelines.list", "clouddeploy.targets.list", "cloudfunctions.functions.list", - "cloudkms.cryptoKey.get", "cloudkms.cryptoKeyVersions.list", + "cloudkms.cryptoKeys.get", + "cloudkms.cryptoKeys.getIamPolicy", "cloudkms.cryptoKeys.list", - "cloudkms.iamPolicy.get", "cloudkms.keyRings.list", "cloudkms.locations.list", - "cloudresourcemanager.folders.get", - "cloudresourcemanager.folders.list", - "cloudresourcemanager.folders.search", - "cloudresourcemanager.organizations.get", - "cloudresourcemanager.organizations.getIamPolicy", - "cloudresourcemanager.projects.get", - "cloudresourcemanager.projects.getIamPolicy", - "cloudresourcemanager.projects.list", - "cloudresourcemanager.projects.search", "cloudscheduler.jobs.list", + "cloudsql.databases.list", + "cloudsql.instances.list", "cloudtasks.queues.list", "compute.addresses.list", "compute.backendServices.list", - "compute.compute.get", "compute.disks.list", "compute.firewalls.list", "compute.healthChecks.list", @@ -74,7 +66,7 @@ "compute.zones.get", "compute.zones.list", "container.clusters.list", - "dataflow.jobs.aggregated", + "dataflow.jobs.list", "dataproc.clusters.list", "datastore.databases.list", "dns.managedZones.list", @@ -82,42 +74,45 @@ "dns.resourceRecordSets.list", "essentialcontacts.contacts.list", "file.instances.list", - "iam.rolesIter.list", + "iam.roles.list", "iam.serviceAccountKeys.list", "iam.serviceAccounts.list", "logging.buckets.list", "monitoring.alertPolicies.list", - "monitoring.conditionAbsent.get", - "monitoring.conditionMatchedLog.get", - "monitoring.conditionMonitoringQueryLanguage.get", - "monitoring.conditionThreshold.get", "orgpolicy.policies.list", + "privateca.caPools.list", + "privateca.certificateAuthorities.list", + "privateca.certificates.list", "recommender.recommendations.list", "redis.backups.list", "redis.clusters.list", "redis.instances.list", + "resourcemanager.folders.get", + "resourcemanager.folders.list", + "resourcemanager.folders.search", + "resourcemanager.organizations.get", + "resourcemanager.organizations.getIamPolicy", + "resourcemanager.projects.get", + "resourcemanager.projects.getIamPolicy", + "resourcemanager.projects.list", + "resourcemanager.projects.search", "run.jobs.list", "run.operations.list", "run.services.list", - "secretmanager.iamPolicy.get", - "secretmanager.secretVersions.list", + "secretmanager.secrets.getIamPolicy", "secretmanager.secrets.list", - "security.caPools.list", - "security.certificateAuthorities.list", - "security.certificates.list", - "serviceusage.service.get", + "secretmanager.versions.list", + "serviceusage.services.get", "serviceusage.services.list", "spanner.backups.list", "spanner.databases.list", "spanner.instances.list", - "sqladmin.databases.list", - "sqladmin.instances.list", "storage.buckets.getIamPolicy", "storage.buckets.list" ], "details": [ { - "permission": "accessapproval.accessApprovalSettings.get", + "permission": "accessapproval.settings.get", "service": "accessapproval", "action": "GetAccessApprovalSettings", "source_file": "access_approval.go" @@ -177,7 +172,7 @@ "source_file": "apikeys.go" }, { - "permission": "artifactregistry.iamPolicy.get", + "permission": "artifactregistry.repositories.getIamPolicy", "service": "artifactregistry", "action": "GetIamPolicy", "source_file": "artifactregistry.go" @@ -219,7 +214,7 @@ "source_file": "bigtable.go" }, { - "permission": "binaryauthorization.systemPolicy.get", + "permission": "binaryauthorization.policy.get", "service": "binaryauthorization", "action": "GetSystemPolicy", "source_file": "binary_authorization.go" @@ -243,27 +238,27 @@ "source_file": "cloud_functions.go" }, { - "permission": "cloudkms.cryptoKey.get", + "permission": "cloudkms.cryptoKeyVersions.list", "service": "cloudkms", - "action": "GetCryptoKey", + "action": "ListCryptoKeyVersions", "source_file": "kms.go" }, { - "permission": "cloudkms.cryptoKeyVersions.list", + "permission": "cloudkms.cryptoKeys.get", "service": "cloudkms", - "action": "ListCryptoKeyVersions", + "action": "GetCryptoKey", "source_file": "kms.go" }, { - "permission": "cloudkms.cryptoKeys.list", + "permission": "cloudkms.cryptoKeys.getIamPolicy", "service": "cloudkms", - "action": "ListCryptoKeys", + "action": "GetIamPolicy", "source_file": "kms.go" }, { - "permission": "cloudkms.iamPolicy.get", + "permission": "cloudkms.cryptoKeys.list", "service": "cloudkms", - "action": "GetIamPolicy", + "action": "ListCryptoKeys", "source_file": "kms.go" }, { @@ -278,72 +273,24 @@ "action": "ListLocations", "source_file": "kms.go" }, - { - "permission": "cloudresourcemanager.folders.get", - "service": "cloudresourcemanager", - "action": "Folders.Get", - "source_file": "folder.go" - }, - { - "permission": "cloudresourcemanager.folders.list", - "service": "cloudresourcemanager", - "action": "Folders.List", - "source_file": "folder.go" - }, - { - "permission": "cloudresourcemanager.folders.search", - "service": "cloudresourcemanager", - "action": "Folders.Search", - "source_file": "folder.go" - }, - { - "permission": "cloudresourcemanager.organizations.get", - "service": "cloudresourcemanager", - "action": "Organizations.Get", - "source_file": "organization.go" - }, - { - "permission": "cloudresourcemanager.organizations.getIamPolicy", - "service": "cloudresourcemanager", - "action": "Organizations.GetIamPolicy", - "source_file": "organization.go" - }, - { - "permission": "cloudresourcemanager.projects.get", - "service": "cloudresourcemanager", - "action": "Projects.Get", - "source_file": "project.go" - }, - { - "permission": "cloudresourcemanager.projects.getIamPolicy", - "service": "cloudresourcemanager", - "action": "Projects.GetIamPolicy", - "source_file": "project.go" - }, - { - "permission": "cloudresourcemanager.projects.list", - "service": "cloudresourcemanager", - "action": "Projects.List", - "source_file": "discovery.go" - }, - { - "permission": "cloudresourcemanager.projects.list", - "service": "cloudresourcemanager", - "action": "Projects.List", - "source_file": "project.go" - }, - { - "permission": "cloudresourcemanager.projects.search", - "service": "cloudresourcemanager", - "action": "Projects.Search", - "source_file": "project.go" - }, { "permission": "cloudscheduler.jobs.list", "service": "cloudscheduler", "action": "ListJobs", "source_file": "cloudscheduler.go" }, + { + "permission": "cloudsql.databases.list", + "service": "cloudsql", + "action": "Databases.List", + "source_file": "sql.go" + }, + { + "permission": "cloudsql.instances.list", + "service": "cloudsql", + "action": "Instances.List", + "source_file": "sql.go" + }, { "permission": "cloudtasks.queues.list", "service": "cloudtasks", @@ -362,12 +309,6 @@ "action": "BackendServices.AggregatedList", "source_file": "compute.go" }, - { - "permission": "compute.compute.get", - "service": "compute", - "action": "Get", - "source_file": "compute.go" - }, { "permission": "compute.disks.list", "service": "compute", @@ -567,7 +508,7 @@ "source_file": "gke.go" }, { - "permission": "dataflow.jobs.aggregated", + "permission": "dataflow.jobs.list", "service": "dataflow", "action": "Jobs.Aggregated", "source_file": "dataflow.go" @@ -615,7 +556,7 @@ "source_file": "filestore.go" }, { - "permission": "iam.rolesIter.list", + "permission": "iam.roles.list", "service": "iam", "action": "ListRolesIter", "source_file": "iam_roles.go" @@ -645,34 +586,28 @@ "source_file": "monitoring.go" }, { - "permission": "monitoring.conditionAbsent.get", - "service": "monitoring", - "action": "GetConditionAbsent", - "source_file": "monitoring.go" - }, - { - "permission": "monitoring.conditionMatchedLog.get", - "service": "monitoring", - "action": "GetConditionMatchedLog", - "source_file": "monitoring.go" + "permission": "orgpolicy.policies.list", + "service": "orgpolicy", + "action": "ListPolicies", + "source_file": "orgpolicy.go" }, { - "permission": "monitoring.conditionMonitoringQueryLanguage.get", - "service": "monitoring", - "action": "GetConditionMonitoringQueryLanguage", - "source_file": "monitoring.go" + "permission": "privateca.caPools.list", + "service": "privateca", + "action": "ListCaPools", + "source_file": "privateca.go" }, { - "permission": "monitoring.conditionThreshold.get", - "service": "monitoring", - "action": "GetConditionThreshold", - "source_file": "monitoring.go" + "permission": "privateca.certificateAuthorities.list", + "service": "privateca", + "action": "ListCertificateAuthorities", + "source_file": "privateca.go" }, { - "permission": "orgpolicy.policies.list", - "service": "orgpolicy", - "action": "ListPolicies", - "source_file": "orgpolicy.go" + "permission": "privateca.certificates.list", + "service": "privateca", + "action": "ListCertificates", + "source_file": "privateca.go" }, { "permission": "recommender.recommendations.list", @@ -698,6 +633,66 @@ "action": "ListInstances", "source_file": "redis.go" }, + { + "permission": "resourcemanager.folders.get", + "service": "resourcemanager", + "action": "Folders.Get", + "source_file": "folder.go" + }, + { + "permission": "resourcemanager.folders.list", + "service": "resourcemanager", + "action": "Folders.List", + "source_file": "folder.go" + }, + { + "permission": "resourcemanager.folders.search", + "service": "resourcemanager", + "action": "Folders.Search", + "source_file": "folder.go" + }, + { + "permission": "resourcemanager.organizations.get", + "service": "resourcemanager", + "action": "Organizations.Get", + "source_file": "organization.go" + }, + { + "permission": "resourcemanager.organizations.getIamPolicy", + "service": "resourcemanager", + "action": "Organizations.GetIamPolicy", + "source_file": "organization.go" + }, + { + "permission": "resourcemanager.projects.get", + "service": "resourcemanager", + "action": "Projects.Get", + "source_file": "project.go" + }, + { + "permission": "resourcemanager.projects.getIamPolicy", + "service": "resourcemanager", + "action": "Projects.GetIamPolicy", + "source_file": "project.go" + }, + { + "permission": "resourcemanager.projects.list", + "service": "resourcemanager", + "action": "Projects.List", + "source_file": "discovery.go" + }, + { + "permission": "resourcemanager.projects.list", + "service": "resourcemanager", + "action": "Projects.List", + "source_file": "project.go" + }, + { + "permission": "resourcemanager.projects.search", + "service": "resourcemanager", + "action": "Projects.Search", + "source_file": "project.go" + }, { "permission": "run.jobs.list", "service": "run", @@ -717,17 +712,11 @@ "source_file": "cloudrun.go" }, { - "permission": "secretmanager.iamPolicy.get", + "permission": "secretmanager.secrets.getIamPolicy", "service": "secretmanager", "action": "GetIamPolicy", "source_file": "secretmanager.go" }, - { - "permission": "secretmanager.secretVersions.list", - "service": "secretmanager", - "action": "ListSecretVersions", - "source_file": "secretmanager.go" - }, { "permission": "secretmanager.secrets.list", "service": "secretmanager", @@ -735,25 +724,13 @@ "source_file": "secretmanager.go" }, { - "permission": "security.caPools.list", - "service": "security", - "action": "ListCaPools", - "source_file": "privateca.go" - }, - { - "permission": "security.certificateAuthorities.list", - "service": "security", - "action": "ListCertificateAuthorities", - "source_file": "privateca.go" - }, - { - "permission": "security.certificates.list", - "service": "security", - "action": "ListCertificates", - "source_file": "privateca.go" + "permission": "secretmanager.versions.list", + "service": "secretmanager", + "action": "ListSecretVersions", + "source_file": "secretmanager.go" }, { - "permission": "serviceusage.service.get", + "permission": "serviceusage.services.get", "service": "serviceusage", "action": "GetService", "source_file": "services.go" @@ -782,18 +759,6 @@ "action": "ListInstances", "source_file": "spanner.go" }, - { - "permission": "sqladmin.databases.list", - "service": "sqladmin", - "action": "Databases.List", - "source_file": "sql.go" - }, - { - "permission": "sqladmin.instances.list", - "service": "sqladmin", - "action": "Instances.List", - "source_file": "sql.go" - }, { "permission": "storage.buckets.getIamPolicy", "service": "storage", From 0e7cfe8f1d0e5254bddca2c0f2ecc6b7ac25dac1 Mon Sep 17 00:00:00 2001 From: vj Date: Tue, 31 Mar 2026 12:35:21 -0600 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=90=9B=20Fix=2042=20incorrect=20Azure?= =?UTF-8?q?=20RBAC=20permissions=20in=20auto-generated=20manifest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Azure permission extraction heuristics produced many invalid permission strings. This fixes the generator and regenerates the manifest. **ARM provider name fixes (azureServiceToARMMap):** - Microsoft.Datafactory → Microsoft.DataFactory (casing) - Microsoft.Cosmosforpostgresql → Microsoft.DBforPostgreSQL (wrong provider) **Permission override table (new, 42 entries):** Resource path fixes (SDK clients don't include parent paths): - Microsoft.Sql/* → Microsoft.Sql/servers/* or servers/databases/* (18 permissions: databases, firewallRules, encryptionProtector, etc.) - Microsoft.Cache/* → Microsoft.Cache/redis/* (firewallRules, patchSchedules) - Microsoft.DBforMySQL/* → Microsoft.DBforMySQL/servers/* (configurations, databases, firewallRules) - Microsoft.DBforPostgreSQL/* → Microsoft.DBforPostgreSQL/servers/* (configurations, databases, firewallRules) - Microsoft.Network/subnets → virtualNetworks/subnets - Microsoft.Network/flowLogs → networkWatchers/flowLogs - Microsoft.Network/virtualNetworkPeerings → virtualNetworks/virtualNetworkPeerings Resource type name fixes (SDK names differ from ARM types): - Microsoft.Batch/account → batchAccounts, pool → batchAccounts/pools - Microsoft.Network/interfaces → networkInterfaces - Microsoft.Network/securityGroups → networkSecurityGroups - Microsoft.Network/watchers → networkWatchers - Microsoft.Network/virtualNetworkGatewayConnections → connections - Microsoft.Storage/accounts → storageAccounts - Microsoft.Storage/blobContainers → storageAccounts/blobServices/containers - Microsoft.Web/environments → hostingEnvironments - Microsoft.Web/plans → serverfarms - Microsoft.Web/webApps → sites - Microsoft.DBforPostgreSQL/clusters → serverGroupsv2 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../v1/util/permissions/permissions.go | 77 ++++- .../azure/resources/azure.permissions.json | 264 +++++++++--------- 2 files changed, 208 insertions(+), 133 deletions(-) diff --git a/providers-sdk/v1/util/permissions/permissions.go b/providers-sdk/v1/util/permissions/permissions.go index 5ab211f62f..44e73d511f 100644 --- a/providers-sdk/v1/util/permissions/permissions.go +++ b/providers-sdk/v1/util/permissions/permissions.go @@ -1247,6 +1247,11 @@ var azureServiceToARMMap = map[string]string{ "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 { @@ -1260,11 +1265,81 @@ func azureServiceToARM(service string) string { 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", + "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 { diff --git a/providers/azure/resources/azure.permissions.json b/providers/azure/resources/azure.permissions.json index 4e35a5f354..5978db38ef 100644 --- a/providers/azure/resources/azure.permissions.json +++ b/providers/azure/resources/azure.permissions.json @@ -1,29 +1,29 @@ { "provider": "azure", "version": "13.3.0", - "generated_at": "2026-03-30T22:13:12-07:00", + "generated_at": "2026-03-31T12:34:20-06:00", "permissions": [ "Microsoft.Advisor/recommendations/read", "Microsoft.Authorization/roleAssignments/read", "Microsoft.Authorization/roleDefinitions/read", - "Microsoft.Batch/account/read", - "Microsoft.Batch/pool/read", - "Microsoft.Cache/firewallRules/read", - "Microsoft.Cache/patchSchedules/read", + "Microsoft.Batch/batchAccounts/pools/read", + "Microsoft.Batch/batchAccounts/read", + "Microsoft.Cache/redis/firewallRules/read", + "Microsoft.Cache/redis/patchSchedules/read", "Microsoft.Compute/disks/read", "Microsoft.Compute/virtualMachines/read", "Microsoft.ContainerService/managedClusters/read", - "Microsoft.Cosmosforpostgresql/clusters/read", - "Microsoft.DBforMySQL/configurations/read", - "Microsoft.DBforMySQL/databases/read", - "Microsoft.DBforMySQL/firewallRules/read", + "Microsoft.DBforMySQL/servers/configurations/read", + "Microsoft.DBforMySQL/servers/databases/read", + "Microsoft.DBforMySQL/servers/firewallRules/read", "Microsoft.DBforMySQL/servers/read", - "Microsoft.DBforPostgreSQL/configurations/read", - "Microsoft.DBforPostgreSQL/databases/read", - "Microsoft.DBforPostgreSQL/firewallRules/read", + "Microsoft.DBforPostgreSQL/serverGroupsv2/read", + "Microsoft.DBforPostgreSQL/servers/configurations/read", + "Microsoft.DBforPostgreSQL/servers/databases/read", + "Microsoft.DBforPostgreSQL/servers/firewallRules/read", "Microsoft.DBforPostgreSQL/servers/read", + "Microsoft.DataFactory/factories/read", "Microsoft.Databricks/workspaces/read", - "Microsoft.Datafactory/factories/read", "Microsoft.DocumentDB/databaseAccounts/read", "Microsoft.Insights/activityLogAlerts/read", "Microsoft.Insights/components/read", @@ -35,52 +35,52 @@ "Microsoft.Network/applicationSecurityGroups/read", "Microsoft.Network/azureFirewalls/read", "Microsoft.Network/bastionHosts/read", + "Microsoft.Network/connections/read", "Microsoft.Network/firewallPolicies/read", - "Microsoft.Network/flowLogs/read", - "Microsoft.Network/interfaces/read", "Microsoft.Network/loadBalancers/read", "Microsoft.Network/natGateways/read", + "Microsoft.Network/networkInterfaces/read", + "Microsoft.Network/networkSecurityGroups/read", + "Microsoft.Network/networkWatchers/flowLogs/read", + "Microsoft.Network/networkWatchers/read", "Microsoft.Network/privateEndpoints/read", "Microsoft.Network/publicIPAddresses/read", "Microsoft.Network/routeTables/read", - "Microsoft.Network/securityGroups/read", - "Microsoft.Network/subnets/read", - "Microsoft.Network/virtualNetworkGatewayConnections/read", "Microsoft.Network/virtualNetworkGateways/read", - "Microsoft.Network/virtualNetworkPeerings/read", "Microsoft.Network/virtualNetworks/read", - "Microsoft.Network/watchers/read", + "Microsoft.Network/virtualNetworks/subnets/read", + "Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read", "Microsoft.Network/webApplicationFirewallPolicies/read", "Microsoft.Resources/resourceGroups/read", "Microsoft.Resources/resources/read", "Microsoft.Resources/subscriptions/read", "Microsoft.Security/autoProvisioningSettings/read", - "Microsoft.Sql/backupShortTermRetentionPolicies/read", - "Microsoft.Sql/databaseAdvancedThreatProtectionSettings/read", - "Microsoft.Sql/databaseBlobAuditingPolicies/read", - "Microsoft.Sql/databaseSecurityAlertPolicies/read", - "Microsoft.Sql/databaseUsages/read", - "Microsoft.Sql/databases/read", - "Microsoft.Sql/encryptionProtectors/read", - "Microsoft.Sql/firewallRules/read", - "Microsoft.Sql/longTermRetentionPolicies/read", - "Microsoft.Sql/serverAdvancedThreatProtectionSettings/read", - "Microsoft.Sql/serverAzureADAdministrators/read", - "Microsoft.Sql/serverAzureADOnlyAuthentications/read", - "Microsoft.Sql/serverBlobAuditingPolicies/read", - "Microsoft.Sql/serverConnectionPolicies/read", - "Microsoft.Sql/serverSecurityAlertPolicies/read", - "Microsoft.Sql/serverVulnerabilityAssessments/read", + "Microsoft.Sql/servers/administrators/read", + "Microsoft.Sql/servers/advancedThreatProtectionSettings/read", + "Microsoft.Sql/servers/auditingSettings/read", + "Microsoft.Sql/servers/azureADOnlyAuthentications/read", + "Microsoft.Sql/servers/connectionPolicies/read", + "Microsoft.Sql/servers/databases/advancedThreatProtectionSettings/read", + "Microsoft.Sql/servers/databases/auditingSettings/read", + "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies/read", + "Microsoft.Sql/servers/databases/backupShortTermRetentionPolicies/read", + "Microsoft.Sql/servers/databases/read", + "Microsoft.Sql/servers/databases/securityAlertPolicies/read", + "Microsoft.Sql/servers/databases/transparentDataEncryption/read", + "Microsoft.Sql/servers/databases/usages/read", + "Microsoft.Sql/servers/encryptionProtector/read", + "Microsoft.Sql/servers/firewallRules/read", "Microsoft.Sql/servers/read", - "Microsoft.Sql/transparentDataEncryptions/read", - "Microsoft.Sql/virtualNetworkRules/read", - "Microsoft.Storage/accounts/read", - "Microsoft.Storage/blobContainers/read", + "Microsoft.Sql/servers/securityAlertPolicies/read", + "Microsoft.Sql/servers/virtualNetworkRules/read", + "Microsoft.Sql/servers/vulnerabilityAssessments/read", + "Microsoft.Storage/storageAccounts/blobServices/containers/read", + "Microsoft.Storage/storageAccounts/read", "Microsoft.Synapse/workspaces/read", "Microsoft.Web/certificates/read", - "Microsoft.Web/environments/read", - "Microsoft.Web/plans/read", - "Microsoft.Web/webApps/read" + "Microsoft.Web/hostingEnvironments/read", + "Microsoft.Web/serverfarms/read", + "Microsoft.Web/sites/read" ], "details": [ { @@ -102,25 +102,25 @@ "source_file": "iam.go" }, { - "permission": "Microsoft.Batch/account/read", + "permission": "Microsoft.Batch/batchAccounts/pools/read", "service": "Microsoft.Batch", - "action": "NewListPager", + "action": "NewListByBatchAccountPager", "source_file": "batch.go" }, { - "permission": "Microsoft.Batch/pool/read", + "permission": "Microsoft.Batch/batchAccounts/read", "service": "Microsoft.Batch", - "action": "NewListByBatchAccountPager", + "action": "NewListPager", "source_file": "batch.go" }, { - "permission": "Microsoft.Cache/firewallRules/read", + "permission": "Microsoft.Cache/redis/firewallRules/read", "service": "Microsoft.Cache", "action": "NewListPager", "source_file": "redis.go" }, { - "permission": "Microsoft.Cache/patchSchedules/read", + "permission": "Microsoft.Cache/redis/patchSchedules/read", "service": "Microsoft.Cache", "action": "NewListByRedisResourcePager", "source_file": "redis.go" @@ -128,7 +128,7 @@ { "permission": "Microsoft.Compute/disks/read", "service": "Microsoft.Compute", - "action": "Get", + "action": "NewListPager", "source_file": "compute.go" }, { @@ -144,25 +144,19 @@ "source_file": "aks.go" }, { - "permission": "Microsoft.Cosmosforpostgresql/clusters/read", - "service": "Microsoft.Cosmosforpostgresql", - "action": "NewListPager", - "source_file": "cosmosdb.go" - }, - { - "permission": "Microsoft.DBforMySQL/configurations/read", + "permission": "Microsoft.DBforMySQL/servers/configurations/read", "service": "Microsoft.DBforMySQL", "action": "NewListByServerPager", "source_file": "mysql.go" }, { - "permission": "Microsoft.DBforMySQL/databases/read", + "permission": "Microsoft.DBforMySQL/servers/databases/read", "service": "Microsoft.DBforMySQL", "action": "NewListByServerPager", "source_file": "mysql.go" }, { - "permission": "Microsoft.DBforMySQL/firewallRules/read", + "permission": "Microsoft.DBforMySQL/servers/firewallRules/read", "service": "Microsoft.DBforMySQL", "action": "NewListByServerPager", "source_file": "mysql.go" @@ -174,19 +168,25 @@ "source_file": "mysql.go" }, { - "permission": "Microsoft.DBforPostgreSQL/configurations/read", + "permission": "Microsoft.DBforPostgreSQL/serverGroupsv2/read", + "service": "Microsoft.DBforPostgreSQL", + "action": "NewListPager", + "source_file": "cosmosdb.go" + }, + { + "permission": "Microsoft.DBforPostgreSQL/servers/configurations/read", "service": "Microsoft.DBforPostgreSQL", "action": "NewListByServerPager", "source_file": "postgresql.go" }, { - "permission": "Microsoft.DBforPostgreSQL/databases/read", + "permission": "Microsoft.DBforPostgreSQL/servers/databases/read", "service": "Microsoft.DBforPostgreSQL", "action": "NewListByServerPager", "source_file": "postgresql.go" }, { - "permission": "Microsoft.DBforPostgreSQL/firewallRules/read", + "permission": "Microsoft.DBforPostgreSQL/servers/firewallRules/read", "service": "Microsoft.DBforPostgreSQL", "action": "NewListByServerPager", "source_file": "postgresql.go" @@ -197,18 +197,18 @@ "action": "NewListBySubscriptionPager", "source_file": "postgresql.go" }, + { + "permission": "Microsoft.DataFactory/factories/read", + "service": "Microsoft.DataFactory", + "action": "NewListPager", + "source_file": "datafactory.go" + }, { "permission": "Microsoft.Databricks/workspaces/read", "service": "Microsoft.Databricks", "action": "NewListBySubscriptionPager", "source_file": "databricks.go" }, - { - "permission": "Microsoft.Datafactory/factories/read", - "service": "Microsoft.Datafactory", - "action": "NewListPager", - "source_file": "datafactory.go" - }, { "permission": "Microsoft.DocumentDB/databaseAccounts/read", "service": "Microsoft.DocumentDB", @@ -254,7 +254,7 @@ { "permission": "Microsoft.Network/applicationGateways/read", "service": "Microsoft.Network", - "action": "NewListAllPager", + "action": "Get", "source_file": "network.go" }, { @@ -275,6 +275,12 @@ "action": "NewListPager", "source_file": "network.go" }, + { + "permission": "Microsoft.Network/connections/read", + "service": "Microsoft.Network", + "action": "NewListPager", + "source_file": "network.go" + }, { "permission": "Microsoft.Network/firewallPolicies/read", "service": "Microsoft.Network", @@ -282,31 +288,43 @@ "source_file": "network.go" }, { - "permission": "Microsoft.Network/flowLogs/read", + "permission": "Microsoft.Network/loadBalancers/read", "service": "Microsoft.Network", - "action": "NewListPager", + "action": "NewListAllPager", + "source_file": "network.go" + }, + { + "permission": "Microsoft.Network/natGateways/read", + "service": "Microsoft.Network", + "action": "NewListAllPager", "source_file": "network.go" }, { - "permission": "Microsoft.Network/interfaces/read", + "permission": "Microsoft.Network/networkInterfaces/read", "service": "Microsoft.Network", "action": "Get", "source_file": "compute.go" }, { - "permission": "Microsoft.Network/interfaces/read", + "permission": "Microsoft.Network/networkInterfaces/read", "service": "Microsoft.Network", "action": "NewListAllPager", "source_file": "network.go" }, { - "permission": "Microsoft.Network/loadBalancers/read", + "permission": "Microsoft.Network/networkSecurityGroups/read", "service": "Microsoft.Network", "action": "NewListAllPager", "source_file": "network.go" }, { - "permission": "Microsoft.Network/natGateways/read", + "permission": "Microsoft.Network/networkWatchers/flowLogs/read", + "service": "Microsoft.Network", + "action": "NewListPager", + "source_file": "network.go" + }, + { + "permission": "Microsoft.Network/networkWatchers/read", "service": "Microsoft.Network", "action": "NewListAllPager", "source_file": "network.go" @@ -335,24 +353,6 @@ "action": "NewListAllPager", "source_file": "network.go" }, - { - "permission": "Microsoft.Network/securityGroups/read", - "service": "Microsoft.Network", - "action": "NewListAllPager", - "source_file": "network.go" - }, - { - "permission": "Microsoft.Network/subnets/read", - "service": "Microsoft.Network", - "action": "Get", - "source_file": "network.go" - }, - { - "permission": "Microsoft.Network/virtualNetworkGatewayConnections/read", - "service": "Microsoft.Network", - "action": "NewListPager", - "source_file": "network.go" - }, { "permission": "Microsoft.Network/virtualNetworkGateways/read", "service": "Microsoft.Network", @@ -360,21 +360,21 @@ "source_file": "network.go" }, { - "permission": "Microsoft.Network/virtualNetworkPeerings/read", + "permission": "Microsoft.Network/virtualNetworks/read", "service": "Microsoft.Network", - "action": "NewListPager", + "action": "NewListAllPager", "source_file": "network.go" }, { - "permission": "Microsoft.Network/virtualNetworks/read", + "permission": "Microsoft.Network/virtualNetworks/subnets/read", "service": "Microsoft.Network", - "action": "NewListAllPager", + "action": "Get", "source_file": "network.go" }, { - "permission": "Microsoft.Network/watchers/read", + "permission": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read", "service": "Microsoft.Network", - "action": "NewListAllPager", + "action": "NewListPager", "source_file": "network.go" }, { @@ -420,99 +420,93 @@ "source_file": "cloud_defender.go" }, { - "permission": "Microsoft.Sql/backupShortTermRetentionPolicies/read", + "permission": "Microsoft.Sql/servers/administrators/read", "service": "Microsoft.Sql", - "action": "Get", + "action": "NewListByServerPager", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/databaseAdvancedThreatProtectionSettings/read", + "permission": "Microsoft.Sql/servers/advancedThreatProtectionSettings/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/databaseBlobAuditingPolicies/read", + "permission": "Microsoft.Sql/servers/auditingSettings/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/databaseSecurityAlertPolicies/read", + "permission": "Microsoft.Sql/servers/azureADOnlyAuthentications/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/databaseUsages/read", + "permission": "Microsoft.Sql/servers/connectionPolicies/read", "service": "Microsoft.Sql", - "action": "NewListByDatabasePager", - "source_file": "sql.go" - }, - { - "permission": "Microsoft.Sql/databases/read", - "service": "Microsoft.Sql", - "action": "NewListByServerPager", + "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/encryptionProtectors/read", + "permission": "Microsoft.Sql/servers/databases/advancedThreatProtectionSettings/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/firewallRules/read", + "permission": "Microsoft.Sql/servers/databases/auditingSettings/read", "service": "Microsoft.Sql", - "action": "NewListByServerPager", + "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/longTermRetentionPolicies/read", + "permission": "Microsoft.Sql/servers/databases/backupLongTermRetentionPolicies/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/serverAdvancedThreatProtectionSettings/read", + "permission": "Microsoft.Sql/servers/databases/backupShortTermRetentionPolicies/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/serverAzureADAdministrators/read", + "permission": "Microsoft.Sql/servers/databases/read", "service": "Microsoft.Sql", "action": "NewListByServerPager", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/serverAzureADOnlyAuthentications/read", + "permission": "Microsoft.Sql/servers/databases/securityAlertPolicies/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/serverBlobAuditingPolicies/read", + "permission": "Microsoft.Sql/servers/databases/transparentDataEncryption/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/serverConnectionPolicies/read", + "permission": "Microsoft.Sql/servers/databases/usages/read", "service": "Microsoft.Sql", - "action": "Get", + "action": "NewListByDatabasePager", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/serverSecurityAlertPolicies/read", + "permission": "Microsoft.Sql/servers/encryptionProtector/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/serverVulnerabilityAssessments/read", + "permission": "Microsoft.Sql/servers/firewallRules/read", "service": "Microsoft.Sql", - "action": "Get", + "action": "NewListByServerPager", "source_file": "sql.go" }, { @@ -522,25 +516,31 @@ "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/transparentDataEncryptions/read", + "permission": "Microsoft.Sql/servers/securityAlertPolicies/read", "service": "Microsoft.Sql", "action": "Get", "source_file": "sql.go" }, { - "permission": "Microsoft.Sql/virtualNetworkRules/read", + "permission": "Microsoft.Sql/servers/virtualNetworkRules/read", "service": "Microsoft.Sql", "action": "NewListByServerPager", "source_file": "sql.go" }, { - "permission": "Microsoft.Storage/accounts/read", + "permission": "Microsoft.Sql/servers/vulnerabilityAssessments/read", + "service": "Microsoft.Sql", + "action": "Get", + "source_file": "sql.go" + }, + { + "permission": "Microsoft.Storage/storageAccounts/blobServices/containers/read", "service": "Microsoft.Storage", "action": "NewListPager", "source_file": "storage.go" }, { - "permission": "Microsoft.Storage/blobContainers/read", + "permission": "Microsoft.Storage/storageAccounts/read", "service": "Microsoft.Storage", "action": "NewListPager", "source_file": "storage.go" @@ -558,19 +558,19 @@ "source_file": "web.go" }, { - "permission": "Microsoft.Web/environments/read", + "permission": "Microsoft.Web/hostingEnvironments/read", "service": "Microsoft.Web", "action": "NewListPager", "source_file": "web.go" }, { - "permission": "Microsoft.Web/plans/read", + "permission": "Microsoft.Web/serverfarms/read", "service": "Microsoft.Web", "action": "NewListPager", "source_file": "web.go" }, { - "permission": "Microsoft.Web/webApps/read", + "permission": "Microsoft.Web/sites/read", "service": "Microsoft.Web", "action": "NewListSlotsPager", "source_file": "web.go"