Azure / Azure/azure-rest-api-specs
[BUG] [Key Vault] accessPolicies/remove with API 2026-02-01 silently fails when permissions use lowercase
- Dominant language
- TypeSpec
- Stars
- 3.1k
- Forks
- 5.9k
- Avg merge
- 3d 37m
- Merged PRs (30d)
- 446
Description
### API Spec link
https://github.com/Azure/azure-rest-api-specs/blob/main/specification/keyvault/resource-manager/Microsoft.KeyVault/KeyVault/stable/2026-02-01/openapi.json#L1804-L1881
https://github.com/Azure/azure-rest-api-specs/blob/main/specification/keyvault/resource-manager/Microsoft.KeyVault/KeyVault/stable/2026-02-01/openapi.json#L2913-L3008
### API Spec version
2026-02-01
### Describe the bug
The `PUT .../accessPolicies/remove?api-version=2026-02-01` endpoint **silently fails when permission values in the request body use different casing than what the API returns**. The response is HTTP 200, but the access policy is not removed.
Details:
- The accessPolicies/remove endpoint performs case-sensitive matching on permission values, so sending lowercase values (as the spec defines) results in a silent no-op.
- Note: The accessPolicies/add endpoint already handles this correctly and accepts permissions regardless of casing.
Impact:
- Any SDK or client that normalizes enum values to match the spec definition (lowercase) will be unable to remove access policies via this endpoint. This is a data-integrity issue disguised as a successful operation.
### Expected behavior
The accessPolicies/remove endpoint should perform case-insensitive matching on permission values, consistent with accessPolicies/add.
### Actual behavior
- The API stores and returns permissions in TitleCase: "Backup", "Create", "Delete", etc. [relevant: https://github.com/Azure/azure-rest-api-specs/issues/34772]
- When calling `accessPolicies/remove` with lowercase permission values (matching the spec definition): "backup", "create", "delete" — the API returns HTTP 200 but the policy is not removed.
- Subsequent GET calls confirm the access policy is still present.
### Reproduction Steps
For reference: `X-Ms-Correlation-Request-Id: 184a0f32-d9d3-fec2-b869-4fbcd01728df`
1. Create a vault with an access policy via the Azure Portal — note that permissions are stored in PascalCase (e.g., "Backup", "Create", "Get").
```
PUT .../accessPolicies/add?api-version=2026-02-01
{
"properties": {
"accessPolicies": [{
"objectId": "{objectId}",
"tenantId": "{tenantId}",
"permissions": {
"certificates": ["Backup","Create","Delete","Get"],
"keys": ["Create"],
"secrets": ["Set"]
}
}]
}
}
```
2. Attempt removal with lowercase permissions (as defined in spec):
```
az rest --method PUT \
--url "https://management.azure.com/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/{vault}/accessPolicies/remove?api-version=2026-02-01" \
--body '{
"properties": {
"accessPolicies": [{
"objectId": "{objectId}",
"tenantId": "{tenantId}",
"permissions": {
"certificates": ["backup","create","delete","get"],
"keys": ["create"],
"secrets": ["set"]
}
}]
}
}'
```
3. Returns 200, but policy is NOT removed
4. GET the vault — policy still exists with TitleCase permissions
### Environment
_No response_
Contributor guide
Research direction
Start with the two linked sections of the Key Vault 2026-02-01 openapi.json and compare the accessPolicies/add and accessPolicies/remove definitions. Reproduce the documented request with az rest, then verify the result with a GET. Done means the remove operation no longer silently leaves the policy when permission casing differs, consistent with the reported add behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, openapi
- Domain
- api, authorization, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100