How to reference external set of permissions in an XACML policy? - xacml

Originally, I asked "How do you write a policy that requires a subject be granted access to a requested permission, where the set of allowed permissions is in an external attribute store. Can you reference an external set of permissions in a policy?" The second question has been answered in the affirmative, so I'm revising the question a bit to focus on the "how".
Can someone provide a xacml policy snippet (or even pseudo-xacml) that requires a role attribute id (will be provided by the request) to be within a set of roles which are identified by another attribute id (managed by external attribute store).
For the sake of providing a starting point, the following is an example from http://docs.oasis-open.org/xacml/2.0/XACML-2.0-OS-ALL.zip. In this case, the role is inline.
<Subject>
<SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">administrator</AttributeValue>
<SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:example:attribute:role"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</SubjectMatch>
</Subject>

Yes, policies can be written to reference attributes that come from an external attribute store.
However, where the attributes actually come from is usually not specified in the policy itself, other than perhaps by a naming pattern in the attribute ID. In the XACML PDP reference architecture, it's the responsibility of the request context handler to resolve attribute IDs and produce values for the PDP.
It goes something like this: While evaluating a request against a set of policies, the PDP encounters an attributeID in a policy rule that it needs to form a decision about the request. The PDP asks the request context handler to get the value of that attributeID "from whereever" - the PDP doesn't care where it comes from. The request context handler may look for the attribute in the attributes provided with the request, or in any number of external attribute providers, such as LDAP or AD or SAML or plain old databases. The request handler might recognize naming patterns (like, namespace prefixes) in the attributeID to know where to obtain it.
You want your attributeIDs to be specific enough to know what they are and what they mean, but not so specific that all of your policies break when you move your attribute provider to a different machine. Policies should be configuration independent.
Ultimately, where the request handler looks for attributes is a matter of configuration of the request handler / PDP server, and will vary by product vendor.
Update: To answer the 2nd revision to this question
You would write your policy to perform a comparison between the attribute value(s) provided in the request and a list of values provided by an external source.
Keep in mind that an attribute designator returns a list of values, since the request could contain multiple attribute values for the same attributeID. You can accommodate that by either by wrapping the attribute designator in a "one-and-only" reduction function, or by using a many-to-many cross product match function that will test every member of list1 for a match in list2.
Unless you have a specific design requirement that the request is only allowed to contain one role attribute, it's best to avoid the "one-and-only" reduction since it really limits your options.
Your Xacml 2.0 policy could look something like this: (forgive syntax errors, my Xacml 2.0 is a little rusty)
<Policy [...] RuleCombiningAlgorithm="deny-unless-permit">
<Rule [...]>
<Effect>Permit</Effect>
<Condition>
<Apply FunctionId=”urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of”>
<SubjectAttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:2.0:example:attribute:role"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
<SubjectAttributeDesignator
AttributeId="list-of-acceptable-roles-from-external-provider-attribute-id"
DataType="http://www.w3.org/2001/XMLSchema#string"/>
</Apply>
</Condition>
</Rule>
</Policy>
The Xacml function "at-least-one-member-of" takes two lists as parameters. For every item in the first list, it tests to see if that item exists in the second list. It returns true as soon as it finds at least one match.
The attribute "...example:attribute:role" from your example is the attribute you're expecting to be provided in the request. If you want to enforce that the attribute must be provided in the request, you can set MustBePresent="true" in the attribute designator.
The "list-of-acceptable-roles..." attribute is an attribute id that your PDP context handler recognizes and retrieves from some external provider. What prefix or pattern the context handler looks for and which provider it fetches from is a matter of PDP configuration.
Ideally, the naming pattern on the attribute id indicates a conceptual domain or namespace the id is associated with, but the id does not explicitly indicate the physical location or provider of the attribute value(s). For longer app lifetime with lower maintenance costs, you want to be able to change your provider implementation details without having to rewrite all of your policies.
You can have vendor-specific attribute ids that will probably only come from a single provider, you can have application-specific attribute ids that could be supplied by multiple providers but only make sense for a particular application, and you can have generic or standardized attribute ids that could come from multiple providers and be used in multiple applications. The Oasis standards body and domain-specific profiles are a good starting point for finding standardized attribute ids and their semantics or getting ideas on how to organize your own app specific ids.
Depending on your PDP and context handler implementation, it may also possible to use the "Issuer" field as a way to constrain the list of providers for an attribute. The Xacml spec doesn't say much about use of the Issuer field, but the same goals of decoupling policy from provider implementation details still holds.

