From bd8bccbd033539c2560840c055e0c0f55a7cb694 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 4 Jun 2026 11:35:14 +0000 Subject: [PATCH] feat(asm): add 403 Forbidden response to all endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 401 and 403 are distinct: 401 means unauthenticated, 403 means authenticated but lacking permission. In a multi-tenant MSSP environment, a valid token scoped to one tenant will correctly receive 403 when accessing another tenant's assets, scans, or vulnerabilities — not 401. Documents this contract for integrators and enables SDK generators to produce correct error-handling code. https://claude.ai/code/session_01VojGqysVpUpTbNquLSsPF3 --- asm/openapi.yaml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/asm/openapi.yaml b/asm/openapi.yaml index 3673084..f0d1482 100644 --- a/asm/openapi.yaml +++ b/asm/openapi.yaml @@ -99,6 +99,8 @@ paths: $ref: '#/components/schemas/Asset' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' @@ -119,6 +121,8 @@ paths: $ref: '#/components/schemas/AssetDetail' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' patch: @@ -143,6 +147,8 @@ paths: $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' delete: @@ -157,6 +163,8 @@ paths: description: Asset archived '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' @@ -189,6 +197,8 @@ paths: $ref: '#/components/schemas/Scan' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' post: operationId: triggerScan summary: Trigger scan @@ -213,6 +223,8 @@ paths: $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/RateLimited' @@ -239,6 +251,8 @@ paths: $ref: '#/components/schemas/ScanDetail' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' @@ -292,6 +306,8 @@ paths: $ref: '#/components/schemas/Vulnerability' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' /vulnerabilities/{vuln_id}: parameters: @@ -316,6 +332,8 @@ paths: $ref: '#/components/schemas/VulnerabilityDetail' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' patch: @@ -340,6 +358,8 @@ paths: $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' @@ -362,6 +382,8 @@ paths: $ref: '#/components/schemas/Tag' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' post: operationId: createTag summary: Create tag @@ -392,6 +414,8 @@ paths: $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' + '403': + $ref: '#/components/responses/Forbidden' components: securitySchemes: @@ -454,6 +478,17 @@ components: application/json: schema: $ref: '#/components/schemas/Error' + Forbidden: + description: Authenticated but not authorized for this resource or action + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + error: + code: forbidden + message: You do not have permission to perform this action + RateLimited: description: Rate limit exceeded headers: