How to get the list of possible operations that can be performed on DriveItem resource? - rest

We are writing a OneDrive client application using a the REST APIs provided for OneDrive (personal) and need a way to identify the operations supported/allowed on the resource.
There's something called activities which lists all the operations that have already been performed on a resource.
And the Permission resource provides information about a sharing permission granted for a DriveItem resource.
The same is returning a blank array when called:(.
So, is there any way to identify what all operations that are allowed on a resource at hand, like Google Drive v3 File resource has a field called 'capabilities' which lists all the operations that are allowed on a resource making it easy for the clients to display only supported actions when that particular resource is selected in client application.

Actually the permissions resource gives shared information that had been granted on a particular resource, i.e. this information is available only if the resource is shared with other users.
So for all the files in 'Shared by me' section of One Drive Personal this information will be available and using the same user can manage sharing access to the resource.
But still the question remains that how to identify what all actions are allowed on particular resource or a role user have on a resource?

Related

Keycloak redirect fails when number of roles are in the hundreds

I have 2 users, one with less than 30 roles and one with 400 roles. When I login with the 30 role user, I can reach the redirect URL without issues. But when I log in with the 400 role user, the request to the redirect URL doesn't complete. If I reduce the number of roles in the 400 role user then it will work. So, is there a way to disable passing roles in the java access token or increase some limit somewhere that's causing the failure?
I would suggest to focus rather on roles reduction/optimization than forcing the transmission (raising limits) over the maximum number of roles inside tokens (or anywhere else).
Some interesting questions (among others) to start with:
Which protected resources am I going to serve?
What am I trying to protect? and what are the associated risks? (build a Threat Model)
How do resources are served by each application? and how are they distributed among my applications?
What kind of resources are they? How can I group them? Which sets are identifiable? or what are the relationships between them? What actions are possible against all sets of resources?
Who are the users of each application? How will they interact with my resources? Which flows are sensitive?
What roles can I define for all my resources?
Which role can apply to each application, resource type or set?
What kind of user groups can I create?
Do I need additional attributes or claims for each set of roles or users/groups?
I firmly believe that if you answer all these questions you will end up having a bunch of roles instead of hundreds. Think security by design and follow principle of least privilege.
Focus on your use case
Now as far as I understand, your blocking point is that you are assuming that each resource is unique, sensitive and requires its own permissions, and consequently a role definition. While it may be true in some cases, in most other cases it does not mean that you have to use the token roles/scopes/claims to secure your assets deep at the resource-level. I'll try to illustrate this sentence by an example.
RBAC and authorizations example for your use case
Let's assume that:
you have millions of sensitive resources to serve
each registered user of your application has access to a (different) set of these resources.
your resources are splitted into, say, 3 categories (e-books, videos, musics).
each resource can be downloaded, uploaded, deleted.
your application will meet unregistered users, registered users, contributors and administrators
registered users will always have read access to resources (not a single action will ever allow a modification)
contributors are particular registered users who can perform special actions including modification ('upload', 'edit')
contributors and administrators may have access to various administrative parts of the application
your application will evolve by serving additional categories of resources in the future and new actions will be available to users later (such as 'flag', 'edit' or 'share link').
Then first things first:
organize your resources accordingly by serving them behind categorized paths such as: .../myapp/res/ebooks, .../myapp/res/videos, .../myapp/res/musics
identify your resources via UUID such that a resource may look like: .../myapp/res/ebooks/duz7327abdhgsd95a
Now imagine that your business risks or at least the greatest risks you wish to avoid are:
unregistered users having gaining access or rights for any part of the application or resource
uncontrolled registration process (robots, spam, no mail verification, fake users, ...)
registered users gaining illegal privileges (unauthorized actions, access to other categories, illegal administrative rights)
discovery of available resources by any mean
You will note that I voluntarily didn't listed:
registered user having illegal access to certain resources. For example: maliciously pointed/provided by an existing user.
This is because it is not a high risk as you may hold contact information about registered users as well as log activity and actions, quota or requests throttling, and you may be able to ban them or start legal action against them. Your registration process is also assumed robust and secure. Nonetheless if its considered a critical risk you can address this with extra mechanisms (cf. suggestions at the end). But never will it result in adding extra roles, such as one per resource, as it does not fit in any security model.
That being said, finally, here are the roles and authorizations scheme you may come with:
SCOPE / AUDIENCE
MY_APP
ROLES
USER
CONTRIBUTOR
ADMINISTRATOR
CLAIMS / ATTRIBUTES
CATEGORIES
ACTIONS
--> POSSIBLE USER GROUPS
USERS
Roles: USER
Claims: CATEGORIES(variable), ACTIONS('download')
CONTRIBUTORS
Roles: USER, CONTRIBUTOR
Claims: CATERGORIES(variable), ACTIONS('download', 'upload', 'edit')
ADMINISTRATORS
Roles: USER, CONTRIBUTOR, ADMINISTRATOR
Claims: CATEGORIES(*), ACTIONS(*)
Following this model, assigning the correct group to each registered user will provide high-grade security by mitigating/controlling the main risks. As claims/attributes are defined in the token(s) (managed and signed by Keycloak) then you can trust this information in your application and serve your resources accordingly and safely. There is also no risk of illegal access or discovery of resources as you are using UUIDs, only registered users having had access once to a resource will know it and registration with appropriate category access will be needed for another user to access it (to only be able to read it basically). Of course you may store in a database the list of resources to which each user has access to, raising the overall security to a very high level.
However, if the latest is not enough you may also implement rolling UUIDs or temporary links for your resources when served to users. To go farther you may also define groups and masks for your categories, resources and actions.
In fine, in this example I made use exclusively of token claims to define roles (common claim), categories and actions (custom claims). In terms of security the authentication and identity will be the first-line security followed by roles then categories, actions and stored list of resources per user (db).
Other alternatives are obviously possible, its just an example. Still, I hope it helps!
To fix this problem you should start from defining client scope mappings for each of you applications (e.g. oidc clients). Main idea of this facility is that even if your user is super duper admin with all existing roles, all of his roles actually don't required for any particular application. For example client foo which defines following roles:
foo_user
foo_viewer
to perform its security logic need to know only whether currently logged user has foo_user or foo_viewer, but it doesn't care about has this user roles bar_user or bar_admin from application bar. So our goal is to make Keycloak return for any client access token with only valuable set of roles for this client. And roles scope mappings is you friend here. You can set for client foo scope like:
foo.foo_user
foo.foo_viewer
bar.bar_admin
and now even if logged user has role "bar.bar_admin" this will not go to access_token since client foo doesn't take this role into account. After applying some scope settings you can test them at 'Clients -> $CLIENT_OIDC_ID -> Client scopes tab -> Evaluate sub tab.
As for you case with 400 roles, i'm quite confident that none of your application requires all of 400 roles, so precise scope configuration for you apllications can drammatically reduce access token size.
But if i'm mistaken and you really have an application that rely on large amount of roles you should look into you runtime settings.
For example if you run keycloak behind reverse proxy like nginx large tokens may not fit in default HTTP parameters buffer size (afaik about 2-4kb) so you have to increase it via appropriate nginx configuration option. Another example is tomcat which has about 16kb as default HTTP header buffer, so if you send request with very large access token in Authorization header Tomcat may not handle this request properly.

RESTful API Design based on the RBAC model

The problem to face lies in the design of a RESTful API that can manage requests from multiple roles in an RBAC-based solution.
Currently we have different resources that can be accessed from different users, which can have one or more roles grouped according to their privileges.
The API we're trying to define must be as clear as possible to the client but without the overhead of adding additional metadata to the URL that could damage and even conflict with the REST practices and definitions. Therefore, we must avoid at all costs include information about the roles inside the URL. The plan is to use JWT tokens that carry in their payloads the info needed to know which permissions has the user making the request.
Having raised our current situation, let's provide an example and state the problem to solve:
Suppose we have * financiers * and * providers * as users with some roles who both want to access ** attentions ** (our resource). Should we add before the resource ** attentions ** information about the * user * whose trying to access the resource?
The endpoints in that case should be defined (as an example) as:
https://example.com/api/v1/financiers/:id/attentions
https://example.com/api/v1/providers/:id/attentions
This way we're attempting to inform the respective controllers that we want the ** attentions ** for that specific role / user which are, in some way, a sub-resource of them.
On the other hand, we could simply implement a much simpler endpoint as follows:
https://example.com/api/v1/attentions
The logic about which attentions return from the database should be now implemented in an unique method that must handle this two roles (and potentially new ones that could come up in the following features). All the information needed must be obtained from the payload from the token, exposing a much more generic API and freeing the web client from the responsibility of which endpoint call depending on the role.
I want to highlight that the attentions are managed in a Microservices Architecture and, hence, the logic to retrieve them is gathered in a single service. The cost of the API Gateway to route the two (and potentially more) of the endpoints from the first solution is a variable not to discard in our specific situation.
Having exposed our current situation:
Which we'll be the best approach to handle this issue?
Is there another alternative not contemplated that could ease the role management and provide a clean API to expose to the client?
In the second solution, is correct to return only the attentions accessible to that specific user based on the roles that it has? Isn't it counterintuitive to access an endpoint and only get some of the resources from that collection (and not all) based on its role?
I hope that someone could clarify the approach we're taking as there are little and none literature that I've found regarding this issue.
There there are multiple solutions for such kind of filtration, and developer have to select one depending on given situation.
As per my experience I can list following.
Structure
When data can't be accessed directly and developer has to use a relation (i.e a table JOIN). In that case URL have to include both the main and sub entities. Before going with this approach a good check is to ask, if the same URL can be used with POST ?
Example
If we have to fetch list of roles assigned to a specific user or want to assign additional roles then we can use
GET users/:uid/roles
POST users/:uid/roles
Security
With Multi-tenant systems where each user can have his/her private resources, i.e other users are prohibited from accessing those resources. Developer should save tenancy information and to filter the resources according to current authentication, without bothering client or requiring any additional info in URL
Example
Phone album of the user
GET photos
POST photos
Search
If it is not security or structure related but client still want to filter the result set depending on his scenario. then developer should use query-string for the filtration.
Example
Client have to fetch messages from his/her inbox or outbox or want messages which are not yet read. or he/she want to search his/her inbox
GET messages?folder=inbox
GET messages?folder=inbox&status=unread
GET messages?search=nasir

Where to save user quota data? In LDAP or RDBMS?

We are developing a system using OpenAM as STS and OpenDJ Directory Service as storage. We have extended the schema for some more data about users and groups, which by changing OpenAM settings, it can easily work with them. We have also used OpenAM Policy for Action (Uri+Verb) privilege for groups (and users).
I know I can export policy list into xml and import in another OpenAM, but actually I wanna know where OpenAM persists the policy under the hood? Within the underlying directory service?
We have a new issue to limit some users/groups for using some actions by quota. For example, a user may buy quota to use uri x + verb GET 200 times and we have to hold this data somewhere. I am in doubt if storing this data within Directory Service is a good pattern.

Access control based on data filtering instead of request authorization

Standard way to control access in a multi user service is to provide as many service methods as necessary, where each service method has concrete results and access permissions.
For example,
Moderator is authorized to call GetModerationAwaitingPosts service method to access posts from any visitor awaiting for moderation
Visitor is authorized to call GetOwnedPosts service method to access only his own posts including draft and moderation awaiting posts
Visitor is authorized to call GetModeratedPosts service method to access only moderated posts from all visitors
But there may be another approach - single service method GetPosts to request posts that the requester is allowed to see.
Any logged in user is authorized to call this method.
Posts are first filtered according to the role of the caller.
Then posts are filtered according to parameters passed in GetPosts method or filtered on client side.
This approach is used, for example, in WCF Data Services through Query Interceptors.
How is approach to filter data based on user inside service method named and treated in different architectures and methodologies, like SOA, REST, CQRS? Is it a solid solution?
Are there any books / articles where difference between these approaches is considered in details?
As for me, I find it really strange and unusual when results of a request depend on the requester.
Yes, there is an access control paradigm called attribute based access control (ABAC, abac) which implements data-based, context-based authorization that uses information about the user (role, department, age, location...) about the resource (owner, classification, type...) action (view, edit, delete), and context (time, IP address...)
ABAC will let you implement policies e.g.:
Medical use cases
doctors can view the medical records of patients they are assigned to
nurses can edit the medical journal of a patient in the same deparment
Finance use cases
A teller can view the accounts of those customers in their branch
A teller can approve a transfer up to their approval limit
ABAC provides an architecture as depicted below.
In the architecture you have the notion of a PEP or policy enforcement point which you can use to secure anything from GUIs, APIs, web services, micro-services, ESBs, and databases.
The PEP calls out to the PDP or policy decision point which is at the core of the architecture. The PDP uses a set of policies to determine whether access should be granted or denied. It can also use external sources of attributes, PIP or policy information points, to help in determining whether access should indeed be granted.
There is one language which implements ABAC today. This language is called XACML (xacml). XACML gives you:
the architecture
a policy language
a request / response scheme
With XACML you can create JSON authorization requests, send them off to the PDP and get a JSON response back. It's an extremely lightweight way of getting a response back.
This means you can either
grant or deny access to a given record, or
filter those records a user can get access to as stated in your requirement

REST API DESIGN - How to overcome the impedance mismatch between a front end client's needs and REST principles?

Given the following scenario:
a RESTful API
that RESTful API has permissions/authorizations that can be granted to entire entity collections, and/or to particular entities, i.e. complex role based permission rules.
The API is (according to RESTful principles) HATEOS-driven (resource url's are revealed through the API. Once you login and get back the "user" resource, you are able to drive the entire API through links given in responses.
A front-end client (web app) that needs to use this API
Imagine now the front-end wants to build a menu. That menu is based on access to particular entities and/or entity collections. For example an "Administration" menu will be shown if the user has access to one of a number of different entities and/or collections.
How do I build the menu? I need to know the permissions the user has in order to build the menu propertly. I don't know all the permissions the user has because it would require walking the url's of the REST API to see all the objects the user has permissions on.
This seems like a tough thing to overcome, but maybe I am missing some obvious technique. How can this impedance mismatch overcome?
Your REST API can expose a resource (or it can be a part of the user resource returned after a user has been successfully signed in) which will contain information what resources the user can access and therefore what menu items should be available for this user.