Keycloak: How to import service accounts with client roles - jboss

I've been trying to import pre-configured clients and service accounts with roles so my json file looks something like
[
"realm": "dev",
"users": [
{
"username": "service-account-example-client",
"enabled": true,
"serviceAccountClientId": "example-client",
"clientRoles": {
"realm-management": ["view-users"],
"example-client": ["view-users"]
}
}
]
]
Also tried to set clients in realm configuration which gets imported but in both cases I have the following issue
Service accounts created,
Client has role in roles list,
But client role for in "Service account roles" is not set.
How to import the service account roles with assigned client roles during setup process when REST API is not available yet?
Also using import export from the UI strips out some configurations.
Keycloak version is: 8.0.0
Thanks.

I have just found out that this is a known issue of keycloak dir import.
You can use singleFile import as a workound. See issue comments for more details / example for singleFile import. Fix is coming in v11.0.0

So at the I decided to go with post-installation step in which re-use generated passwords to assign client role to client with service account
$ /opt/jboss/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password ${LAST_PASS} --client admin-cli
$ /opt/jboss/keycloak/bin/kcadm.sh add-roles -r dev --uusername service-account-example-client --cclientid realm-management --rolename view-users'

Related

Service account not assigned to CloudSQL instance

I would need to have a CloudSQL instace created with particular service account. Trying API call instances.insert:
POST https://www.googleapis.com/sql/v1beta4/projects/{project}/instances
{
"serviceAccountEmailAddress": "<my account>#managed-gcp.iam.gserviceaccount.com",
"name": "pvtest20200611-3",
"settings": {
"tier": "db-n1-standard-1"
},
"databaseVersion": "MYSQL_5_7"
}
The instance is created but it has a generated svc account (e.g. p754990076948-kf1bsf#gcp-sa-cloud-sql.iam.gserviceaccount.com) instead of mine.
For my SA, I have storage admin/storage object admin roles assiged (this is what I would need newly created instances to always have). I also added cloudsql admin role. When I thought it was a role problem so even tried the Project Editor role, but this didn't work.
I have tried MySQL and Postgres db types.
Would you know why is not my account picked up, why is CloudSQL engine always assigning it's own?
What are requirement/setup for custom SA to work with CloudSQL instance?
When you create an instance in Cloud SQL, it will use the default one during the creation, so, you won't be able to set a custom one during the creation.
It's possible, however, for you to give access and permissions for a Service Account after the creation. As explained in the official documentation Granting roles to a service account for specific resources, you can provide specific permissions to your Service Account. You can try using the gcloud command as follows:
gcloud projects add-iam-policy-binding my-project-123 \
--member serviceAccount:my-sa-123#my-project-123.iam.gserviceaccount.com \
--role roles/editor
Besides that, you can also check all your available Service Accounts using this link here, to verify if your custom one is there and even add the permissions via UI, if you think it's better via this way.
Let me know if the information helped you!

403 status when creating realm and user using service account from master realm - Keycloak

I have a multitenant app where realms will be created automatically by the backend service.
For this, I have a client with service account enabled and full scope allowed at the master realm, but when using it through the keycloak admin java client I can create a new realm, but can't create a new user inside of it.
KeycloakBuilder
.builder()
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.serverUrl(masterCredentials.getAuthServerUrl())
.realm(MASTER_REALM)
.clientId(masterCredentials.getClientId())
.clientSecret(masterCredentials.getClientSecret())
.resteasyClient(buildResteasyClient())
.build();
When logging with the admin user the user was created successfully:
Keycloak.getInstance(masterCredentials.getAuthServerUrl(),
"master",
"admin",
"admin",
"admin-cli");
You need to set needed roles for your service Account , can check more information about service account roles in keycloak wiki

Performing the association of an existing service account to a newly created subscription in gcloud

I have a service account in gcloud that i am using to create a new topic and subscription to that topic in that order.
However i need to be able to assign the newly created subscription to the service account explicitly. In the UI this is done by going to
Pubsub > Subscription > Selecting the subscription and then clicking on "Search member" > Adding the service account.
However I want to automate this using the gcloud command.
So far I have been able to :
1) Activate a service account serviceAccountA
2) Create Topic
3) Create subscription to the Topic
While trying to use the following command to set iam policy on the service account so as to give pubsub.editor role to the service account.
gcloud iam service-accounts set-iam-policy serviceAccountA <json> file path>
Json file content is as below:
{
"bindings": [
{
"role": "roles/pubsub.editor",
"members": ["serviceAccountA"]
}
]
}
The above gcloud command results in the error:
ERROR: (serviceAccountA PERMISSION_DENIED: Not allowed to get project settings for project <id>
I am missing something. Is there an easy way to associate the subscription with a specific service account?
I suspect the problem is that the service account you've activated doesn't have permissions to give itself permissions. Try setting this with a gcloud account that has edit permissions for the project. You can set the current account with gcloud auth login or gcloud config configurations activate <your_config>.

Can I authenticate gcloud cli using both service account and user credentials?

Google API clients typically recognise the GOOGLE_APPLICATION_CREDENTIALS environment variable. If found, it's expected to point to a JSON file with credentials for either a service account or a user.
Service account credentials can be downloaded from the GCP web console and look like this:
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "...",
"client_email": "...",
"client_id": "...",
"auth_uri": "...",
"token_uri": "...",
"auth_provider_x509_cert_url": "...",
"client_x509_cert_url": "..."
}
User credentials are often available in ~/.config/gcloud/application_default_credentials.json and look something like:
{
"client_id": "...",
"client_secret": "...",
"refresh_token": "...",
"type": "authorized_user"
}
Here's an example of the official google rubygem detecting the type of credentials provided via the environment var.
I'd like to authenticate an unconfigured gcloud install with both types of credential. In our case we happen to be passing the GOOGLE_APPLICATION_CREDENTIALS variable and path into a docker container, but I think this is a valid question for clean installs outside docker too.
If the credentials file is a service account type, I can do this:
gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS}
However I can't see any way to handle the case where the credentials belong to a real user.
Questions:
Why doesn't the official gcloud tool follow the conventions that other google API clients use and use GOOGLE_APPLICATION_CREDENTIALS when available?
Is there a hidden method that will activate the user credentials case?
As you point out gcloud command line tool (CLI) does not use application default credentials. It has separate system for managing its own credentials.
GOOGLE_APPLICATION_CREDENTIALS are designed for client libraries to simplify wiring in credentials, and gcloud CLI is not a library. Even in the client code best practice is not to depend on this environment variable but instead explicitly provide credentials.
To answer your second question, user credentials can be obtained via
gcloud auth login
command. (NOTE this is different from gcloud auth application-default login) This besides saving actual credentials will also set account property in current configuration:
gcloud config list
gcloud can have many configurations, each with different credentials. See
gcloud config configurations list
You can create multiple configurations, one with user account another with service account and use it simultaneously by providing --configuration parameter, for example
gcloud compute instances list --configuration MY_USER_ACCOUNT_CONFIG
Similarly you can also switch which credentials are used by using --account flag, in which case it will use same configuration and will only swap out the account.
I've found a way to authenticate a fresh gcloud when GOOGLE_APPLICATION_CREDENTIALS points to a file with user credentials rather than service account credentials.
cat ${GOOGLE_APPLICATION_CREDENTIALS}
{
"client_id": "aaa",
"client_secret": "bbb",
"refresh_token": "ccc",
"type": "authorized_user"
}
gcloud config set auth/client_id aaa
gcloud config set auth/client_secret bbb
gcloud auth activate-refresh-token user ccc
This uses the undocumented auth activate-refresh-token subcommand - which isn't ideal - but it does work.
Paired with gcloud auth activate-service-account --key-file=credentials.json, this makes it possible to initialize gcloud regardless of the credential type available at $GOOGLE_APPLICATION_CREDENTIALS

