Azure / Azure/data-api-builder
[Enh]: Restrict client predicates per entity field
- Dominant language
- C#
- Stars
- 1.5k
- Forks
- 370
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 8
Description
## Problem
Today, if a role has read access to an entity field, clients can generally use that field in REST `$filter` / `$orderby` and GraphQL `filter` / `orderBy` inputs.
That is good for usability, but it leaves large entities exposed to expensive queries when clients filter or sort on unindexed columns. On large tables, this can trigger table scans and become a denial-of-service risk.
DAB already supports field-level include/exclude permissions, and I verified that excluding a field prevents filtering/sorting on that field. However, that is too broad for this scenario: customers may want a field to be **readable** but **restricted from client predicates/order-by**.
## Proposal
Add per-field restriction controls to entity field metadata.
Suggested config shape:
```json
{
"entities": {
"Order": {
"source": { "object": "dbo.Orders", "type": "table" },
"fields": [
{ "name": "OrderId" },
{ "name": "CustomerId" },
{ "name": "Notes", "restricted": true },
{ "name": "Description", "restricted": true }
]
}
}
}
```
Recommended default:
```json
"restricted": false
```
This preserves current behavior unless customers opt in to restricting a field.
## Expected behavior
If a field is readable but marked `restricted: true`:
- REST should allow the field in the selected/output payload.
- GraphQL should allow the field in the selected/output payload.
- REST should reject `$filter` using that field.
- REST should reject `$orderby` using that field, or the same option should also apply to sorting.
- GraphQL should omit that field from generated `filter` / `orderBy` input types, or reject it consistently at validation time.
Example REST request:
```http
GET /api/Orders?$filter=Notes eq 'foo'
```
Suggested response:
```json
{
"error": {
"code": "FieldRestricted",
"message": "Restricted field 'Notes' cannot be used to filter this entity response.",
"status": 400
}
}
```
For ordering:
```json
{
"error": {
"code": "FieldRestricted",
"message": "Restricted field 'Notes' cannot be used to order this entity response.",
"status": 400
}
}
```
## Why field-level include/exclude is not enough
Current field exclusion can block filters, but it also removes read access. That does not solve the common case where a field is safe to return but unsafe to predicate on.
## Benefit
- Prevents accidental or malicious table scans on large entities.
- Lets API authors expose rich read models without exposing every column as a query predicate.
- Provides a clear, config-level performance/security contract.
- Preserves backwards compatibility with `restricted: false` as the default.
Contributor guide
Assessment
This issue has not been assessed yet.