What are some of the well known products/services around Authorization (RBAC and ABAC) that implement standards like XACML? - authorization

What are some of the well known products/services around Authorization (RBAC and ABAC) that implement standards like XACML?
Our customers are organizations.
Each organization would be given 3 default roles (after onboarding)
but also have the capability to create more roles
Roles define level of access on the under lying resources (not just the API level (which is via scopes) but at the resource level)
Another use case is that of superuser who can act across organizations and perform any action.
Please share your thoughts on if these use cases can be solved (and the ease) in the product or service you recommend. thanks.

You can find a list of XACML implementations on the dedicated Wikipedia page. To address your use case which is very RBAC-oriented, I would use the RBAC Profile of XACML, so make sure the implementation you choose supports that.

cdan is right. Start with the Wikipedia page for XACML (and the ones for ABAC and ALFA) which list implementations but also use cases. You have quite a broad range of commercial and open-source alternatives.
In ABAC, you tend to try to write authorization policies independently of the underlying technology. This means that whether access is via APIs or via a webpage should not matter in defining the authorization.
The key questions you want to ask yourself are:
Are there relationships in authorizations? E.g.
a user with role='manager' can do action = 'view' on object = 'record' if object.organization == user.organization.
Do I care about auditing the authorization? Do I need to prove my compliance?
Do I need context and runtime attributes e.g. time and location?
Do I need to apply the same authorization logic across multiple apps, APIs, and data?
Do I need to regularly update my authorizations?
If you answered Yes to one or more of the above questions, you likely need ABAC.

Related

How to deal with a breaking change in an invariant (business rule) when you expose a Public API

I am starting to investigate the good practices about Public API, specifically about how to deal with breaking changes. There is a lot of technicalities related to the versioning (or non-versioning!), but I am more interested about the code base implication.
Imagine a basic scenario where you have a business rule "password must have at least 10 caracters". And you have a "Create User" scenario exposed in a public API, accepting a password.
You have hundreds of clients using it, and one day, you decide to change the business rule to "password must have at least 15 caracters". Even if you did not change the semantic of the API signature and payloads, you just introduced a breaking change in your API because you changed the behavior of this API.
How would you deal with this?
I only find wrong approaches:
Modify your domain invariants (business rules) with dated/versionned invariants: this would create a nightmare in the code readibility / testing / etc.
Duplicate your code base per API version: this would create a maintenance nightmare
Hope one day you will be able to deprecate all this and become clean again: in your dream...
Any real life experience on this in your job?
The easiest way is just to communicate with your clients and warn them of the upcoming change weeks/months before. This way they can prepare and be ready for the breaking change.
If you absolutely must support old clients, another option is to keep the domain invariant to 10, but add an additionnal api call for the create user scenario which checks the password length and verifies it is of length 15 outside the domain. Then, encourage your users to migrate to the new CreateUser endpoint. This works for simple cases like this one but will become very hard to do for complicated invariants or if your domain is used in different contexts (multiple Apis, desktop app etc).
If you decide to go with this route, a good tip is to make sure you have metrics to know how many clients use the old endpoint vs how many use the new endpoint. When you have reached a certain threshold you can shutdown the old endpoint and move the minimum password length of 15 invariant from the Api to the domain,

RESTful API with multitenancy and shared resources

I am trying to figure out the "right" implementation for an url structure for an application with multitenancy support and shared resources.
Resources: Users, Projects
The URL schema is
host/api/tenant_id/resource[/id][/subresource][/id]
User A (width id = 1) gets a collection of his projects at
GET http://example.com/api/1/projects/
User A creates a new project, readable by
GET http://example.com/api/1/projects/2
Now User A gives another User B (id = 2) access to project 2.
User B would like to see a collection of all projects related to his account via:
GET http://example.com/api/2/projects/
Should the shared project (id = 2) be in this collection besides those, User B created by himself? Or is there a better naming structure for shared resources?
Focusing on the design of URL structures is actually a no-go for RESTful architectures. Roy Fielding:
A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server).
See also this answer.
For your specific problem I would return a list of (basically arbitrary) hypertext links to the projects the user has access to. The links would contain attributes making it clear, whether the project is »owned« or »accessible« by the user. To improve readability you could design your resource URLs as
http://example.com/user/{user id}
http://example.com/project/{project id}
The representation of user after a GET http://example.com/user/2 would contain the list of links like
<a href="http://example.com/project/1" class="owned"/>
<a href="http://example.com/project/2" class="access-permitted"/>
The HATEOAS principle is inherent to REST and makes most »how do I design my URIs« questions obsolete:
The principle is that a client interacts with a network application entirely through hypermedia provided dynamically by application servers. A REST client needs no prior knowledge about how to interact with any particular application or server beyond a generic understanding of hypermedia.
Maybe one advantage can be in using tenant info in the path. In such way we can easily have for example the lists of objects.
Querying the uri on get /tenant-id/projects
We can have a list of of projects for each entry tenant.
How can be get without tenant info into url?
My 2 cents