Related

Dynamic root policyset for multi-tenancy using Authzforce Core

I basically want to use Authzforce in a multi-tenant system.
Right now, I have a single root policy that has a few PolicySetIdReference elements that point to other policy sets (per organization) but I noticed that it tries to resolve every reference element and queries the database (I set up my own version of the MongoDbBasedRefProvider). I am worried that I would needlessly load every other policy for other organizations.
<PolicySet PolicySetId="ROOT" ....>
<PolicySetIdReference>ID-for-org-1</PolicySetIdReference>
<PolicySetIdReference>ID-for-org-2</PolicySetIdReference>
</PolicySet>
Am I able to make the root policy provider check some condition(based on org) so that the policies that I check are significantly smaller? In the example above, i only want to retrieve the one for ID-for-org-1
For full multi-tenancy, I recommend to have one PDP instance per tenant, i.e. dispatch the request to a specific PdpEngine instance based on the tenant (org) ID, e.g. via a String-to-PdpEngine map or whatever, just a suggestion.
If you still want to use the same PDP engine for all tenants (i.e. handling policies for all), make sure you do all these:
Use the first-applicable policy combining algorithm in the ROOT policy (so that the evaluation stops at the first applicable policyset within).
Make sure there is a tenant/org ID attribute present in XACML requests.
Define a XACML Target in each org policyset with a Match (equal) on this tenant/org ID attribute, to make sure the policyset applies (is evaluated) only if the tenant/org-id matches.
Implement and enable a Decision Cache on the PDP.

Which identity properties are required to be SCIM compliant?

Maybe I didn't really get the concept but basicly if you say you're compatible with SCIM then there must be certain expectations of properties that belong to identities am I right?
For an example if you take a look at the example createUser request from
https://developers.onelogin.com/scim/implement-scim-api
you will see a variety of different properties like displayName, nickName etc..
My use case however requires only one name, the userName.
My question is, are any of these even required to say that you are SCIM compliant?
The RFC7643 indicates that the id parameter must be included.
The requirement for the other properties depends on the resource type and thus schemas used by your application. For a user resource, the section 4.1 of the RFC indicates that the userName is also required.

Ignore or not API endpoint parameters based on access level

