Authorization and roles in Data API builder
Data API builder uses a role-based authorization workflow. Any incoming request, authenticated or not, is assigned to a role. Roles can be System Roles or User Roles. The assigned role is then checked against the defined permissions specified in the configuration file to understand what actions, fields, and policies are available for that role on the requested entity.
Roles
Roles set the permissions context in which a request should be executed. For each entity defined in the runtime config, you can define a set of roles and associated permissions that determine how the entity can be accessed in both the REST and GraphQL endpoints.
Data API builder evaluates requests in the context of a single role:
anonymous
when no access token is presented.authenticated
when a valid access token is presented.<CUSTOM_USER_ROLE>
when a valid access token is presented and theX-MS-API-ROLE
HTTP header is included specifying a user role that is also included in the access token'sroles
claim.
Roles are not additive, which means that a user who is a member of both Role1
and Role2
doesn't inherit the permissions associated with both roles.
System roles
System roles are built-in roles recognized by Data API builder. A system role is autoassigned to a requestor regardless of the requestor's role membership denoted in their access tokens. There are two system roles: anonymous
and authenticated
.
Anonymous system role
The anonymous
system role is assigned to requests executed by unauthenticated users. Runtime configuration defined entities must include permissions for the anonymous
role if unauthenticated access is desired.
Example
The following Data API builder runtime configuration demonstrates explicitly configuring the system role anonymous
to include read access to the Book entity:
"Book": {
"source": "books",
"permissions": [
{
"role": "anonymous",
"actions": [ "read" ]
}
]
}
When a client application sends a request accessing the Book entity on behalf of an unauthenticated user, the app shouldn't include the Authorization
HTTP header.
Authenticated system role
The authenticated
system role is assigned to requests executed by authenticated users.
Example
The following Data API builder runtime configuration demonstrates explicitly configuring the system role authenticated
to include read access to the Book entity:
"Book": {
"source": "books",
"permissions": [
{
"role": "authenticated",
"actions": [ "read" ]
}
]
}
User roles
User roles are nonsystem roles that are assigned to users within the identity provider you set in the runtime config. For Data API builder to evaluate a request in the context of a user role, two requirements must be met:
- The client app supplied access token must include role claims that list a user's role membership.
- The client app must include the HTTP header
X-MS-API-ROLE
with requests and set the header's value as the desired user role.
Role evaluation example
The following example demonstrates requests made to the Book
entity that is configured in the Data API builder runtime configuration as follows:
"Book": {
"source": "books",
"permissions": [
{
"role": "anonymous",
"actions": [ "read" ]
},
{
"role": "authenticated",
"actions": [ "read" ]
},
{
"role": "author",
"actions": [ "read" ]
}
]
}
In Static Web Apps, a user is a member of the anonymous role by default. If the user is authenticated, the user is a member of both the anonymous
and authenticated
roles.
When a client app sends an authenticated request to Data API builder deployed using Static Web Apps database connections (Preview), the client app supplies an access token that Static Web Apps transforms into JSON:
{
"identityProvider": "azuread",
"userId": "d75b260a64504067bfc5b2905e3b8182",
"userDetails": "username",
"userRoles": ["anonymous", "authenticated", "author"]
}
Because Data API builder evaluates requests in the context of a single role, it evaluates the request in the context of the system role authenticated
by default.
If the client application's request also includes the HTTP header X-MS-API-ROLE
with the value author
, the request is evaluated in the context of the author
role. An example request including an access token and X-MS-API-ROLE
HTTP header:
curl -k -r GET -H 'Authorization: Bearer ey...' -H 'X-MS-API-ROLE: author' https://localhost:5001/api/Book
Important
A client app's request is rejected when the supplied access token's roles
claim doesn't contain the role listed in the X-MS-API-ROLE
header.
Permissions
Permissions describe:
- Who can make requests on an entity based on role membership?
- What actions (create, read, update, delete, execute) a user can perform?
- Which fields are accessible for a particular action?
- Which extra restrictions exist on the results returned by a request?
The syntax for defining permissions is described in the runtime configuration article.
Important
There may be multiple roles defined within a single entity's permissions configuration. However, a request is only evaluated in the context of a single role:
- By default, either the system role
anonymous
orauthenticated
- When included, the role set in the
X-MS-API-ROLE
HTTP header.
Secure by default
By default, an entity has no permissions configured, which means no one can access the entity. Additionally, Data API builder ignores database objects when they aren't referenced in the runtime configuration.
Permissions must be explicitly configured
To allow unauthenticated access to an entity, the anonymous
role must be explicitly defined in the entity's permissions. For example, the book
entity's permissions is explicitly set to allow unauthenticated read access:
"book": {
"source": "dbo.books",
"permissions": [{
"role": "anonymous",
"actions": [ "read" ]
}]
}
To simplify permissions definition on an entity, assume that if there are no specific permissions for the authenticated
role, then the permissions defined for the anonymous
role are used. The book
configuration shown previously allows any anonymous or authenticated user's to perform read operations on the book
entity.
When read operations should be restricted to authenticated users only, the following permissions configuration should be set, resulting in the rejection of unauthenticated requests:
"book": {
"source": "dbo.books",
"permissions": [{
"role": "authenticated",
"actions": [ "read" ]
}]
}
An entity doesn't require and isn't preconfigured with permissions for the anonymous
and authenticated
roles. One or more user roles can be defined within an entity's permissions configuration and all other undefined roles, system, or user defined, are automatically denied access.
In the following example, the user role administrator
is the only defined role for the book
entity. A user must be a member of the administrator
role and include that role in the X-MS-API-ROLE
HTTP header to operate on the book
entity:
"book": {
"source": "dbo.books",
"permissions": [{
"role": "administrator",
"actions": [ "*" ]
}]
}
Note
To enforce access control for GraphQL queries when using Data API builder with Azure Cosmos DB, you are required to use the @authorize
directive in your supplied GraphQL schema file.
However, for GraphQL mutations and filters in GraphQL queries, access control still is enforced by the permissions configuration as described previously.
Actions
Actions describe the accessibility of an entity within the scope of a role. Actions can be specified individually or with the wildcard shortcut: *
(asterisk). The wildcard shortcut represents all actions supported for the entity type:
- Tables and Views:
create
,read
,update
,delete
- Stored Procedures:
execute
For more information about actions, see the configuration file documentation.
Field access
You can configure which fields should be accessible for an action. For example, you can set which fields to include and exclude from the read
action.
The following example prevents users in the free-access
role from performing read operations on Column3
. References to Column3
in GET requests (REST endpoint) or queries (GraphQL endpoint) result in a rejected request:
"book": {
"source": "dbo.books",
"permissions": [
{
"role": "free-access",
"actions": [
"create",
"update",
"delete",
{
"action": "read",
"fields": {
"include": [ "Column1", "Column2" ],
"exclude": [ "Column3" ]
}
}
]
}
]
}
Note
To enforce access control for GraphQL queries when using Data API builder with Azure Cosmos DB, you are required to use the @authorize
directive in your supplied GraphQL schema file. However, for GraphQL mutations and filters in GraphQL queries, access control still is enforced by the permissions configuration as described here.
Item level security
Database policy expressions enable results to be restricted even further. Database policies translate expressions to query predicates executed against the database. Database policy expressions are supported for the following actions:
- create
- read
- update
- delete
Warning
The execute action, used with stored procedures, does not support database policies.
Note
Database policies are not currently supported by CosmosDB for NoSQL.
For more information about database policies, see the configuration file documentation.
Example
A database policy restricting the read
action on the consumer
role to only return records where the title is "Sample Title."
{
"role": "consumer",
"actions": [
{
"action": "read",
"policy": {
"database": "@item.title eq 'Sample Title'"
}
}
]
}