Implementing Access Control in a system

I came across many different models for the Access Control in a system. When implementing an Access Control model in any system, we usually hard code the rules/rights in the database(considering an RDBMS) by creating separate tables for the Access Control. Also, these rules/rights can be stored in an XML database.
I would like to know what is the difference between storing the rules on RDBMS and on an XML database? Also, when should we use XACML for implementing an Access Control model in a system? I mean, how one can decide whether one should hardcode the rules/rights in the database or one should use XACML policy language?
Thanks.
Disclaimer: I work for Axiomatics, a vendor implementation of XACML
Storing authorization logic if you go your own way could be done either in the RDBMS or in an XML database. It doesn't matter. I doubt that XML brings you any added capabilities.
Now, if you want an authorization system that can cater for RDBMS systems and other types of applications too (CRM, .NET, Java...) then you want to use a solution that is agnostic of the type of application it protects. That's the goal of XACML, the eXtensible Access Control Markup Language.
XACML provides attribute-based, policy-based access control (ABAC and PBAC). This gives you the ability to write extremely expressive authorization policies and managed them centrally in a single repository. A central authorization engine (called Policy Decision Point or PDP) will then serve decisions to your different applications.
As Bell points out, the minimum set of attributes you will need is typically attributes about the user (Subject), the resource, and the action. XACML also lets you add environment attributes. This means you can write the following type of policy:
Doctors can view the medical records of patients they are assigned to.
Doctors describes the user / subject
view describes the action
medical records describes the targeted resource
of patients describes the targeted resource too. It's metadata about the resource
they are assigned to is an interesting case. It's an attribute that defines the relationship between the doctor and the patient. In ABAC, this gets implemented as doctor.id==patient.assignedDoctorId. This is one of the key benefits of using XACML.
Benefits of XACML include:
- the ability to externalize the authorization logic as mentioned by Bell
- the ability to update authorization logic without going through a development/deployment lifecycle
- the ability to have fine-grained authorization implemented the same way for many different applications
- the ability to have visibility and audits on the authorization logic
HTH
The two are not mutually exclusive.
An XACML policy describes how to translate a set of attributes about an attempted action into a permitted/denied decision. At minimum the attributes would be who the user is (Subject), what they are trying to do (Action) and what they are trying to do it to (Object). Information such as time, the source of the request and many others can be added.
The attributes of the user and the object will still have to be stored in the database. If you are grouping users or objects to simplify administration or to simplify defining access control rules then you're going to have to manage all of that in the database to. All that data will then need to be passed to the XACML Policy Decision Point to return the permit/deny decision.
The advantage of using XACML to define these rules, rather than writing your own decision logic for the rules defined in the database, is that the assessment of the rules can be handed off to an external application. Using a mature, tested XACML implementation (there are open source options) will avoid you making any mistakes in building the checks into your own code.
Hardcoding the policies in your code is a very bad practice I think. In that case you mix the business logic of your resources and the permission check of the access control system. XACML is a big step in the right direction because you can create a fully automatic access control system if you store your rules in a separated place (not hardcoded in the business logic).
Btw you can store that rules in the database too. For example (fictive programming language):
hardcoded RBAC:
#xml
role 1 editor
#/articles
ArticleController
#GET /
readAll () {
if (session.notLoggedIn())
throw 403;
if (session.hasRole("editor"))
return articleModel.readAll();
else
return articleModel.readAllByUserId(session.getUserId());
}
not hardcoded ABAC:
#db
role 1 editor
policy 1 read every article
constraints
endpoint GET /articles
permissions
resource
projections full, owner
role 2 regular user
policy 2 read own articles
constraints
endpoint GET /articles
logged in
permissions
resource
projections owner
#/articles
ArticleController
#GET /
readAll () {
if (session.hasProjection(full))
return articleModel.readAll();
else if (session.hasProjection(owner))
return articleModel.readAllByUserId(session.getUserId());
}
As you see the non hardcoded code is much more clear than the hardcoded because of the code separation.
The XACML is a standard (which knows 10 times more than the example above) so you don't have to learn a new access control system by every project, and you don't have to implement XACML in every language, because others have already done it if you are lucky...

