From 9839ef22bb6aa6635a7a6315f7d12bffaaeaccd2 Mon Sep 17 00:00:00 2001 From: Tejaswi Salaigari Date: Fri, 8 Aug 2025 15:31:24 -0500 Subject: [PATCH 1/6] Removed rule TenantLevelAPIsNotAllowed RPC-Uri-V1-11 --- docs/rules.md | 18 +-- docs/tenant-level-apis-not-allowed.md | 51 -------- packages/rulesets/CHANGELOG.md | 12 ++ .../rulesets/generated/spectral/az-arm.js | 34 ------ packages/rulesets/package.json | 2 +- packages/rulesets/src/spectral/az-arm.ts | 15 --- .../tenant-level-apis-not-allowed.ts | 27 ---- .../tenant-level-apis-not-allowed.test.ts | 115 ------------------ 8 files changed, 19 insertions(+), 255 deletions(-) delete mode 100644 docs/tenant-level-apis-not-allowed.md delete mode 100644 packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts delete mode 100644 packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts diff --git a/docs/rules.md b/docs/rules.md index 2213a7444..2dda6cab9 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -942,12 +942,6 @@ For more detail, pls refer to https://github.com/microsoft/api-guidelines/blob/v Please refer to [path-resource-type-name-camel-case.md](./path-resource-type-name-camel-case.md) for details. -### Post201Response - -Using post for a create operation is discouraged. - -Please refer to [post201-response.md](./post201-response.md) for details. - ### PostOperationIdContainsUrlVerb A POST operation's operationId should contain the verb indicated at the end of the corresponding url. @@ -962,6 +956,12 @@ Long-running POST operations must have responses with 202 and default return cod Please refer to [post-response-codes.md](./post-response-codes.md) for details. +### Post201Response + +Using post for a create operation is discouraged. + +Please refer to [post201-response.md](./post201-response.md) for details. + ### PreviewVersionOverOneYear Per [Retirement-of-Previews](https://dev.azure.com/msazure/AzureWiki/_wiki/wikis/AzureWiki.wiki/37683/Retirement-of-Previews), service, feature, API, and SKU in preview for over one year need to move to GA or retire. @@ -1244,12 +1244,6 @@ Please refer to [system-data-in-properties-bag.md](./system-data-in-properties-b Please refer to [tags-are-not-allowed-for-proxy-resources.md](./tags-are-not-allowed-for-proxy-resources.md) for details. -### TenantLevelAPIsNotAllowed - -Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. The reason for this guidance is that tenant level APIs have a really broad scope and blast radius. We permit APIs to be at this broad scope under rare conditions. Some ARM feature sets also do not cover tenant level APIs such as the use of AFEC. Additionally, if you intend to bypass the standard RBAC constructs and make the APIs unauthorized, you will need an approval from the PAS team before the open API spec can be merged. - -Please refer to [tenant-level-apis-not-allowed.md](./tenant-level-apis-not-allowed.md) for details. - ### TopLevelResourcesListByResourceGroup Per [ARM guidelines](https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/resource-api-reference.md), all the top-level resources must have a list by resource group operation which returns the collection of the resource. diff --git a/docs/tenant-level-apis-not-allowed.md b/docs/tenant-level-apis-not-allowed.md deleted file mode 100644 index 30eb133b6..000000000 --- a/docs/tenant-level-apis-not-allowed.md +++ /dev/null @@ -1,51 +0,0 @@ -# TenantLevelAPIsNotAllowed - -## Category - -ARM Error - -## Applies to - -ARM OpenAPI(swagger) specs - -## Related ARM Guideline Code - -- RPC-Uri-V1-11 - -## Description - -Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. The reason for this guidance is that tenant level APIs have a really broad scope and blast radius. We permit APIs to be at this broad scope under rare conditions. Some ARM feature sets also do not cover tenant level APIs such as the use of AFEC. Additionally, if you intend to bypass the standard RBAC constructs and make the APIs unauthorized, you will need an approval from the PAS team before the open API spec can be merged. - -## How to fix the violation - -The error can be fixed in one of the following two ways - -1. Do not define tenant level APIs -2. Address both the sub sections below - - 1. Provide a justification as to why you need the APIs to have the broad tenant scope to the ARM API reviewer. To do this, please attend the ARM API review office hours to have a conversation with the ARM API reviewer. To book a slot, please visit aka.ms\armofficehoursinfo. - - 2. In addition to modeling the API at the tenant scope, if you also intend to add the API to the "allowUnauthorizedActions" list in your ARM manifest, you must present your design and get an exception from the PAS team. Once you get an approval, please share the evidence of the approval by dropping a screenshot of the written approval as a comment on the PR. Please proceed by adding a suppression for the linter error indicating that the exception has been approved by the PAS team. If you do not intend to add the API to the "allowUnauthorizedActions" list in your ARM manifest, please add a suppression indicating the same. - -Please use the following guidance to add a suppression - https://github.com/Azure/autorest/blob/main/docs/generate/suppress-warnings.md#suppress-warnings - -To get an approval from PAS, please book their office hours slot at https://aka.ms/azurerbacofficehours . You will have to present the scenario and explain why the API needs to be unauthorized. If the service team would like to reach out over email, they can send an email to authzeng@microsoft.com - -## Good Examples - -```json -... -"/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Music/songs/{songName}" { - "put" {} - } -... -``` - -## Bad Examples -```json -... -"/providers/Microsoft.Music/songs/{songName}" { - "put" {} -} -... -``` \ No newline at end of file diff --git a/packages/rulesets/CHANGELOG.md b/packages/rulesets/CHANGELOG.md index 3192e9b66..397266e8c 100644 --- a/packages/rulesets/CHANGELOG.md +++ b/packages/rulesets/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log - @microsoft.azure/openapi-validator-rulesets +## 2.1.8 + +### Patches + +- Removed rule TenantLevelAPIsNotAllowed RPC-Uri-V1-11 + +## 2.1.7 + +### Patches + +- Updated autorest package.json to 2.2.4 + ## 2.1.6 ### Patches diff --git a/packages/rulesets/generated/spectral/az-arm.js b/packages/rulesets/generated/spectral/az-arm.js index d0a7ac15f..804073fca 100644 --- a/packages/rulesets/generated/spectral/az-arm.js +++ b/packages/rulesets/generated/spectral/az-arm.js @@ -2965,28 +2965,6 @@ const tagsAreNotAllowedForProxyResources = (definition, _opts, ctx) => { return errors; }; -const tenantLevelAPIsNotAllowed = (pathItems, _opts, ctx) => { - if (pathItems === null || typeof pathItems !== "object") { - return []; - } - const path = ctx.path || []; - const apiPaths = Object.keys(pathItems); - if (apiPaths.length < 1) { - return []; - } - const errors = []; - for (const apiPath of apiPaths) { - if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { - errors.push({ - message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team.`, - path: [...path, apiPath], - }); - break; - } - } - return errors; -}; - const trackedExtensionResourcesAreNotAllowed = (apiPath, _opts, ctx) => { var _a, _b, _c; if (apiPath === null || typeof apiPath !== "string") { @@ -3974,18 +3952,6 @@ const ruleset = { function: noDuplicatePathsForScopeParameter, }, }, - TenantLevelAPIsNotAllowed: { - rpcGuidelineCode: "RPC-Uri-V1-11", - description: "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", - message: "{{error}}", - severity: "error", - resolved: true, - formats: [oas2], - given: "$[paths,'x-ms-paths']", - then: { - function: tenantLevelAPIsNotAllowed, - }, - }, TrackedExtensionResourcesAreNotAllowed: { rpcGuidelineCode: "RPC-Uri-V1-12", description: "Extension resources are always considered to be proxy and must not be of the type tracked.", diff --git a/packages/rulesets/package.json b/packages/rulesets/package.json index 27d6c891e..34cc59e15 100644 --- a/packages/rulesets/package.json +++ b/packages/rulesets/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft.azure/openapi-validator-rulesets", - "version": "2.1.7", + "version": "2.1.8", "description": "Azure OpenAPI Validator", "main": "dist/index.js", "scripts": { diff --git a/packages/rulesets/src/spectral/az-arm.ts b/packages/rulesets/src/spectral/az-arm.ts index 209503627..1b1bde743 100644 --- a/packages/rulesets/src/spectral/az-arm.ts +++ b/packages/rulesets/src/spectral/az-arm.ts @@ -50,7 +50,6 @@ import { securityDefinitionsStructure } from "./functions/security-definitions-s import skuValidation from "./functions/sku-validation" import { systemDataInPropertiesBag } from "./functions/system-data-in-properties-bag" import { tagsAreNotAllowedForProxyResources } from "./functions/tags-are-not-allowed-for-proxy-resources" -import { tenantLevelAPIsNotAllowed } from "./functions/tenant-level-apis-not-allowed" import { trackedExtensionResourcesAreNotAllowed } from "./functions/tracked-extension-resources-are-not-allowed" import trackedResourceTagsPropertyInRequest from "./functions/trackedresource-tags-property-in-request" import { validQueryParametersForPointOperations } from "./functions/valid-query-parameters-for-point-operations" @@ -946,20 +945,6 @@ const ruleset: any = { function: noDuplicatePathsForScopeParameter, }, }, - // RPC Code: RPC-Uri-V1-11 - TenantLevelAPIsNotAllowed: { - rpcGuidelineCode: "RPC-Uri-V1-11", - description: - "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", - message: "{{error}}", - severity: "error", - resolved: true, - formats: [oas2], - given: "$[paths,'x-ms-paths']", - then: { - function: tenantLevelAPIsNotAllowed, - }, - }, // RPC Code: RPC-Uri-V1-12 TrackedExtensionResourcesAreNotAllowed: { rpcGuidelineCode: "RPC-Uri-V1-12", diff --git a/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts b/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts deleted file mode 100644 index 02d3b0e5d..000000000 --- a/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts +++ /dev/null @@ -1,27 +0,0 @@ -// This rule checks for tenant level paths of PUT operation and flags errors if found - -export const tenantLevelAPIsNotAllowed = (pathItems: any, _opts: any, ctx: any) => { - if (pathItems === null || typeof pathItems !== "object") { - return [] - } - - const path = ctx.path || [] - const apiPaths = Object.keys(pathItems) - if (apiPaths.length < 1) { - return [] - } - - const errors: any[] = [] - - // check for existence of tenant level paths & throw if exists - for (const apiPath of apiPaths) { - if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { - errors.push({ - message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team.`, - path: [...path, apiPath], - }) - break - } - } - return errors -} diff --git a/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts b/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts deleted file mode 100644 index 3b06703e8..000000000 --- a/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Spectral } from "@stoplight/spectral-core" -import linterForRule from "./utils" - -const ERROR_MESSAGE = - "is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team." - -let linter: Spectral - -beforeAll(async () => { - linter = await linterForRule("TenantLevelAPIsNotAllowed") - return linter -}) - -test("TenantLevelAPIsNotAllowed should find no errors for non tenant level api paths and operations api-path", () => { - const oasDoc = { - swagger: "2.0", - paths: { - "/providers/Microsoft.Music/operations": { - put: { - parameters: {}, - responses: { - "200": {}, - }, - }, - }, - "/subscriptions/{subscriptionId}/providers/Microsoft.Music/songs/{songName}": { - put: { - parameters: {}, - responses: { - "200": {}, - }, - }, - }, - "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft..Music/songs/{songName}": { - get: { - parameters: {}, - responses: { - "200": {}, - }, - }, - }, - }, - } - return linter.run(oasDoc).then((results) => { - expect(results.length).toBe(0) - }) -}) - -test("TenantLevelAPIsNotAllowed should find no errors for extension resources", () => { - const oasDoc = { - swagger: "2.0", - paths: { - "/{resourceUri}/providers/Microsoft.Music/songs": { - put: { - parameters: {}, - responses: { - "200": {}, - }, - }, - }, - "/subscriptions/{subscription1}/resourceGroups/{resourceGroup1}/providers/Microsoft.Foo/resourceType/{resourceType1}/providers/Microsoft.Music/songs": - { - put: { - parameters: {}, - responses: { - "200": {}, - }, - }, - }, - }, - } - return linter.run(oasDoc).then((results) => { - expect(results.length).toBe(0) - }) -}) - -test("TenantLevelAPIsNotAllowed should find no errors for non put teant-level api paths", () => { - const oasDoc = { - swagger: "2.0", - paths: { - "/providers/Microsoft.Music/songs": { - post: { - parameters: {}, - responses: { - "200": {}, - }, - }, - }, - }, - } - return linter.run(oasDoc).then((results) => { - expect(results.length).toBe(0) - }) -}) - -test("TenantLevelAPIsNotAllowed should find errors for tenant level api path for put operation", () => { - const oasDoc = { - swagger: "2.0", - paths: { - "/providers/Microsoft.Music/songs": { - put: { - parameters: {}, - responses: { - "200": {}, - }, - }, - }, - }, - } - return linter.run(oasDoc).then((results) => { - expect(results.length).toBe(1) - expect(results[0].path.join(".")).toBe("paths./providers/Microsoft.Music/songs") - expect(results[0].message).toContain(ERROR_MESSAGE) - }) -}) From 0ad00d7de1dd23551a92ce8419fc2f08eea84582 Mon Sep 17 00:00:00 2001 From: Tejaswi Salaigari Date: Tue, 12 Aug 2025 12:42:06 -0500 Subject: [PATCH 2/6] Revert "Removed rule TenantLevelAPIsNotAllowed RPC-Uri-V1-11" This reverts commit 9839ef22bb6aa6635a7a6315f7d12bffaaeaccd2. --- docs/rules.md | 18 ++- docs/tenant-level-apis-not-allowed.md | 51 ++++++++ packages/rulesets/CHANGELOG.md | 12 -- .../rulesets/generated/spectral/az-arm.js | 34 ++++++ packages/rulesets/package.json | 2 +- packages/rulesets/src/spectral/az-arm.ts | 15 +++ .../tenant-level-apis-not-allowed.ts | 27 ++++ .../tenant-level-apis-not-allowed.test.ts | 115 ++++++++++++++++++ 8 files changed, 255 insertions(+), 19 deletions(-) create mode 100644 docs/tenant-level-apis-not-allowed.md create mode 100644 packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts create mode 100644 packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts diff --git a/docs/rules.md b/docs/rules.md index 2dda6cab9..2213a7444 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -942,6 +942,12 @@ For more detail, pls refer to https://github.com/microsoft/api-guidelines/blob/v Please refer to [path-resource-type-name-camel-case.md](./path-resource-type-name-camel-case.md) for details. +### Post201Response + +Using post for a create operation is discouraged. + +Please refer to [post201-response.md](./post201-response.md) for details. + ### PostOperationIdContainsUrlVerb A POST operation's operationId should contain the verb indicated at the end of the corresponding url. @@ -956,12 +962,6 @@ Long-running POST operations must have responses with 202 and default return cod Please refer to [post-response-codes.md](./post-response-codes.md) for details. -### Post201Response - -Using post for a create operation is discouraged. - -Please refer to [post201-response.md](./post201-response.md) for details. - ### PreviewVersionOverOneYear Per [Retirement-of-Previews](https://dev.azure.com/msazure/AzureWiki/_wiki/wikis/AzureWiki.wiki/37683/Retirement-of-Previews), service, feature, API, and SKU in preview for over one year need to move to GA or retire. @@ -1244,6 +1244,12 @@ Please refer to [system-data-in-properties-bag.md](./system-data-in-properties-b Please refer to [tags-are-not-allowed-for-proxy-resources.md](./tags-are-not-allowed-for-proxy-resources.md) for details. +### TenantLevelAPIsNotAllowed + +Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. The reason for this guidance is that tenant level APIs have a really broad scope and blast radius. We permit APIs to be at this broad scope under rare conditions. Some ARM feature sets also do not cover tenant level APIs such as the use of AFEC. Additionally, if you intend to bypass the standard RBAC constructs and make the APIs unauthorized, you will need an approval from the PAS team before the open API spec can be merged. + +Please refer to [tenant-level-apis-not-allowed.md](./tenant-level-apis-not-allowed.md) for details. + ### TopLevelResourcesListByResourceGroup Per [ARM guidelines](https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/resource-api-reference.md), all the top-level resources must have a list by resource group operation which returns the collection of the resource. diff --git a/docs/tenant-level-apis-not-allowed.md b/docs/tenant-level-apis-not-allowed.md new file mode 100644 index 000000000..30eb133b6 --- /dev/null +++ b/docs/tenant-level-apis-not-allowed.md @@ -0,0 +1,51 @@ +# TenantLevelAPIsNotAllowed + +## Category + +ARM Error + +## Applies to + +ARM OpenAPI(swagger) specs + +## Related ARM Guideline Code + +- RPC-Uri-V1-11 + +## Description + +Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. The reason for this guidance is that tenant level APIs have a really broad scope and blast radius. We permit APIs to be at this broad scope under rare conditions. Some ARM feature sets also do not cover tenant level APIs such as the use of AFEC. Additionally, if you intend to bypass the standard RBAC constructs and make the APIs unauthorized, you will need an approval from the PAS team before the open API spec can be merged. + +## How to fix the violation + +The error can be fixed in one of the following two ways + +1. Do not define tenant level APIs +2. Address both the sub sections below + + 1. Provide a justification as to why you need the APIs to have the broad tenant scope to the ARM API reviewer. To do this, please attend the ARM API review office hours to have a conversation with the ARM API reviewer. To book a slot, please visit aka.ms\armofficehoursinfo. + + 2. In addition to modeling the API at the tenant scope, if you also intend to add the API to the "allowUnauthorizedActions" list in your ARM manifest, you must present your design and get an exception from the PAS team. Once you get an approval, please share the evidence of the approval by dropping a screenshot of the written approval as a comment on the PR. Please proceed by adding a suppression for the linter error indicating that the exception has been approved by the PAS team. If you do not intend to add the API to the "allowUnauthorizedActions" list in your ARM manifest, please add a suppression indicating the same. + +Please use the following guidance to add a suppression - https://github.com/Azure/autorest/blob/main/docs/generate/suppress-warnings.md#suppress-warnings + +To get an approval from PAS, please book their office hours slot at https://aka.ms/azurerbacofficehours . You will have to present the scenario and explain why the API needs to be unauthorized. If the service team would like to reach out over email, they can send an email to authzeng@microsoft.com + +## Good Examples + +```json +... +"/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Music/songs/{songName}" { + "put" {} + } +... +``` + +## Bad Examples +```json +... +"/providers/Microsoft.Music/songs/{songName}" { + "put" {} +} +... +``` \ No newline at end of file diff --git a/packages/rulesets/CHANGELOG.md b/packages/rulesets/CHANGELOG.md index 397266e8c..3192e9b66 100644 --- a/packages/rulesets/CHANGELOG.md +++ b/packages/rulesets/CHANGELOG.md @@ -1,17 +1,5 @@ # Change Log - @microsoft.azure/openapi-validator-rulesets -## 2.1.8 - -### Patches - -- Removed rule TenantLevelAPIsNotAllowed RPC-Uri-V1-11 - -## 2.1.7 - -### Patches - -- Updated autorest package.json to 2.2.4 - ## 2.1.6 ### Patches diff --git a/packages/rulesets/generated/spectral/az-arm.js b/packages/rulesets/generated/spectral/az-arm.js index 804073fca..d0a7ac15f 100644 --- a/packages/rulesets/generated/spectral/az-arm.js +++ b/packages/rulesets/generated/spectral/az-arm.js @@ -2965,6 +2965,28 @@ const tagsAreNotAllowedForProxyResources = (definition, _opts, ctx) => { return errors; }; +const tenantLevelAPIsNotAllowed = (pathItems, _opts, ctx) => { + if (pathItems === null || typeof pathItems !== "object") { + return []; + } + const path = ctx.path || []; + const apiPaths = Object.keys(pathItems); + if (apiPaths.length < 1) { + return []; + } + const errors = []; + for (const apiPath of apiPaths) { + if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { + errors.push({ + message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team.`, + path: [...path, apiPath], + }); + break; + } + } + return errors; +}; + const trackedExtensionResourcesAreNotAllowed = (apiPath, _opts, ctx) => { var _a, _b, _c; if (apiPath === null || typeof apiPath !== "string") { @@ -3952,6 +3974,18 @@ const ruleset = { function: noDuplicatePathsForScopeParameter, }, }, + TenantLevelAPIsNotAllowed: { + rpcGuidelineCode: "RPC-Uri-V1-11", + description: "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", + message: "{{error}}", + severity: "error", + resolved: true, + formats: [oas2], + given: "$[paths,'x-ms-paths']", + then: { + function: tenantLevelAPIsNotAllowed, + }, + }, TrackedExtensionResourcesAreNotAllowed: { rpcGuidelineCode: "RPC-Uri-V1-12", description: "Extension resources are always considered to be proxy and must not be of the type tracked.", diff --git a/packages/rulesets/package.json b/packages/rulesets/package.json index 34cc59e15..27d6c891e 100644 --- a/packages/rulesets/package.json +++ b/packages/rulesets/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft.azure/openapi-validator-rulesets", - "version": "2.1.8", + "version": "2.1.7", "description": "Azure OpenAPI Validator", "main": "dist/index.js", "scripts": { diff --git a/packages/rulesets/src/spectral/az-arm.ts b/packages/rulesets/src/spectral/az-arm.ts index 1b1bde743..209503627 100644 --- a/packages/rulesets/src/spectral/az-arm.ts +++ b/packages/rulesets/src/spectral/az-arm.ts @@ -50,6 +50,7 @@ import { securityDefinitionsStructure } from "./functions/security-definitions-s import skuValidation from "./functions/sku-validation" import { systemDataInPropertiesBag } from "./functions/system-data-in-properties-bag" import { tagsAreNotAllowedForProxyResources } from "./functions/tags-are-not-allowed-for-proxy-resources" +import { tenantLevelAPIsNotAllowed } from "./functions/tenant-level-apis-not-allowed" import { trackedExtensionResourcesAreNotAllowed } from "./functions/tracked-extension-resources-are-not-allowed" import trackedResourceTagsPropertyInRequest from "./functions/trackedresource-tags-property-in-request" import { validQueryParametersForPointOperations } from "./functions/valid-query-parameters-for-point-operations" @@ -945,6 +946,20 @@ const ruleset: any = { function: noDuplicatePathsForScopeParameter, }, }, + // RPC Code: RPC-Uri-V1-11 + TenantLevelAPIsNotAllowed: { + rpcGuidelineCode: "RPC-Uri-V1-11", + description: + "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", + message: "{{error}}", + severity: "error", + resolved: true, + formats: [oas2], + given: "$[paths,'x-ms-paths']", + then: { + function: tenantLevelAPIsNotAllowed, + }, + }, // RPC Code: RPC-Uri-V1-12 TrackedExtensionResourcesAreNotAllowed: { rpcGuidelineCode: "RPC-Uri-V1-12", diff --git a/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts b/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts new file mode 100644 index 000000000..02d3b0e5d --- /dev/null +++ b/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts @@ -0,0 +1,27 @@ +// This rule checks for tenant level paths of PUT operation and flags errors if found + +export const tenantLevelAPIsNotAllowed = (pathItems: any, _opts: any, ctx: any) => { + if (pathItems === null || typeof pathItems !== "object") { + return [] + } + + const path = ctx.path || [] + const apiPaths = Object.keys(pathItems) + if (apiPaths.length < 1) { + return [] + } + + const errors: any[] = [] + + // check for existence of tenant level paths & throw if exists + for (const apiPath of apiPaths) { + if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { + errors.push({ + message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team.`, + path: [...path, apiPath], + }) + break + } + } + return errors +} diff --git a/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts b/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts new file mode 100644 index 000000000..3b06703e8 --- /dev/null +++ b/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts @@ -0,0 +1,115 @@ +import { Spectral } from "@stoplight/spectral-core" +import linterForRule from "./utils" + +const ERROR_MESSAGE = + "is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team." + +let linter: Spectral + +beforeAll(async () => { + linter = await linterForRule("TenantLevelAPIsNotAllowed") + return linter +}) + +test("TenantLevelAPIsNotAllowed should find no errors for non tenant level api paths and operations api-path", () => { + const oasDoc = { + swagger: "2.0", + paths: { + "/providers/Microsoft.Music/operations": { + put: { + parameters: {}, + responses: { + "200": {}, + }, + }, + }, + "/subscriptions/{subscriptionId}/providers/Microsoft.Music/songs/{songName}": { + put: { + parameters: {}, + responses: { + "200": {}, + }, + }, + }, + "/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft..Music/songs/{songName}": { + get: { + parameters: {}, + responses: { + "200": {}, + }, + }, + }, + }, + } + return linter.run(oasDoc).then((results) => { + expect(results.length).toBe(0) + }) +}) + +test("TenantLevelAPIsNotAllowed should find no errors for extension resources", () => { + const oasDoc = { + swagger: "2.0", + paths: { + "/{resourceUri}/providers/Microsoft.Music/songs": { + put: { + parameters: {}, + responses: { + "200": {}, + }, + }, + }, + "/subscriptions/{subscription1}/resourceGroups/{resourceGroup1}/providers/Microsoft.Foo/resourceType/{resourceType1}/providers/Microsoft.Music/songs": + { + put: { + parameters: {}, + responses: { + "200": {}, + }, + }, + }, + }, + } + return linter.run(oasDoc).then((results) => { + expect(results.length).toBe(0) + }) +}) + +test("TenantLevelAPIsNotAllowed should find no errors for non put teant-level api paths", () => { + const oasDoc = { + swagger: "2.0", + paths: { + "/providers/Microsoft.Music/songs": { + post: { + parameters: {}, + responses: { + "200": {}, + }, + }, + }, + }, + } + return linter.run(oasDoc).then((results) => { + expect(results.length).toBe(0) + }) +}) + +test("TenantLevelAPIsNotAllowed should find errors for tenant level api path for put operation", () => { + const oasDoc = { + swagger: "2.0", + paths: { + "/providers/Microsoft.Music/songs": { + put: { + parameters: {}, + responses: { + "200": {}, + }, + }, + }, + }, + } + return linter.run(oasDoc).then((results) => { + expect(results.length).toBe(1) + expect(results[0].path.join(".")).toBe("paths./providers/Microsoft.Music/songs") + expect(results[0].message).toContain(ERROR_MESSAGE) + }) +}) From 6572d6e142a373861c14f86f2046fc600ba2ff38 Mon Sep 17 00:00:00 2001 From: Tejaswi Salaigari Date: Tue, 12 Aug 2025 13:54:47 -0500 Subject: [PATCH 3/6] Modified rule TenantLevelAPIsNotAllowed RPC-Uri-V1-11 to be a warning --- docs/rules.md | 12 ++++++------ docs/tenant-level-apis-not-allowed.md | 2 +- packages/rulesets/CHANGELOG.md | 12 ++++++++++++ packages/rulesets/generated/spectral/az-arm.js | 2 +- packages/rulesets/package.json | 2 +- packages/rulesets/src/spectral/az-arm.ts | 2 +- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/docs/rules.md b/docs/rules.md index 2213a7444..770261bf2 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -942,12 +942,6 @@ For more detail, pls refer to https://github.com/microsoft/api-guidelines/blob/v Please refer to [path-resource-type-name-camel-case.md](./path-resource-type-name-camel-case.md) for details. -### Post201Response - -Using post for a create operation is discouraged. - -Please refer to [post201-response.md](./post201-response.md) for details. - ### PostOperationIdContainsUrlVerb A POST operation's operationId should contain the verb indicated at the end of the corresponding url. @@ -962,6 +956,12 @@ Long-running POST operations must have responses with 202 and default return cod Please refer to [post-response-codes.md](./post-response-codes.md) for details. +### Post201Response + +Using post for a create operation is discouraged. + +Please refer to [post201-response.md](./post201-response.md) for details. + ### PreviewVersionOverOneYear Per [Retirement-of-Previews](https://dev.azure.com/msazure/AzureWiki/_wiki/wikis/AzureWiki.wiki/37683/Retirement-of-Previews), service, feature, API, and SKU in preview for over one year need to move to GA or retire. diff --git a/docs/tenant-level-apis-not-allowed.md b/docs/tenant-level-apis-not-allowed.md index 30eb133b6..99867759c 100644 --- a/docs/tenant-level-apis-not-allowed.md +++ b/docs/tenant-level-apis-not-allowed.md @@ -2,7 +2,7 @@ ## Category -ARM Error +ARM Warning ## Applies to diff --git a/packages/rulesets/CHANGELOG.md b/packages/rulesets/CHANGELOG.md index 3192e9b66..f8df3bf8f 100644 --- a/packages/rulesets/CHANGELOG.md +++ b/packages/rulesets/CHANGELOG.md @@ -1,5 +1,17 @@ # Change Log - @microsoft.azure/openapi-validator-rulesets +## 2.1.8 + +### Patches + +- Modified the rule TenantLevelAPIsNotAllowed RPC-Uri-V1-11 from error to warning + +## 2.1.7 + +### Patches + +- Updated autorest package.json to 2.2.4 +- ## 2.1.6 ### Patches diff --git a/packages/rulesets/generated/spectral/az-arm.js b/packages/rulesets/generated/spectral/az-arm.js index d0a7ac15f..c6086f41e 100644 --- a/packages/rulesets/generated/spectral/az-arm.js +++ b/packages/rulesets/generated/spectral/az-arm.js @@ -3978,7 +3978,7 @@ const ruleset = { rpcGuidelineCode: "RPC-Uri-V1-11", description: "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", message: "{{error}}", - severity: "error", + severity: "warn", resolved: true, formats: [oas2], given: "$[paths,'x-ms-paths']", diff --git a/packages/rulesets/package.json b/packages/rulesets/package.json index 27d6c891e..34cc59e15 100644 --- a/packages/rulesets/package.json +++ b/packages/rulesets/package.json @@ -1,6 +1,6 @@ { "name": "@microsoft.azure/openapi-validator-rulesets", - "version": "2.1.7", + "version": "2.1.8", "description": "Azure OpenAPI Validator", "main": "dist/index.js", "scripts": { diff --git a/packages/rulesets/src/spectral/az-arm.ts b/packages/rulesets/src/spectral/az-arm.ts index 209503627..1cef623f5 100644 --- a/packages/rulesets/src/spectral/az-arm.ts +++ b/packages/rulesets/src/spectral/az-arm.ts @@ -952,7 +952,7 @@ const ruleset: any = { description: "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", message: "{{error}}", - severity: "error", + severity: "warn", resolved: true, formats: [oas2], given: "$[paths,'x-ms-paths']", From 6d343914131b9e512af6e01db56047ffe30efc5c Mon Sep 17 00:00:00 2001 From: Tejaswi Salaigari Date: Tue, 12 Aug 2025 16:39:54 -0500 Subject: [PATCH 4/6] Modified warning text --- docs/rules.md | 2 +- docs/tenant-level-apis-not-allowed.md | 15 ++------------- packages/rulesets/generated/spectral/az-arm.js | 4 ++-- packages/rulesets/src/spectral/az-arm.ts | 2 +- .../functions/tenant-level-apis-not-allowed.ts | 2 +- .../test/tenant-level-apis-not-allowed.test.ts | 2 +- 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/docs/rules.md b/docs/rules.md index 770261bf2..5a045c761 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -1246,7 +1246,7 @@ Please refer to [tags-are-not-allowed-for-proxy-resources.md](./tags-are-not-all ### TenantLevelAPIsNotAllowed -Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. The reason for this guidance is that tenant level APIs have a really broad scope and blast radius. We permit APIs to be at this broad scope under rare conditions. Some ARM feature sets also do not cover tenant level APIs such as the use of AFEC. Additionally, if you intend to bypass the standard RBAC constructs and make the APIs unauthorized, you will need an approval from the PAS team before the open API spec can be merged. +This rule checks for th tenant level APIs. Please refer to [tenant-level-apis-not-allowed.md](./tenant-level-apis-not-allowed.md) for details. diff --git a/docs/tenant-level-apis-not-allowed.md b/docs/tenant-level-apis-not-allowed.md index 99867759c..3de5aafd1 100644 --- a/docs/tenant-level-apis-not-allowed.md +++ b/docs/tenant-level-apis-not-allowed.md @@ -14,22 +14,11 @@ ARM OpenAPI(swagger) specs ## Description -Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. The reason for this guidance is that tenant level APIs have a really broad scope and blast radius. We permit APIs to be at this broad scope under rare conditions. Some ARM feature sets also do not cover tenant level APIs such as the use of AFEC. Additionally, if you intend to bypass the standard RBAC constructs and make the APIs unauthorized, you will need an approval from the PAS team before the open API spec can be merged. +This rule checks for th tenant level APIs. ## How to fix the violation -The error can be fixed in one of the following two ways - -1. Do not define tenant level APIs -2. Address both the sub sections below - - 1. Provide a justification as to why you need the APIs to have the broad tenant scope to the ARM API reviewer. To do this, please attend the ARM API review office hours to have a conversation with the ARM API reviewer. To book a slot, please visit aka.ms\armofficehoursinfo. - - 2. In addition to modeling the API at the tenant scope, if you also intend to add the API to the "allowUnauthorizedActions" list in your ARM manifest, you must present your design and get an exception from the PAS team. Once you get an approval, please share the evidence of the approval by dropping a screenshot of the written approval as a comment on the PR. Please proceed by adding a suppression for the linter error indicating that the exception has been approved by the PAS team. If you do not intend to add the API to the "allowUnauthorizedActions" list in your ARM manifest, please add a suppression indicating the same. - -Please use the following guidance to add a suppression - https://github.com/Azure/autorest/blob/main/docs/generate/suppress-warnings.md#suppress-warnings - -To get an approval from PAS, please book their office hours slot at https://aka.ms/azurerbacofficehours . You will have to present the scenario and explain why the API needs to be unauthorized. If the service team would like to reach out over email, they can send an email to authzeng@microsoft.com + Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest ## Good Examples diff --git a/packages/rulesets/generated/spectral/az-arm.js b/packages/rulesets/generated/spectral/az-arm.js index c6086f41e..4f491c4fe 100644 --- a/packages/rulesets/generated/spectral/az-arm.js +++ b/packages/rulesets/generated/spectral/az-arm.js @@ -2978,7 +2978,7 @@ const tenantLevelAPIsNotAllowed = (pathItems, _opts, ctx) => { for (const apiPath of apiPaths) { if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { errors.push({ - message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team.`, + message: `${apiPath} is a tenant level api. Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest`, path: [...path, apiPath], }); break; @@ -3976,7 +3976,7 @@ const ruleset = { }, TenantLevelAPIsNotAllowed: { rpcGuidelineCode: "RPC-Uri-V1-11", - description: "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", + description: "Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest", message: "{{error}}", severity: "warn", resolved: true, diff --git a/packages/rulesets/src/spectral/az-arm.ts b/packages/rulesets/src/spectral/az-arm.ts index 1cef623f5..8ea47493e 100644 --- a/packages/rulesets/src/spectral/az-arm.ts +++ b/packages/rulesets/src/spectral/az-arm.ts @@ -950,7 +950,7 @@ const ruleset: any = { TenantLevelAPIsNotAllowed: { rpcGuidelineCode: "RPC-Uri-V1-11", description: - "Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Design presentation and getting an exception from the PAS team is needed if APIs cannot be modelled at subscription or resource group level.", + "Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest", message: "{{error}}", severity: "warn", resolved: true, diff --git a/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts b/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts index 02d3b0e5d..b3d23623e 100644 --- a/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts +++ b/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts @@ -17,7 +17,7 @@ export const tenantLevelAPIsNotAllowed = (pathItems: any, _opts: any, ctx: any) for (const apiPath of apiPaths) { if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { errors.push({ - message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team.`, + message: `${apiPath} is a tenant level api. Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest`, path: [...path, apiPath], }) break diff --git a/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts b/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts index 3b06703e8..4d356f858 100644 --- a/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts +++ b/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts @@ -2,7 +2,7 @@ import { Spectral } from "@stoplight/spectral-core" import linterForRule from "./utils" const ERROR_MESSAGE = - "is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. If you cannot model your APIs at these levels, you will need to present your design and get an exception from PAS team." + "is a tenant level api. Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest" let linter: Spectral From b90d6a0d23b3751dba9b409842040b77c473ac5f Mon Sep 17 00:00:00 2001 From: Tejaswi Salaigari Date: Wed, 13 Aug 2025 11:58:41 -0500 Subject: [PATCH 5/6] Modified warning text --- packages/rulesets/generated/spectral/az-arm.js | 2 +- .../src/spectral/functions/tenant-level-apis-not-allowed.ts | 2 +- .../src/spectral/test/tenant-level-apis-not-allowed.test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rulesets/generated/spectral/az-arm.js b/packages/rulesets/generated/spectral/az-arm.js index 4f491c4fe..9b782781c 100644 --- a/packages/rulesets/generated/spectral/az-arm.js +++ b/packages/rulesets/generated/spectral/az-arm.js @@ -2978,7 +2978,7 @@ const tenantLevelAPIsNotAllowed = (pathItems, _opts, ctx) => { for (const apiPath of apiPaths) { if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { errors.push({ - message: `${apiPath} is a tenant level api. Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest`, + message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Please note that these APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest`, path: [...path, apiPath], }); break; diff --git a/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts b/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts index b3d23623e..6655b7786 100644 --- a/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts +++ b/packages/rulesets/src/spectral/functions/tenant-level-apis-not-allowed.ts @@ -17,7 +17,7 @@ export const tenantLevelAPIsNotAllowed = (pathItems: any, _opts: any, ctx: any) for (const apiPath of apiPaths) { if (pathItems[apiPath]["put"] && !apiPath.endsWith("/operations") && apiPath.startsWith("/providers")) { errors.push({ - message: `${apiPath} is a tenant level api. Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest`, + message: `${apiPath} is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Please note that these APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest`, path: [...path, apiPath], }) break diff --git a/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts b/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts index 4d356f858..1da969114 100644 --- a/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts +++ b/packages/rulesets/src/spectral/test/tenant-level-apis-not-allowed.test.ts @@ -2,7 +2,7 @@ import { Spectral } from "@stoplight/spectral-core" import linterForRule from "./utils" const ERROR_MESSAGE = - "is a tenant level api. Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest" + "is a tenant level api. Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Please note that these APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest" let linter: Spectral From 12dd9ab02c83ff32d54a59e8ad2fe1c2c675e75e Mon Sep 17 00:00:00 2001 From: Tejaswi Salaigari Date: Thu, 14 Aug 2025 11:54:40 -0500 Subject: [PATCH 6/6] Mispelled --- docs/rules.md | 2 +- docs/tenant-level-apis-not-allowed.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rules.md b/docs/rules.md index 5a045c761..a5ce73411 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -1246,7 +1246,7 @@ Please refer to [tags-are-not-allowed-for-proxy-resources.md](./tags-are-not-all ### TenantLevelAPIsNotAllowed -This rule checks for th tenant level APIs. +This rule checks for the tenant level APIs. Please refer to [tenant-level-apis-not-allowed.md](./tenant-level-apis-not-allowed.md) for details. diff --git a/docs/tenant-level-apis-not-allowed.md b/docs/tenant-level-apis-not-allowed.md index 3de5aafd1..2c6e2f66a 100644 --- a/docs/tenant-level-apis-not-allowed.md +++ b/docs/tenant-level-apis-not-allowed.md @@ -14,11 +14,11 @@ ARM OpenAPI(swagger) specs ## Description -This rule checks for th tenant level APIs. +This rule checks for the tenant level APIs. ## How to fix the violation - Tenant level APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest +Tenant level APIs are strongly discouraged and subscription or resource group level APIs are preferred instead. Please note that these APIs require a review from the security RBAC team during manifest check-in. For details, refer to the Manifest security review process: https://eng.ms/docs/microsoft-security/identity/auth-authz/access-control-managed-identityacmi/policy-administration-service/pas-wiki/livesite/security/manifest ## Good Examples