Does an add/remove role require a "Publish to PDP" action to take effect in wso2? - xacml

For testing purposes, We set a given policy that allows GET operations on one resource to users with Manager Role.
Then we used the "PEP TryIt" form to check how the policy was applied to users with and without the Manager role, and right after removing and adding the role. We found these two behaviors:
1) The PEP TryIt, returns Permit, for a given user who got his/her Manager role removed => Unexpected.
Only after publishing the given policy to the PDP, the system returns NotApplicable.
2) The PEP TryIt, returns NotApplicable, for a given user who got his/her Manager role reassigned => Unexpected
Only after publishing the given policy to the PDP, the system returns Permit.
Does the policy need to be published to the PDP, every time a Role is granted/removed to a given User ? Is this the expected behavior or should be considered a bug ?
Thanks!
Fermin Ordaz.

Yes.. I guess you have experienced the correct behavior.....
Carbon user store is acts an attribute finder (PIP) for the PDP. Basically Carbon user store is the default PIP implementation. In the PIP level, PDP has introduced the attribute caching. In simply, we can say that It caches the user's attribute (here user's roles). Your assignment modification, It is not known by the PIP cache. (As User store and PDP act as two separate entities) Therefore it can not invalidate the cache. That has been caused to experience above result. Basically Attribute sources (user stores or any ) are independent from the PDP and they can be running in separately. There are two way you can void this,
Once you update any attributes that is related to PIP. you can clear the attribute cache using UI or API. In UI, you can go to Entitlement-> PDP->Extension and There is icon to clear attribute cache. This has been expose via admin service.. therefore you can call this method from some external application as well.
You can disable or reduce the invalidation value of the attribute cache using entitlement.properties file which can be found at <IS_HOME>/repository/conf/security directory
PDP.AttributeCaching.Enable=true
PDP.AttributeCaching.CachingInterval=300
Also, for NotApplicable, I guess you have not enable the policy in PDP.. Once you have publish a policy to PDP.. It must be enabled to put it in to actual runtime

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.

What's the expected behavior of a dependent app when an LDAP user's DN changes?

