I am using helm charts. During the deploy process, I override values as below:
auth.generic_oauth: # for SSO
groups_attribute_path: contains(groups[*], 'GrafanaAdmins') && 'Admin' || 'Viewer'
enabled: true
name: Keycloak
allow_sign_up: false
client_id: grafana
client_secret: CLIENT_SECRET
scopes: openid,email,profile,groups
team_ids:
allowed_organizations:
auth_url: AUTH_URL
token_url: TOKEN_URL
api_url: API_URL
tls_skip_verify_insecure: true
In the Keycloke, I create a client, a client scope, a group mapper in the client scope, a group and assign GrafanaAdmins group to a user.
What I want to achieve is to be able to login to Grafana with a user defined in Keycloak that is also assigned the GrafanaAdmins group.
What I have is this error:
t=2021-12-27T13:32:18+0000 lvl=warn msg="Not allowing oauth_generic_oauth login, user not found in internal user database and allow signup = false"
t=2021-12-27T13:32:18+0000 lvl=eror msg="invalid username or password" logger=context userId=0 orgId=0 uname=
I don't want to sign up new users nor I want to use additional database. It should use Keycloak.
Grafana documentation is not very descriptive and it is hard to get around it.
You have a few problems:
Grafana documentation is clear:
Groups mapping: Available in Grafana Enterprise v8.1 and later versions.
You are using Grafana 7.1.5 and I guess also free OSS Grafana (not a paid enterprise version, where license is required), so group mapping (config groups_attribute_path) is not possible in your case.
You are mixing also Grafana role mapping (role_attribute_path) with Grafana group mapping (groups_attribute_path) Please note role != group. So I guess you wanted:
role_attribute_path: contains(groups[*], 'GrafanaAdmins') && 'Admin' || 'Viewer'
instead of:
groups_attribute_path: contains(groups[*], 'GrafanaAdmins') && 'Admin' || 'Viewer'
Grafana creates internal users, based on the OIDC response, so you want to sign up new users in auth.generic_oauth section:
allow_sign_up: true
I bet your scopes config has wrong syntax and it should be:
scopes: openid email profile groups
Generally, you are using groups in the Keycloak to map roles in the Grafana. It is possible, but better logic will be to use roles in the Keycloak to map roles in the Grafana. Keycloak/Grafana have concept roles/groups and it is up to you how will you use them for your users. I would start with basic roles concept first.
Related
Below is my kubeconfig file for accessing kubernetes clusters:
kind: ClientConfig
apiVersion: authentication.gke.io/v2alpha1
spec:
name: dev-corp
server: https://10.x.x.x:443
certificateAuthorityData: ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
authentication:
- name: oidc
oidc:
clientID: aaaaad3-9aa1-33c8-dd0-ddddd6b5bf5
clientSecret: ccccccccccccccccc-
issuerURI: https://login.microsoftonline.com/aaaa92-aab7-bbfa-cccf-ddaaaaaaaa/v2.0
kubectlRedirectURI: http://localhost:12345/callback
cloudConsoleRedirectURI: http://console.cloud.google.com/kubernetes/oidc
scopes: offline_access,profile
userClaim: upn
userPrefix: '-'
groupsClaim: groups
preferredAuthentication: oidc
There are different OAuth grant types.
My understanding is, above OAuth grant type is client credential grant type, that requires client_id, client_secret, token URL(issuerURI), scope
What is the significance of fields kubectlRedirectURI, cloudConsoleRedirectURI, userClaim, userPrefix?
How OIDC different from OAuth2?
oauth2.Config does not store userClaim & userPrefix, groupsClaim information
, as shown here.... https://github.com/golang/oauth2/blob/master/oauth2.go#L41
How to store kind:ClientConfig with oidc based authentication into cache? for example api.Config can be stored with an API from client-go to write api.Config as shown here.
KUBECTL_REDIRECT_URL: the redirect URL that kubectl oidc login uses for authorization. This is typically of the format http://localhost:PORT/callback, where PORT is any port above 1024 that will be available on developer workstations, for example http://localhost:10000/callback. You must register the URL with your OIDC provider as an authorized redirect URL for the client application.
USER_PREFIX: prefix prepended to user claims to prevent conflicts with existing names. By default, an issuer prefix is appended to the userID given to the Kubernetes API server (unless the user claim is email). The resulting user identifier is ISSUER_URI#USER. We recommend using a prefix, but you can disable the prefix by setting USER_PREFIX to -.
userClaim: the user identifier in the token under the claim name configured in spec.authentication.oidc.userClaim in the client configuration file.
cloudConsoleRedirectURI the name tell the story, the cloud redirect URL for OIDC, for example in case of google https://console.cloud.google.com/kubernetes/oidc
OIDC vs OAuth2
What's the difference between OpenID and OAuth?
The file in the question from OIDC and you are comparing the value with Oauth, both handling at different way, better to update the question again with Oauth config file.
api-server-authentication
you can check kubeconfig builder
kubernetes-engine-oidc
How to store kind:ClientConfig with oidc based authentication into cache?
you can write to a file and then read, or somewhere in the cloud storage as well
I have configured a custom SAML app in Google Workspace and configured AWS Opensearch to use SP-initiated SSO.
I am able to access OpenSearch via the URL but I get the following error
Missing Role
No roles available for this user, please contact your system administrator.
I guess there are some SAML attribute mapping and group set up that are required. I've created an opensearch group in Google for users that I wish to have access.
I think the following AWS Opensearch parameters require a value
SAML master backend role
Subject key
Roles key
From what I can see, the issue is that you need to create a custom attribute inside the Admin console of Google Workspace with the "roles" for AWS Opensearch.
You can also read this information in the AWS documentation.
This was resolved using and IdP initiated authentication flow instead. The links posted in answers above helped us implement this.
I'm having a bit of trouble understanding how to link together authenticating and authorizing users in my frontend using Keycloak and the keycloak-js adapter.
To preface this: I know that the keycloak-js adapter requires the client to have public as the Access Type.
My main question is how can I use Keycloak authentication AND authorization via the same client. If the Access Type MUST be set to public for the keycloak-js adapter to work, then how can I restrict access to my API depending on the users permissions?
Will I need two clients for this? One for authentication and one for authorization? If so, how can I use the access token from the authentication client in the authorization client?
My current setup in Keycloak is as follows:
Realm: admin-service
Client: admin-service-api
Access Type: confidential (because I want to use authorization to restrict api requests according to permission levels)
Root URL: http://localhost:8080/
Valid Redirect URIs: http://localhost:8080/*
Roles:
admin
Users:
test-user
My authorization setup for admin-service-api is as follows:
Resources: Books Resource
Uri (these are my API endpoints):
/v1/books
/v1/books/{id}
Scopes:
books:delete
books:create
books:update
books:read
Policies:
Default Policy
Books Policy:
Realm roles:
admin (the required checkbox is not checked)
Permissions:
Default Permission
Books Resource Permission:
Resources: Books Resource
Apply Policy: Books Policy
So with this setup, I have restricted my API (which is written in GoLang) to only allow requests if the requesting user has the appropriate permissions by making a request to the Keycloak API via https://my.auth.server/auth/realms/{{realm_name}}/protocol/openid-connect/token to retrieve the users access token and a list of the users permissions.
From there I can use this access token to make requests to my API to create/read/update/delete books so long as my test-user has the admin role. If my user does not have the admin role, the user is presented with an unauthorized message (401).
i am new to grafana and i want to use a JWT authentication as described in grafana docs : https://grafana.com/docs/grafana/latest/auth/jwt/ how can i use generally the JWK to authenticate with external Identity provider ?
specifically, which jwts endpoint i have to use, is it my main base url for my provider? and then the provided http auth header?
my grafana.ini configuration file :
[auth.jwt]
enabled = true
header_name = X-JWT-HEADER
cache_ttl = 60m
jwk_set_url = https://$AUTH-PROVIDER-URL/
username_claim = user
email_claim = email
after restarting the grafana server i see no changes for my grafana login page and i can still login only with the admin user. should this works with such configuration or I have missed something?
Note that the auth.jwt is currently broken by design:
https://github.com/grafana/grafana/issues/8198
Even if you get everything else right it requires you to have prepopulated all accounts in grafana. It should provide similar functionality to auto-sign-up provided in auth.proxy The whole argument for auth.jwt is to provide something similar to, but safer to auth.proxy:
https://cloud.google.com/iap/docs/identity-howto
#Ying.Zhao
the authentication with JWT didn't work due to missing some claim properties in the json web endpoint (JWKs url)..
alternatively you can use the "auth generic" or proxy-auth for your OAuth Login.
[auth.proxy]
enabled = true
# HTTP Header name that will contain the username or email
header_name = X_HEADER_NAME
header_property = username
I would like to create a all users policy in Keycloak:
How can I specify that this policy is for all users?
Using '*' didn't work.
How can I specify that this policy is for all users? Using '*' didn't
work.
Having a policy for all users is kind of unusual I would say.
Nonetheless, You can try to create a default Realm role, so all users will get that role, and then create a policy-based on that role.