# How Do You Model Permissions?

**URL:** <https://discuss.jsonapi.org/t/how-do-you-model-permissions/818>\
**Category:** Uncategorized\
**Created:** [October 26, 2016, 9:30pm UTC](https://discuss.jsonapi.org/t/how-do-you-model-permissions/818 "2016-10-26T21:30:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![EndangeredMassa](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/endangeredmassa/32/346_2.png) [@EndangeredMassa](https://discuss.jsonapi.org/u/EndangeredMassa)\
**Post date:** [October 26, 2016, 9:30pm UTC](https://discuss.jsonapi.org/t/how-do-you-model-permissions/818/1 "2016-10-26T21:30:38Z")

</div>

Has anyone found a good way to model permissions on a resource in JSON API?

I want to describe a `Campaign` resource that a `User` can or cannot take action on, such as `apply`ing to it.

Note that in our JSON API implementation, we’ve chosen to make all resources always include all of their attributes as a standard representation of that resource.

I can see a few different approaches: meta properties, related resource, other resource+user resource, and response header `Allow` values.

**Meta Properties**

This approach uses the `meta` member to describe the permissions the authenticated user has on the returned `Campaign` resource. The description for `meta` in the spec says that it can be used to include `non-standard meta-information.` These permission properties are not part of the standard representation of the resource, in my opinion. So, it makes sense that they could go in `meta`.

However, we then have to invent a permission structure that lives in `meta`. One approach may be the following:

```auto
GET /campaigns/1
{
  "id": 1,
  "type": "campaigns",
  "attributes": {
    // ...
  },
  "meta": {
    "permissions": {
      "apply": true
    }
  }
}

```

The client would then look in `meta.permissions` to determine if the current user could or could not take specific actions.

**Related Resource**

This approach creates a related resource to describe the permissions the authenticated user has on the returned `Campaign` resource. This other resource wouldn’t be something that could be directly CRUDed and would need some fake `id` property. Much like the `meta` approach, this provides a separate place to contain the non-standard information about a `Campaign`.

```auto
GET /campaigns/1
{
  "id": 1,
  "type": "campaigns",
  "attributes": {
    // ...
  },
  "relationships": {
    "campaign-user-permission": {
      "data": {
        "type": "campaign-user-permissions",
        "id": 2
      }
    }
  },
  "included": [
    {
      "type": "campaign-user-permissions",
      "id": 2,
      "attributes": {
        "canApply": true
      }
    }
  ]
}

```

This approach doesn’t seem to buy us much over the `meta` approach and has several problems.

**Resource+User Resource**

Maybe what we need is just a new resource that represents the combinations of a `Campaign` and the `User` requesting it. That could look like:

```auto
GET /user-campaigns/1
{
  "id": 1,
  "type": "user-campaigns",
  "attributes": {
    // ...
    canApply: true
  }
}

```

This approach puts the permissions in `attributes` of a different resource. It’s not the same resource as `Campaign` and therefore can have a different standard representation.

This feels a bit messy, though. Are we going to CRUD this resource? Possibly. If we want to say that a specific user can see a specific campaign, we may want to create a `UserCampaign` resource for that.

**Response Header `Allow`**

This approach uses the `Allow` response header (from the HTTP spec) to describe the permissions the authenticated user has on the returned `Campaign` resource. It can only list HTTP Method names, but the HTTP spec mentions that you can use non-standard method names in here.

```auto
GET /campaigns/1

Allow: APPLY
{
  "id": 1,
  "type": "campaigns",
  "attributes": {
    // ...
  }
}

```

This approach isn’t as flexible as others. It has to apply to the entire response. If there are ever degrees of parmission on an action, it would be hard to describe those with this method.

---

<div class="post-metadata">

**Author:** ![dgeb](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/dgeb/32/17_2.png) [@dgeb](https://discuss.jsonapi.org/u/dgeb)\
**Post date:** [October 28, 2016, 5:41pm UTC](https://discuss.jsonapi.org/t/how-do-you-model-permissions/818/2 "2016-10-28T17:41:46Z")

</div>

In general, I would consider a dual-approach for modeling permissions.

I would recommend modeling permissions that can be edited as resources in their own right. Their structure should align with how you store them in your server-side ORM / DB. Depending on the complexity of your permission model, a single permission resource might relate a user or group of users to a single campaign or group of campaigns.

With that said, clients should not necessarily need to “download the world” in order to understand how permissions apply to individual resources. Clients should easily be able to determine _what_ they can do with an individual resource without understanding the reason _why_. For that reason, I would also recommend using `meta` as a side-channel to relay these _applied permissions_.

So to sum up, I think there can be value in presenting normalized permissions as editable resources, and there can also be value in de-normalizing those permissions as read-only meta-data related to a resource.

---

<div class="post-metadata">

**Author:** ![EndangeredMassa](https://sea2.discourse-cdn.com/flex016/user_avatar/discuss.jsonapi.org/endangeredmassa/32/346_2.png) [@EndangeredMassa](https://discuss.jsonapi.org/u/EndangeredMassa)\
**Post date:** [November 2, 2016, 5:01pm UTC](https://discuss.jsonapi.org/t/how-do-you-model-permissions/818/3 "2016-11-02T17:01:13Z")

</div>

If the permission model ended up being complicated and editable, I like the idea of them being represented as resources and having (as you said) the applied permissions to a resource available in the `meta` section. If it’s a simple permission system that’s not really editable by clients, I think the `meta` approach makes sense on its own.

In the case where it starts simple and grows, given the above, we’d be using `meta` anyway. So, I think `meta` is the best approach.
