Need some help in the desing of the Auth/Permissions of a REST API for a SAAS app.

I'd done a prototype of a SAAS app and for permissions of the SAAS client, I'd setup the API to request for a header called CLIENT-ID. This way, the API filters all views by the Logged in Client. This header is Mandatory.

The next thing am testing is building the Super Admin Backend and am thinking the best way is to use the same APIs but then have the appropriate permission checks.

Now, the super-admin should be able to "work on multiple clients" e.g. when they do a GET request for /clients, they should be able to see a list of all clients as opposed to a Client Admin who would only see their client coz the CLIENT-ID header would filter to ensure the view returns the correct results. To allow the Super Admin to do this then I have to make the CLIENT-ID header non-mandatory for their role?

So my issue is, how do I provide a consistent API to provide for both types of roles?

Option 1:

For each API, I have to check the role of the user, if its a Super Admin role then I skip enforcing the CLIENT-ID header. That's doable. Issue though is, if the Super Admin then wants to get a single client, then I now have to request them to provide the CLIENT-ID header or I have to introduce it as a filter parameter. My problem here is now I have extra scenarios to check and am thinking I haven't even thought through all possible scenarios.

Option 2:

Create different REST views for the admin. This however then duplicates tons of code and its not pretty.

So am gravitating towards option 1 but it seems to get complex with each different scenario. Or is there no alternative and I just have to bake in this scenarios?

Am building the APIs using Django Rest Framework so any framework specific pointers would be welcome also.

1 Answer 1

  • Go with Option 2.
  • Get rid of the CLIENT-ID header. It is not secure.
  • Make /clients only visible to Super-Admins and list all clients.
  • Move the Client ID to the URL, so you have e.g. /clients/12345. Only the Super-Admin can access these too.
  • Make an alias such as /my-client that each Client Admin uses.
  • When a request to /my-client comes in, look at the user credentials to see which client they correspond to. I am assuming based on your question that a Client Admin has a 1-to-1 correspondence to a Client. If a Client Admin can administer more than one client, give them access to a filtered version of /clients.

Any common code should be shared between the three kinds of resource, /clients, /clients/ID and /my-client. Sharing code is a fundamental part of programming and you should never duplicate code.

  • I get your logic.. Thanks for this. I'd come up with a different way (Using Option One) which I will post below... In the meantime, can you explain what you mean by the CLIENT-ID header is not secure? My logic was to use it the same way some APIs request for e.g. the PUBLIC KEY via a header...
    – lukik
    Mar 6, 2018 at 5:24
  • 1
    Anything in headers is not secure, including those APIs you refer to. There's no security difference between headers and URL. But a URL is an identifier for a "thing", and you are proposing using a combination of a (simpler) URI + a custom header, to identify a thing. This makes things more complex for clients, and subverts the way HTTP is intended to work. I propose using the user's login cookie (also not secure, but cannot be guessed easily unlike an ID) to determine which client the user can access. Otherwise client admins can craft requests to see other clients' data! Mar 9, 2018 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.