I am working on an API endpoint that returns a list of products:
"api/products"
The endpoint accepts the following parameters:
page_size
page_number
Each product has a boolean property named IsApproved.
In the web application used by common users I always want to return only the Approved products ... On the web ADMIN application used by administrators I want to return all products, Approved or Not ...
My idea would be to add a new parameter (enumeration) named:
ApprovedStatus
And the values would be Approved, NotApproved and All.
On each API call I would check the user permissions ... If is admin I will consider the value on this parameter. If not then I will always return only approved products.
Another solution would be to have different endpoints ...
Any advice on which approach to take or is there other options?
The approval status is part of the product, therefore, in a perfect REST world, you don't want a different endpoint at all since you're accessing the same resource.
Then, for filtering a resource based on a property value, I think the convention is that if you specify that property as a query parameter it will only return those matching the value, and if not, it will return all of them, so I don't see the need to define a special ApprovedStatus parameter with some special values. Just query by isApproved!
Finally, about how to handle authorization. This, I think, should be handled at a completely separate layer**. If authorization is involved, you should have an explicit authorization layer that decides, for a specific resource and user, wether access is granted or not. This means the query would be triggered and if one of the resources generated by the query fails to be authorized for the user that triggered the query, it's taken out of the results. This accomplishes the behaviour you want without having any code that is checking specific users against specific query parameters, which is good because if tomorrow you have another endpoint that exposes this objects you won't have to implement the same authorization policy twice. Pundit is a perfect example on how to do this with Ruby elegantly.
**Of course, this approach retrieves data from the database unnecessarily which could matter to you, and also opens your endpoint up to timing attacks. Even then, I would consider tackling these problems premature optimizations and should be ignored unless you have a very good reason.
You're right about your ideas:
You can create a new endpoint just for admins, that will return all products
You can use a kind of authorization (e.g. Authorization Header) in order to check if the API is being called through admin or normal user. Then you can route internally to get all products or just IsApproved products.
You can add a proxy in front of your API to route to the right action, but it can also be achieved directly in the API but I think the second solution is easier.
Adding one more property is a bad idea.
In my opinion, adding another end point is very good. Because it will increase the protection in the admin end point.
Otherwise, since it is a web application, Simply set a cookie and a session to identify and separate the admin and user.
Going with the principle of least astonishment, I'd be in favour of adding a second endpoint for admin users. Such that you'll have:
GET /api/products (for regular users)
GET /api/admin/products (for admins)
This allows your code and API documentation to be nicely separated, and all of the admin-specific authentication details can live under the "admin" namespace.
The intention behind each API call is also clearer this way, which helps developers; and means that you can differentiate between admin vs regular usage in any usage stats that you track.
With ApprovedStatus, I think the specifics here don't matter much, but - considering what a developer using the API might reasonably expect / assume - it would be good to:
Ensure the ApprovalStatus parameter name matches the property name for "approval" that you return with each product object
Defaults to "approved" if it is not specified
Alert the user when an invalid value is specified, or one that they don't have access to
Bottom line: to answer your headline question - I think it's bad practice to ignore user input... sometimes. Design your API such that distinctions around when input can be passed in is very clear; and always alert the user if you receive input values that are technically acceptable, but not in the way that the user has requested, or for their access level. Ignoring values that are plain wrong (e.g. an argument that doesn't exist) is another story, and can be useful for future proofing or backwards compatibility.

RESTful API authorization on entities/resources?

