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:

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 Folders. However, Files and Folders have meaning beyond the Folder to which they belong––for instance, they might be deleted independently of their containing Folders. 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.

Related