Field-Level Authorization
Objects in your application might have fields or other sub-resources to which you want to apply more granular authorization.
For example, in a social app, you might permit a particular type of user to change other users' usernames, but no other fields of their accounts. In this case, field-level authorization is the right approach. For more context, see When to use field-level authorization.
To implement field-level authorization, we suggest one of the following strategies:
-
Fields in permissions, where you specify a permission per action per field on the "parent" resource. This approach can be straightforward in terms of your policy, but might require more complex client-side processing.
For more details, see Model Resource Fields in Permissions.
-
Fields as resources, where you treat fields as their own resources in your policy. This approach likely requires additional policy rules, but can provide a more ergonomic experience with Oso clients.
For more details, see Model Resource Fields as Resources.
When to use field-level authorization
Field-level authorization is useful when a resource (the "field") can only be defined in relationship to another resource (its "parent"). Consider using field-level authorization if you can answer "yes" to either of these questions:
- Is the resource defined solely in relationship to some other resource?
- Does the resource identifier uniquely identify the resource?
Resource relationships
If a resource is defined solely in relation to another resource, field-level authorization might be an appropriate model.
For example, Account
resources might have fields like email addresses or
usernames. Those fields are defined solely in relationship to the account to
which they belong. For example, it wouldn't make sense to delete the username
independent of the Account
. To support granular authorization on those fields,
you likely want to use field-level authorization.
By contrast, when considering File
and Folder
resources, they can have a
belongs-to relationship with Folder
s. However, File
s and Folder
s have
meaning beyond the Folder
to which they belong––for instance, they might be
deleted independently of their containing Folder
s. To support granular
authorization on the contained resources, you likely want to model a
hierarchical
approach.
Resource identifiers
If the most natural identifier of a resource would not uniquely identify it, field-level authorization might be an appropriate model.
Considering an Account
resource, if you modeled its fields as resources,
Field{"username"}
would not uniquely identify any specific account's username
field. Instead, all accounts would have a Field{"username"}
.
While you could model Field
in such a way that its identifiers were
unique, it would be very cumbersome. Field-level authorization can provide a
more idiomatic model.
By contrast, File
and Folder
resources can be uniquely identified by their
paths in the file system.
Field-level authorization vs. attribute-based access control (ABAC)
In programming, the terms "fields" and "attributes" can both be used to refer to a component of an object/struct/class, so you might wonder what distinctions Oso draws between field-level authorization and ABAC. For the rest of this section, we'll used "field" and "attribute" to mean the same thing.
The distinction between these features can be summarized as:
-
In ABAC, permissions are granted based on attributes.
-
In field-level authorization, permissions are granted to attributes, which then must be modeled as resources in some way.
It is possible to successfully build policies that use one, both, or neither feature.
However, in the case where you use both ABAC and field-level authorization on
the same attribute, be mindful of the design. For example, during an
authorization check, you may not want to rely on the state of an attribute if
the actor you're authorizing lacks "read"
permissions.