Is there any expected/standardized behavior for an app that authenticates via LDAP, when one of its registered users has its DN changed? (Or more generally, when their effective principal changes, which seems to commonly be their DN. I'll say "principal" instead from here, though I usually think "DN".)
Here's an example from Gitlab running into this issue: https://gitlab.com/gitlab-org/gitlab-foss/issues/993
In their case (based on the commit linked in that issue) they seem to address this by using multiple attributes to identify users instead of a single one, so that a single change doesn't prevent them from mapping back to the same LDAP user.
It seems to me the available options would be:
Don't try to prevent the issue but provide some method to change the principal stored (either in-app or via DB modifications)
Try to prevent the issue by picking (automatically or manually by user) a better, static user attribute to use as principal
Try to mitigate the issue by cross-referencing multiple attributes, as in the above links
Which of these would be the expected/"best" approach here, if any?

Is the appropriate way to fetch user roles/permissions/information from an ID Token or an API endpoint (or other)?

When creating an Angular web application that also has a backend API, I feel like there are a few different options when it comes to getting User Info such as roles/permissions/display name/email/etc.
We can use an ID Token to store user claims like this. That token can be put into local storage or a cookie and the Angular app can read it and render the UI/guard against unauthorized route navigation/etc as soon as the app spins up (since the ID token is available right then and there).
We can NOT use an ID Token for this information at all and instead have an API endpoint that we have to call every page re-load to fetch this data. The server would decode our access token/ID token and return the data in JSON format.
Lastly, there could be some hybrid solution where basic User Info like names/emails are stored int he ID token and available right away, but user permissions (which could be a larger payload and maybe not wanted in a token that should be small) could be fetched via an API
Is there maybe a 4th option I didn't think about?
I haven't been able to find many conventions around which of these options is the best. I like the ID token option as it requires no "blocking" of the UI until the API request is done making the page load that much faster, but I'm not sure if that goes against other conventions.
All your approaches rely on a permissions-based system where you would have been granted permissions upon login. These are sometimes referred to as birth rights since they are typically given when the user is created or whenever their permission sets change. The typical way to carry birth rights around is to have them as scopes / assertions inside an identity token (e.g. OAUth 2.0) that you pass along from service to service.
You can also have your applications retrieve additional permissions / roles / entitlements from a backend store (a database for instance) based on the user ID so that you know what your user can or cannot do.
So far this is essentially role-based access control / permissions-based access control.
The main challenge with that approach is role explosion / permissions explosion as well as token bloat (too many permissions in the token) and administration pains - you have to assign roles and permissions to users all the time. You have to deprovision. It becomes a management nightmare and a risk you may have the wrong permissions set for users. You then need to think about identity and access governance as well as recertification. Heavy.
What's the alternative?
You definitely need some roles - yes - but they should be kept to a minimum - essentially the business roles you need in your apps e.g. a doctor, a nurse, a non-medical staff rather than doctor_hospital1_unitA.
You should then express your authorization as plain-old English policies using any number of attributes - not just user attributes but also contextual information (time, location), resource information (what type of object, who owns it, where is it? How sensitive is it?), and action information (view, edit, delete...).
Sample Policies
A doctor can view a medical record if they are assigned to the patient the medical record belongs to
A nurse can view a medical record if the medical record is in the same unit as the nurse
A non-medical staff can view the financial section of a medical record but not the medical section.
Attribute-Based Access Control
Following this approach is called attribute-based access control (abac). In ABAC, you clearly decouple your app from the authorization process. Authorization is expressed as policies rather than code which makes it easier to:
update
audit
review
How to implement?
You have several options to implement ABAC (from open-source to commercial). You can go down the XACML (xacml) path, the ALFA alfa path, or others. They all have similar architectures with:
the notion of a policy decision point (PDP): a service that evaluates the authorization requests against the set of policies you defined and produce decisions (Permit / Deny) that can be enriched with additional information e.g. order to do two-factor Authentication.
the notion of a policy enforcement point (PEP): an interceptor that sits in front of or inside your API that will send an authorization request to the PDP.
I've written about the architecture more in detail in this SO post.
ALFA Example
In ALFA, a sample policy would look like:
policyset viewMedicalRecord{
target clause object == "medical record" and action == "view"
apply firstApplicable
policy allowDoctors{
target clause role == "doctor"
apply firstApplicable
rule allowAssignedPatient{
permit
condition patient.assignedDoctor == user.name
}
}
}

setting passwordMustChange attribute to "on" in Sun-one LDAP doesn't have any expected effect

I am using JNDI framework to interact with various LDAP servers specifically for Sun one LDAP, I am observing the following:
Use case: If Administrator resets password of any user in Sun-One LDAP server then passwordMustChange attribute is set to "on". As a result user has to change his/her password on next logon. This is what documented.
I am performing same action through JAVA code using JNDI. I observed that this attribute is set to "on" successfully. So programming logic is correct.
But when I logon with that user on LDAP server, it doesn't give any error or pop saying that password has expired and please change your password.
The same use case works as expected in case of Active Directory (AD ) servers
In case of AD, we need to set pwdLastSet to 0. It works and system asks to change password on next logon.
On contrary, same use case does not work for any LDAP flavour such as Sun-One LDAP, ADAM, or Open LDAP.
Please let me know if anybody has observed such issue and suggest me how to fix this.
You're setting it in the wrong place. passwordMustChange is an attribute of the policy, not of a user. It means that if you set the operational attribute pwdReset for any user, he must change his password on next login, and that is advised via a response control when he does so.
That in turn means you must use the password-policy request control when binding a user, and check the response control. It also means that you must use the change-password extended operation when changing the password, rather than just rewriting the attribute.
This also explains why you thought you had to add objectClass=passwordPolicy to the user entry. You don't. You have to define a separate policy object containing a value for passswordMustChange and the other policy attributes, and specify that in the configuration as default policy, or in the user entry as his specific policy if you're going that far.
You need to reread the documentation and distinguish clearly between policy attributes and user operational attributes. They're listed separately.
What code are you using for the extended operation and request/response controls? I had to write mine. I posted it on the Sun Java forums several years ago: is it that code? Just curious.
Unfortunately there is no standard for this kind of feature (there's an internet draft, expired and which is partially implemented in different servers).
Depending on your versions of Sun Directory Server, there are different ways to do this (SunDS 6.x introduced a new password policy based on the Internet Draft).
With 5.x, I seem to recall that the passwordExpirationTime would take a specific value when the password is expired. The server will return a PasswordExpired Control part of the Bind response saying that it has expired.
With 6.x and beyond, the pwdReset operational attribute is set to true. The server will either return the PasswordExpired Control, or a PwdPolicyControl response if you've set the PwdPolicyControl request in the Bind request.

Yii RBAC, Role change in runtime

I am building up a dynamic RBAC system for Yii and I don't know how to handle this problem:
The moderators can change the roles of the Users, furthermore the User can change it too by getting a different qualification (let's say achievement, so s/he can do more stuff and it can happen both ways).
What happens, when the role is changed Backwards (a role with less right) or Forwards (a role with more right) when s/he is logged in? Cannot access the functions he just got the right to use? Or can still access the functions until a logout/relog action?
Thanks your help in advance.
The effect of changing the authorization assignment will be inmediate.
Only the successive calls to IWebUser::checkAccess() issued in the same request may return cached values, since the default implementation of IWebUser, i.e. CWebUser, uses a static attribute to cache the calculated permissions.
To clarify the procedure, you will be calling IAuthManager::revoke() on the old permissions and IAuthManager::assign() on the new ones.
Edit
Sometimes you store session information through the IWebUser::setState() method; if the state of the currently logged user shall change along with the permissions, e.g. you store the current user's role name, you must take this into account and either call IWebUser::clearState() or IWebUser::logout() followed by IWebUser::login() –the latter also clears the cached permissions in the CWebUser implementation.
CWebUser::_access is declared private, so you will have to declare a new attribute if you want to override the default implementation.