Api URI Design Preference

A quick api uri design question. We have resources that belong to our clients. These resources can be edited / viewed / deleted by the client who entered them into our system. The resources can be searched by all clients but access is only granted if certain criteria is met (client has level 3 access etc).
Choice 1: include the client who owns the resource in the uri.
client/:clientname/widgets
client/:clientname/widgets/:id
Choice 2: ditch the whole "client/:clientname" since this part of the uri has to be verified and checked against the credentials of the user accessing the information.
/widgets
/widgets:id
We have other resources other than widgets that also belong to clients.
Which way is the more preferred way and why? Cheers.
The only advantage that Choice 1 gives it that it allows you to effectively namespace widgets/whatever by the user that uploaded them. Similar to Github, how different users can have projects with the same name. If Github were to exclude the username, no two users could have a project with the same name. If the widgets are all unique, I would go with option two and you will have a 1:1 mapping from a widget the the user that created it, thus supplying it is just extra work for whoever is calling it.
If you can have the same widget name for different users, use an approach which includes the username. You may not need to actually use the 'client' word in your url though; using a path like '/:clientname/widget/:widgetid' instead.
Note that this is kind of an opinion based question, so you may get different answers. You'll have to weigh the information provided and in the end make your own decision.

Suggestions on addressing REST resources for API

I'm a new REST convert and I'm trying to design my first RESTful (hopefully) api and here is my question about addressing resources
Some notes first:
The data described here are 3d render
jobs
A user (graphics company) has multiple projects.
A project has multiple render jobs.
A render job has multiple frames.
There is a hierarchy enforced in the data (1 render job
belongs to one project, to one user)
How's this for naming my resourses...?
https:/api.myrenderjobsite.com/
/users/graphicscompany/projects
/users/graphicscompany/projects/112233
/users/graphicscompany/projects/112233/renders/
/users/graphicscompany/projects/112233/renders/889900
/users/graphicscompany/projects/112233/renders/889900/frames/0004
OR a shortened address for renders?
/users/graphicscompany/renders/889900
/users/graphicscompany/renders/889900/frames/0004
OR should I shorten (even more) the address if possible, omitting the user when not needed...?
/projects/112233/
/renders/889900/
/renders/889900/frames/0004
THANK YOU!
Instead of thinking about your api in terms of URLs, try thinking of it more like pages and links
between those pages.
Consider the following:
Will it be reasonable to create a resource for users? Do you have 10, 20 or 50 users? Or do you have 10,000 users? If it is the latter then obviously creating a single resource that represents all users is probably not going too work to well when you do a GET on it.
Is the list of Users a reasonable root url? i.e. The entry point into your service. Should the list of projects that belong to a GraphicsCompany be a separate resource, or should it just be embedded into the Graphics Company resource? You can ask the same question of each of the 1-to-many relationships that exist. Even if you do decide to merge the list of projects into the GraphicsCompany resource, you may still want a distinct resource to exist simple for the purpose of being able to POST to it in order to create a new project for that company.
Using this approach you should be able get a good idea of most of the resources in your API and how they are connected without having to worry about what your URLs look like. In fact if you do the design right, then any client application you right will not need to know anything about the URLs that you create. The only part of the system that cares what the URL looks like is your server, so that it can dispatch the request to the right controller.
The other significant question you need to ask yourself is what media type are you going to use for these resources. How many different clients will need to access these resources? Are you writing the clients, or is someone else? Should you attempt to reuse an existing standard like XHTML and classes/microformats? Could you squeeze most of the information into Atom? Maybe Atom with some extra namespaces like GDATA does it? Or is this only going to be used internally so you can just create your own media types, like application/vnd.YourCompany.Project+xml, application/vnd.YourCompany.Render+xml, etc.
There are many things to think about when designing a REST api, don't get hung up on what your URLs look like and you should really try to avoid doing "design by URL".
Presuming that you authenticate to the service, I would use the 1st option, but remove the user, particularly if the user is the currently logged in user.
If user actually represents something else (like client), I would include it, but not if it simply designates the currently logged in user. Agree with StaxMan, though, don't worry too much about squeezing the paths, as readability is key in RESTful APIs.
Personally I would not try to squeeze path too much, that is, some amount of redundant information is helpful both to quickly see what resource is, and for future expansion.
Generally users won't be typing paths anyway, so verbosity is not all that bad.