We are using Keycloak for a SaaS offering. Each user is part of a tenant / account and has specific roles for accessing this account's data. The roles are configured in Keycloak and the related account is saved as a user attribute on the user.
Now we've got a new requirement to give users access to multiple accounts. And for each of these accounts the user might have different roles:
User A:
- Account A:
- ADMIN
- Account B:
- Reader
User B
- Account B:
- Reader
...
I found a lot of articles about different approaches to multi tenancy, but nothing in this direction. Most of the articles combined roles and groups. But in my case I would need to create a new group for every account. So I would end up with thousands or millions of groups.
Right now my APIs can authorize requests based on the issued JWT. Ideally I can keep this.
What's the best way to get this structure (users having access to multiple accounts with different roles) into place?
Is this actually possible with keycloak?
Or am I thinking into the wrong direction?
It sounds like a rather common use case.
Thanks a lot already.
The roles are configured in Keycloak and the related account is saved as > a user attribute on the user.
I am not sure why you need this, since you can extrapolate that based on the user role.
Now we've got a new requirement to give users access to multiple
accounts. And for each of these accounts the user might have different
roles:
If I fully understood your problem I think it can be solved with Client Level roles. For instance:
Go to :
Your Realm;
Clients;
Account A;
Roles;
Add Role;
Set the role and save it
To set the role to the user go to
Your Realm;
Users;
Click on the user;
Role Mapping;
From the Client Roles dropdown select the client (e.g., Account A)
Add the Role;
Right now my APIs can authorize requests based on the issued JWT.
Ideally I can keep this.
How a token request to the Account A on behalf of user a would look like:
"acr": "1",
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"AccountA": {
"roles": [
"ADMIN"
]
},
"AccountB": {
"roles": [
"Reader"
]
},
"account": {
"roles": [
"manage-account",
"view-profile"
]
}
},
One might say that when requesting a token from client Account A one does not really care about the roles in the client Account B. That can be solved by using Keycloak's Scope Feature. With this feature one can select the roles from other clients that are relevant to the current client. By default, all roles are included. Nonetheless, to filter the roles one needs to go:
Your Realm;
Clients;
Client Account A in this case;
Scope;
Switch to OFF the option Full Scope Allowed;
Save.
How the token looks like now:
"resource_access": {
"AccountA": {
"roles": [
"ADMIN"
]
}
},
Related
I'm trying to make a POST request to our KeyCloak.
I can create a user with no problem but once i provide the post request with the federationLink this isn't picked up. I tried it both with the ID and the string of the Federation Link. I noticed that the added Attributed aren't picked up aswell.
The body i post is:
"username": "xx#local",
"email": "xx#local",
"emailVerified": true,
"enabled": true,
"federationLink": "qa.exn-dir.xxx.com/cn=xxx,cn=xxxx,o=xxx",
"attributes":{
"PHONE_NUMBER": [
"xxxx"
],
"CARD_NUMBER":[
"xxx"
]
},
"credentials": [
{
"type": "password",
"value": "12345"
}
]
And i post this to /auth/admin/realms/REALM/users
When looking at the created user this is still in the default federation and not the one we provided in the body.
Any idea how i could solve this?
User federation in keycloak provide functionality to import user data from your selected LDAP system, source from keycloak documentation
Keycloak can store and manage users. Often, companies already have LDAP or Active Directory services that store user and credential information. You can point Keycloak to validate credentials from those external stores and pull in identity information.
That means keycloak does not store the user credential, keycloak only point to those external stores to validate the user credentials.
Quoting from your comment replying to #sventorben
Thanks for the reply. The users that we need to create in case are external users and they need to be added in keycloak using the API. Atleast that is what i'm told.. But they need to be added to a specific federationLink. This is my first time using KeyCloak so i'm still new to the whole thing
In case of your requirement to create external users:
You can create it and store the user data information and credential in keycloak, that means you need to send the appropriate user data and credentials along to the keycloak so that keycloak can use it.
Or if you prefer to load the users data and validate the credential from your LDAP system, then first you need to register the external users to your LDAP system just like #sventorben said, and then let keycloak automatically synchronize these new users (based on your synchronize settings of the user federation) or if you prefer manually, you can do it via keycloak admin console.
We have impersonation roles for a number of admins -- it's working as expected.
A Client application, for audit purposes, would like to be informed when a token issued is via impersonation -- is there a way we can send an attribute/claim to the Client informing that the token is an Admin impersonating a user?
Yes, Keycloak stores that information in user session notes. The information can be mapped via builtin mappers.
Follow these steps:
Navigate to Clients -> <your client> -> Mappers
Click Add Builtin
Choose Impersonator Username and/or Impersonator User ID (depends on whether you want the username or id as a claim in the token)
Click Add selected
That's it. Your tokens contain the information as shown below:
{
...
"sub": "9ab9bfd1-f95d-4aa1-a8b2-0d1fb06b365a",
"preferred_username": "test",
...
"impersonator": {
"id": "2d2f4b4a-716c-4428-97cd-22fa731c0d9a",
"username": "admin"
}
...
}
We are evaluating VSTS for an enterprise use.
One of the challenges from security team is lack of control and governance around usage of PAT (personal access tokens)
As I understand, any user can create one or more PAT and this PAT could be used from outside network to make REST API calls (or to connect with tools outside network) to VSTS to access information.
Have number of questions around this scenario and any insights/ workarounds from your experience are appreciated
How is your organization handling this issue or has worked around this issue? Looking for options to get buy-in from security team. Has anyone ever approached Microsoft with this problem statement? I am sure there are many enterprise customers, wondering how did they tackle this issue.
Is there a way to disable creation of PAT for all users? Don't see any option, but any workaround to enforce this.
Is there a way to get list of all PATs across all users? Don't see any option in VSTS, but may be through a script of some sort
Thanks
Update
There is now an API to list which PATs have been created and the option for an admin to revoke PATs on behalf of their users:
GET https://vssps.dev.azure.com/{organization}/_apis/tokenadmin/personalaccesstokens/{subjectDescriptor}?api-version=5.0-preview.1
Response:
{
"value": [
{
"clientId": "00000000-0000-0000-0000-000000000000",
"accessId": "00000000-0000-0000-0000-000000000000",
"authorizationId": "952858d3-7084-4635-964e-3c2a57645185",
"hostAuthorizationId": "00000000-0000-0000-0000-000000000000",
"userId": "bb5bb6c8-ef0a-400f-8987-92b3674d2043",
"validFrom": "2018-07-19T00:00:00",
"validTo": "2018-07-19T00:00:00",
"displayName": null,
"scope": "app_token",
"targetAccounts": null,
"token": null,
"alternateToken": null,
"isValid": true,
"isPublic": false,
"publicData": null,
"source": null
},
....
More details here:
https://learn.microsoft.com/en-us/rest/api/azure/devops/tokenadmin/personal%20access%20tokens/list?view=azure-devops-rest-5.0
And to revoke tokens of other users then use:
POST https://vssps.dev.azure.com/{organization}/_apis/tokenadmin/revocations?api-version=5.0-preview.1
[
{
"authorizationId": "532c7fe6-74f8-408b-8051-4abb73dca491"
}
]
See:
https://learn.microsoft.com/en-us/rest/api/azure/devops/tokenadmin/revocations/revoke%20authorizations?view=azure-devops-rest-5.0
There is an option to turn off Basic Credentials/Alternate authentication and SSH credentials, which are less secure than personal access tokens. There is no option to turn off Personal Access Tokens. I suppose the primary reason for this is that Git and the VSTS Agent infrastructure rely on these access tokens to work.
Since the Personal Access Tokens can be restricted in their scope, they're actually more secure than caching the user's credentials directly. They can also never give more permissions than the user already has.
You can't query all personal access tokens for all users, that would be a huge security violation. Exactly for the reason you're trying to restrict access to these tokens.
You can disable OAuth and Basic Credentials. This will not block Personal Access Tokens:
https://learn.microsoft.com/en-us/vsts/accounts/change-application-access-policies-vs?view=vsts
Impact on Azure Conditional Access is explained here:
https://learn.microsoft.com/en-us/vsts/accounts/manage-conditional-access?view=vsts
Important
VSTS only enforces conditional access policies when a user signs into services with their AAD credentials. Accessing VSTS using personal access tokens (PATs), alternate authentication, OAuth, and SSH keys circumvents conditional access policies.
Remember that when a person performs authentication using Azure Conditional Access and then leaves the building will be able to use that credential until it expires. In the end, security comes from education and monitoring, not from trying to put everything in an airtight container.
VSTS does keep an activity log which includes which users have performed which actions. This log will include the user's IP address. This way you can at least monitor the actions.
We are using AWS Cognito (Federated Identities) in order to provide login via facebook and google+.
We are facing the following challenge. Our company is providing different apps, that interact with each other, so that we would like to have authenticated users to have one identity inside of one cognito identity pool. And to make use of the sync store cross apps.
For cognito you can only choose one audience (client-id/app-id) for each IdP, when using the AWS console. It would make sense for us, to associate many facebook audiences and google+ audiences with that one cognito setup.
We figured out how to setup many google+ audiences, by creating google+ as IdP via IAM. Which works perfectly fine for us.
We are struggling to figure out a way how to configure many facebook audience via IAM-IdP or any other way.
Well, facebook is no open-id-connect provider, and that seems to be the issue. But I kind of don't want to accept this.
Does one of you know how to configure multiple facebook apps to be associated with one cognito identity pool. Workaround are very welcome.
One additional information: It would be OK for us to use one global facebook app, e.g. 'OurCompany - Network', that would do the trick. The blocker for this is, that it would block us from doing facebook-campaigns with installation tracking. If you know a workaround for this, is also a welcome solution.
I did this by using multiple pools, and then allowing both pools at the role level. That means my Trust Relationships for that role look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"ForAnyValue:StringEquals": {
"cognito-identity.amazonaws.com:aud": [
"<first cognito pool>",
"<second cognito pool>"
]
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
One workaround is to use Developer Authenticated Identities. You will need to validate the Facebook token yourself in this case.
I am using keycloak, and I have created a dropwizard service that I want to start enforcing roles in.
I have tried using the #RolesAllowd("user") annotation, but it always returns 403.
I have also tried #PermitAll, and that works fine.
I know I am connected correctly to the server, as the user has the correct information in it (email, name, etc), but where do the roles come from?
Is there a way to see the roles that a user has?
(answering my own question)
The issue that I was having #RolesAllowd("user") always returns a 403, is because of a checkbox in the Keycloak UI called "Scope Param Required". and the tooltip reads:
This role will be granted just if scope parameter with role name is used during authorization/token request.
It turns out, if you are trying to use that role, and the checkbox is on, it will not be sent to the client, so it will seem to the client that the user does not have that role. That checkbox was clicked ON for me, so that is why the annotation was showing the user was not authenticated.
So, if that checkbox is checked, you need to explicitly ask for the role, here is how you do that with user:
"scope" : {
"realm" : [ "user" ]
}
And here is more information from Keyclaok: https://issues.jboss.org/browse/KEYCLOAK-231
In your application realm on the keycloak admin console, you have a section called roles. There you must add the roles that will be checked by java security.
If you want that a user after a registration automatically receive a role, you need to add this role into default roles (roles -> default roles). You can also add manually roles to existent users in users -(select a user)->role mapping->assigned roles