Or… How to Commandeer a Starship

Fine-Grained Permissions with Stormpath Custom Data

Many customers have asked us how to do fine-grained permissions for users managed in Stormpath. Good news! With customData, you now have tons of flexibility in modeling user permissions.

Stormpath was intentionally designed with a fairly generic model for role-based access control. Because our customers use the API for everything from simple website login to multi-tenant SaaS applications, deep application-specific permissioning requires some custom data modeling. That’s where the customData resource comes into play.

A Stormpath customData resource allows you to store up to 10MB of JSON-formatted information about a user or a group. (docs here) For instance, customData can store profile info for Jean-Luc Picard:

curl -X POST --user $YOUR_API_KEY_ID:$YOUR_API_KEY_SECRET \
   -H "Accept: application/json" \
   -H "Content-Type: application/json" \
   -d '{
      "username" : "jlpicard",
      "email" : "capt@enterprise.com",
      "givenName" : "Jean-Luc",
      "surname" : "Picard",
      "customData": {
         "rank": "Captain",
         "birthDate": "2305-07-13",
         "birthPlace": "La Barre, France",
         "favoriteDrink": "Earl Grey tea",
      }
   }
\

Permissions using the customData object

Another way to use the customData object is to assign special permissions either at the user or group level. You could give Jean-Luc fine-grained permissions by declaring a set of permissions attributes in your application and then assigning them to the fine captain.

For instance:

"customData": {
   “permissions”: 
       “crew_quarters”: “ 9-3601”,
       "lock_override”: “all”,
       "command_bridge”: {
          “type”: “vessel:bridge”,
          “identifier”: “NCC-1701-D”,
          “action”: “lockout”,
          "control_key”: "173467321476C32789777643T732V73117888732476789764376",
       }
    }

In this example: Picard has two permission types that would apply to all crewmembers of the Enterprise: crew_quarters and lock_override. These could define what he can do in a certain area of the shop, and what parts of the Enterprise he has access to. Similarly, Stormpath customData can help define what users can do in a part of your application, or restrict access to certain areas.

User-Unique Permissions

Picard also has a permission block that is unique to him: command_bridge. This highlights an important feature about the customData object:

The customData object is schema-less, and its name-value pairs do not need to have the same structure for all accounts or groups.

command_bridge allows Picard to lockout command functions of his own ship, NCC-1701-D, and restrict command to the Bridge area of the ship. Only a Captain would have this permission, presumably to command the ship as it goes down or to lock out control from a hostile boarding party, so no other users in the directory would need this name-value pair.

Permissions with Shared Secrets

The command_bridge permission includes a nested value, control_key,that holds a shared secret that authenticates the command_bridge permission. In order to commandeer the Enterprise, he needs to enter that value in his own voice from the Bridge.

We can also see how a coding error lost Picard control of the Enterprise – he failed to encrypt his secret token, control_key. Before passing a shared secret to Stormpath, make sure to encrypt it using a strong encryption cipher, such as AES-256-CBC with a secure random Initialization Vector.

Otherwise, you might as well just tell the Android your shared secret.

Permissions Vs. Roles

When modeling a complex user infrastructure, such as a ship or a multi-tenant SaaS, one of the biggest challenges is modeling out permissions, groups and roles. So first, lets define what these things are:

  • A group is a collection of users. Users may be members of many groups.
  • A role is a way to organize rights.
  • Permissions are a type of right. Permissions could be grouped into a role and assigned to a group. Or you can assign permissions to users on an ad-hoc basis.

A permission, such as command_bridge, is a statement of raw functionality: actions, and behaviors in an application and nothing more. Permissions explicitly define only “what” the application can do, but not “who” can do those things. They have three important components.

  1. What type of resource is being interacted with (“type”: “vessel:bridge”)
  2. Which specific resource is being interacted with (“identifier”: “NCC-1701-D”)
  3. What action or behavior is being performed (“action”: “lockout”)

If a group of permissions doesn’t address these things specifically, it would likely be better expressed as a role.

Setting Permissions at the Group Level

You could also set permissions for crewmembers at the group level, based on organizational groupings like rank and function. Remember, users can be associated with multiple groups in Stormpath. This would mean that any user assigned a group would inherit that group’s permissions.

First, create a series of groups associated with different sets of permissions. Then give each group a customData resource that defined those permissions. Picard, as a member of the “Command Division” and “Senior Officers” groups, would have different permissions than Guinan, who would be a member of totally different groups, such as “Operations Division” and “TenForward staff” groups. Setting coarse-grained permissions at this level reduces complexity and development time.

About Stormpath

Stormpath is a User Management API that reduces development time with instant-on, scalable user infrastructure. Stormpath’s intuitive API and expert support make it easy for developers to authenticate, manage, and secure users and roles in any application.

And, because I love all things TNG, the most epic password breach… ever. 

Get Started with Stormpath

User Management API for Developers