I am working on an API in a system that has very complex access control rules. Often times there are complex SQL queries required to determine if a user has read or write access to a particular resource. This causes a lot of complexity and redundancy in our client applications as they have to know all these rules in order to determine whether to present the user with CRUD options for each object.
My goal is to reduce much of the complexity on the client side and house all the complex logic in the API. This way new client applications written against our API can avoid re-implementing the complex access rule logic on their side when ensuring that the UI only presents valid options to the user.
I am not sure what the best way is to handle this. I'm considering two different options but I don't know if there is a better or more standard way to expose generic access information to callers of an API.
Option 1
When a caller makes a GET request on a resource entity or collection of them, every returned entity will return an _allowed_actions field attached, which is an array of actions the caller is allowed to perform on that entity. For example, requesting a Listing object may result in the following response.
GET /listing/5
{
"id": 5,
"address": "123 Foo Street",
"city": "New York",
"state": "New York",
"price": 457000,
"status": "pending",
"_allowed_actions": ["READ", "UPDATE", "DELETE"]
}
Still unsure how to relate to clients whether they have the authority to create instances of a resource entity using this method, but perhaps the client will simply need to maintain enough understanding of the permission structure to determine this on its own. The access rules around creating instances are typically less complex than the READ/UPDATE/DELETE access rules so that doesn't seem too bad.
Option 2
Create a meta-API, which clients can make requests to in order to determine what actions they can perform on each resource. For example, checking what the client can do with a listing:
GET /access-query/listing/5
{
"allowed_actions": ["READ", "UPDATE","DELETE"]
}
And checking what options are allowed for listings in general, including CREATE:
GET /access-query/listing
{
"allowed_actions": ["READ", "CREATE", "UPDATE", "DELETE"]
}
The benefit of this approach is that it allows callers to have a full understanding of what they can do on every resource in a generic way. This way clients wouldn't have to understand that the "create_listing" permission AND a non-probationary user status are required required in order to create listings. They can simply query for this information ahead of time.
The downside to this approach is that it increases the amount of requests. Rather than require clients to have an understanding of the permissions logic, they now have to query once to determine what they can do and a second time to do it.
I don't particularly care for either of these methods but they're all I can come up with at the moment. Is there a better way to go about this?
What you are looking for is fine-grained, externalized authorization:
fine-grained: you want to create authorization policies that take into account multiple parameters or attributes and possibly relationships between the client (the requestor) and the targeted entity e.g. a listing in your case.
externalized: you want to decouple the business logic from the authorization logic. In your question you complain about how complex the code and the SQL statements are becoming. This is a direct consequence of not clearly separating business logic from authorization logic.
There is a model called attribute-based access control (ABAC) that defines an approach to fine-grained externalized authorization. NIST, the National Institute of Standards and Technology, has produced a report on ABAC which you can read online.
OASIS, the organization for the advancement of structured information standards, has defined a standard called XACML (eXtensible Access Control Markup Language) to implement ABAC.
XACML brings you:
an architecture as illustrated below
The policy enforcement point (PEP) intercepts your API calls. It protects your API, inspects the messages and sends an authorization request to the policy decision point (PDP).
The policy decision point (PDP) evaluates incoming authorization requests from the PEP against a set of authorization policies written in XACML. The PDP eventually reaches a Permit or Deny decision. To reach decisions it may need to look up additional attribute values from databases, web services, LDAP, or files. These are called policy information points in the architecture.
a policy language: the XACML policy language is attribute-based which means it uses attributes to define what can be allowed and what is not. For instance, you could define rules such as:
a real estate agent can see all the listings if and only if the listing location == the agent location
a real estate agent can edit a listing if and only if he/she owns the listing
a real estate agent can close a listing if and only if the listing's item is sold and if and only if the agent is the person that sold the item.
a request/response scheme: XACML also defines a way to query the PDP and to get responses back. A PDP can be queried either via single questions or via multiple questions in a single request e.g.:
Can Alice view listing 123? Yes, permit.
Can Alice view, edit, or delete listing 123? Permit; Deny; Deny.
With a XACML-based approach, you get to maintain your business logic and your API separate from the authorization logic. This has several benefits:
you can always reimplement the API and keep the same authorization model
you can easily expand your API without having to rewrite the authorization
you can change your authorization logic independently of your code
you can audit your authorization logic more easily
your authorization logic is technology-neutral. It works for REST APIs, web services, databases, and more
I recommend you check out the following resources:
the OASIS XACML website
the ALFA plugin for Eclipse - a free tool to write XACML policies.
The XACML developer community
There are both vendor and open-source implementations of XACML:
Axiomatics is a vendor solution that provides both .NET and Java XACML implementations
SunXACML is a long-standing open source Java XACML implementation
HTH,
David.
Not trying to resurrect an old question, but I came here searching for almost exactly the same thing and wanted to add a solution that I think is more RESTful.
I haven't actually implemented this but think it may help others who come here...
Your second option is very nearly what I think should be done, but instead of a get use the OPTIONS verb to your resource which will then return an "allow" header with a list of available verbs for that resource.
OPTIONS /listing/5
Assuming your resources are fine-grained enough for this to make sense, then you would know if you can make a POST/DELETE

How To Disable Per Request (URL Based) Claims Authorization in WCF?

I have a WCF service which uses claims based authorization.
What I want to do is to attribute an operation with a ClaimsPrincipalPermissionAttribute and only have the authorization check trigger once in my custom ClaimsAuthorizationManager. However I am finding that this authorization check is being triggered twice; once for the URL and then a second time on the operation itself.
I can't find much information on this subject, but what I have found indicates that this is by design. Is it possible for me to overwrite this behavior and not perform any authorization on the URL, and only authorization based on the operation?
I have no interest in authorizing based on URLs, and would really rather avoid adding claims for each and every URL as I am likely to have a lot of them and they may change in future.
I have read several articles, and seen videos from Dominick Baier on this subject, and while I have learnt a lot from these I still can't find an answer to this. Is this simply not possible and I just have to deal with having to authorize based on the URL as well?
You can't change this behavior - what I did is to write a custom claims permission attribute that does emit different claim types. This way I could distinguish between the per-request invocation and the explicit attribute.
https://github.com/thinktecture/Thinktecture.IdentityModel.45/tree/master/IdentityModel/Thinktecture.IdentityModel/Authorization
or the Thinktecture.IdentityModel nuget package.