Adding roles to service accounts on Google Cloud Platform using REST API

I want to create a service account on GCP using a python script calling the REST API and then give it specific roles - ideally some of these, such as roles/logging.logWriter.
First I make a request to create the account which works fine and I can see the account in Console/IAM.
Second I want to give it the role and this seems like the right method. However, it is not accepting roles/logging.logWriter, saying HttpError 400, "Role roles/logging.logWriter is not supported for this resource.">
Conversely, if I set the desired policy in console, then try the getIamPolicy method (using the gcloud tool), all I get back is response etag: ACAB, no mention of the actual role I set. Hence I think these roles refer to different things.
Any idea how to go about scripting a role/scope for a service account using the API?
You can grant permissions to a GCP service account in a GCP project without having to rewrite the entire project policy!
Use the gcloud projects add-iam-policy-binding ... command for that (docs).
For example, given the environment variables GCP_PROJECT_ID and GCP_SVC_ACC the following command grants all privileges in the container.admin role to the chosen service account:
gcloud projects add-iam-policy-binding ${GCP_PROJECT_ID} \
--member=serviceAccount:${GCP_SVC_ACC} \
--role=roles/container.admin
To review what you've done:
$ gcloud projects get-iam-policy $GCP_PROJECT_ID \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:${GCP_SVC_ACC}"
Output:
ROLE
roles/container.admin
(or more roles, if those were granted before)
Notes:
The environment variable GCP_SVC_ACC is expected to contain the email notation for the service account.
Kudos to this answer for the nicely formatted readout.
You appear to be trying to set a role on the service account (as a resource). That's for setting who can use the service account.
If you want to give the service account (as an identity) a particular role on the project and its resources, see this method: https://cloud.google.com/resource-manager/reference/rest/v1/projects/setIamPolicy