# API authentification

**URL:** <https://renku.discourse.group/t/api-authentification/544>\
**Category:** Renku (CLI)\
**Created:** [11 February 2022 10:24 UTC](https://renku.discourse.group/t/api-authentification/544 "2022-02-11T10:24:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [11 February 2022 10:24 UTC](https://renku.discourse.group/t/api-authentification/544/1 "2022-02-11T10:24:40Z")

</div>

I am struggling finding which authentication method to pass in my API calls headers.

Basic authentication is failing and passing the /jupyterhub or /gitlab Bearer token doesn’t seem to do the trick.

The first method gives me a -32601 error while the other gives me a simpler 401 unauthorized

Furthermore, I can’t find the proper authentication API endpoint that may provide a proper token.

For reference, I am trying to use /api/renku/datasets.import on a privately deployed renku server.

What is the right way to authenticate my API calls ?

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [11 February 2022 13:01 UTC](https://renku.discourse.group/t/api-authentification/544/2 "2022-02-11T13:01:19Z")

</div>

Hi @erwan.beguin if you are using the swagger page to test the API you need to authorize it with the PKCE flow:

 ![image](https://global.discourse-cdn.com/free1/uploads/renku/original/1X/fe4dddb2fcf664bd9cc3d3f31119c859a1bdd2ba.png)

This will fetch a JWT token from keycloak (assuming your deployment is using keycloak) for you using the `swagger` client and insert it into the API call headers. Any backend API calls sent to `/api` with the JWT in the header will get forwarded to the appropriate service with the appropriate credentials. This client (and the swagger page) were added relatively recently - which renku chart version are you using?

For some reason this isn’t working right now on [renkulab.io/swagger](http://renkulab.io/swagger) (looking into it) but you can try it on dev.renku.ch/swagger (our development cluster). Note that you need to be logged in to renku normally in order for the swagger client to be able to get a token for you.

If you can’t get the PKCE grant to work, you can get a token from keycloak directly, but you need to have the client credentials. Do you have admin access to the keycloak that your renku instance is using?

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [11 February 2022 13:23 UTC](https://renku.discourse.group/t/api-authentification/544/3 "2022-02-11T13:23:55Z")

</div>

I am building a custom connector between a Dataverse server and our renku platform to load datasets.

The ideal scenario would be for me to either have an admin token to manage all the API calls server side, or to let the user login with his renku credentials on my connector and get his token via another API endpoint.

Testing a token with swagger is not very usefull for me as I am using a production application.

I am using the current production version of Renku, and I can have admin access (at least my college, who deployed the platform, can).

Is there a keycloak endpoint to retrieve easily a Token with credentials?

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [11 February 2022 14:57 UTC](https://renku.discourse.group/t/api-authentification/544/4 "2022-02-11T14:57:23Z")

</div>

Yes you can do that; you can find the endpoints on a URL similar to this one: [https://renkulab.io/auth/realms/Renku/.well-known/openid-configuration](https://renkulab.io/auth/realms/Renku/.well-known/openid-configuration) - to get the tokens with a specific client you would use the `token_endpoint` and pass a request body that includes

```auto
grant_type: "password"
username: "username"
password: "password"
scope: "openid"
client_id: "renku"
client_secret: "secret"

```

You will also need to enable the “Direct access grant” for that client in Keycloak in order for this to work. However, it’s not ideal because users will have to trust you with their credentials. You should instead set up an additional client in keycloak under the Renku realm and have your application use this client to perform an oauth2 flow to obtain the JWT token.

PS: it’s really cool to learn that you are working on this! Please keep us informed of your progress and let us know what we can do to help move it along. There was also quite a bit of discussion on this topic already in [Import from Dataverse · Issue #536 · SwissDataScienceCenter/renku-python · GitHub](https://github.com/SwissDataScienceCenter/renku-python/issues/536) and [Dataset Explore · Issue #5028 · IQSS/dataverse · GitHub](https://github.com/IQSS/dataverse/issues/5028) - not sure if any of it is relevant for your case and the information there is probably pretty outdated by this point, but maybe it’s worth having a look.

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [15 February 2022 07:07 UTC](https://renku.discourse.group/t/api-authentification/544/5 "2022-02-15T07:07:52Z")

</div>

Thank you. I will try setting up this flow shortly

I indeed read this GitHub discussion and based my preliminary tests on this.

I will keep you posted, this project takes place in the french public institution INRAE and the code will be open (before the end of the month)

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [15 February 2022 09:16 UTC](https://renku.discourse.group/t/api-authentification/544/7 "2022-02-15T09:16:57Z")

</div>

I am confused about how to obtain the client\_secret, is that a global config secret ? Or is it user owned ?

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [15 February 2022 09:25 UTC](https://renku.discourse.group/t/api-authentification/544/8 "2022-02-15T09:25:46Z")

</div>

The client secret is set in keycloak at setup time, if you create the keycloak instance with our chart - see [here](https://github.com/SwissDataScienceCenter/renku/blob/master/helm-chart/renku/templates/_keycloak-clients-users.tpl#L10). Once it’s installed, you can go to the admin panel in keycloak and go to `Clients -> Renku -> Credentials` to find it. If you prefer, you can also extract the `renku` secret from kubernetes and look under `clients` - there you will see the `renku` client defined with the client secret. Hope that makes sense… so many secrets! 🙂

---

<div class="post-metadata">

**Author:** ![andreas](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/andreas/32/8_2.png) [@andreas](https://renku.discourse.group/u/andreas)\
**Post date:** [15 February 2022 09:42 UTC](https://renku.discourse.group/t/api-authentification/544/9 "2022-02-15T09:42:14Z")

</div>

Auth0 has excellent resources on OAuth2, in particular their diagram of the authorization code flow might be helpful. [Authorization Code Flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow)  
Compared to their diagram, the “Auth0 tenant” would be the Renku Keycloak instance and “your API” is the actual Renku API.

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [15 February 2022 10:21 UTC](https://renku.discourse.group/t/api-authentification/544/10 "2022-02-15T10:21:10Z")

</div>

I managed to get the API token endpoint working for a given user and retrieve a working access token.

However I am struggling passing that token to my next API calls. A authentication Bearer on headers yield :  
{“error”: “authentication”, “message”: “unknown”, “target”: “renku”}

While any other form of headers authentication fail with a -32601 error

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [15 February 2022 11:19 UTC](https://renku.discourse.group/t/api-authentification/544/11 "2022-02-15T11:19:59Z")

</div>

which API endpoint are you trying to use?

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [15 February 2022 11:20 UTC](https://renku.discourse.group/t/api-authentification/544/12 "2022-02-15T11:20:17Z")

</div>

and how are you forming the header?

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [15 February 2022 12:47 UTC](https://renku.discourse.group/t/api-authentification/544/13 "2022-02-15T12:47:25Z")

</div>

I am using the datasets.import endpoint and I am passing Authorization: Bearer on the headers.

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [16 February 2022 09:09 UTC](https://renku.discourse.group/t/api-authentification/544/14 "2022-02-16T09:09:22Z")

</div>

So just to be sure - you are using `POST /api/renku/datasets.import` and passing `Authorization: Bearer <JWT-token>` as one of the headers - correct?

Has the user logged in to Renku itself? I’ve sometimes gotten errors like that when the gateway service (which swaps out the JWT for whatever other tokens are needed) doesn’t have the information on the user. Try logging the user in and repeating the request.

Also, can you try a simpler endpoint like `GET /api/renku/cache.files_list`?

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [16 February 2022 09:29 UTC](https://renku.discourse.group/t/api-authentification/544/15 "2022-02-16T09:29:33Z")

</div>

> [@rrrrrok](#):
>
> /api/renku/cache.files\_list

Yes this is the exact header I am using, as well as the endpoint.  
The user was indeed logged in renku. I tried logged in and logged out with the same result.

I get the same error with the files\_list endpoint

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [16 February 2022 09:53 UTC](https://renku.discourse.group/t/api-authentification/544/16 "2022-02-16T09:53:54Z")

</div>

Ok it could be that the token retrieved in that way is somehow different from the one we obtain automatically. I will try it out.

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [16 February 2022 16:18 UTC](https://renku.discourse.group/t/api-authentification/544/17 "2022-02-16T16:18:38Z")

</div>

I just tried this again with a token I retrieved from the `renku` client using the Direct Access grant (i.e. using client id/secret and username/password). This gives me a JWT token which is then passed in the `Authorization` header and it works. Are you also trying it with the `renku` client or did you make a new client for this?

Two more things to look at: 1) check the JWT token at [jwt.io](http://jwt.io) 2) check the renku-gateway-auth service logs for errors.

Does a request to `/api/user` with the same authorization header work?

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [17 February 2022 10:29 UTC](https://renku.discourse.group/t/api-authentification/544/18 "2022-02-17T10:29:50Z")

</div>

I apologize, there was something I didn’t understand.

I tried the token endpoint with ‘admin\_cli’ as client\_id to prevent using the client\_secret. I believe it’s the reason it gave me the wrong access token.

But after I tried with renku as client\_id with the right client secret, i get :

{‘error’: ‘unauthorized\_client’, ‘error\_description’: ‘Client not allowed for direct access grants’}

I believe it is referring to what you said here :

“You will also need to enable the “Direct access grant” for that client in Keycloak in order for this to work. However, it’s not ideal because users will have to trust you with their credentials. You should instead set up an additional client in keycloak under the Renku realm and have your application use this client to perform an oauth2 flow to obtain the JWT token.”

Could you elaborate on this, I am unsure of the way to go from here

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [17 February 2022 10:54 UTC](https://renku.discourse.group/t/api-authentification/544/19 "2022-02-17T10:54:36Z")

</div>

No worries - by default the direct access grant (which allows retrieving JWTs based on username/password) is disabled for the renku client. But you can enable it in keycloak if you go to `Clients --> renku --> Settings` like here:

 ![image](https://global.discourse-cdn.com/free1/uploads/renku/original/1X/456a1d9e7cebea8fb220a77827d010388eeeddc9.png)

Here you can turn on the direct access grant. If you want to use your `admin` client, you can set it up in the same way and leave the default `renku` client untouched. However, in that case, you need to make sure to add the `renku` _audience_ to the client as well - you can check the “Mappers” tab in the keycloak client settings for the `renku` or `swagger` clients to see how the renku audience is set up. That’s probably the reason the token was rejected (though we should arguably give a more informative error in that case).

---

<div class="post-metadata">

**Author:** ![rrrrrok](https://yyz2.discourse-cdn.com/free1/user_avatar/renku.discourse.group/rrrrrok/32/117_2.png) [@rrrrrok](https://renku.discourse.group/u/rrrrrok)\
**Post date:** [17 February 2022 10:58 UTC](https://renku.discourse.group/t/api-authentification/544/20 "2022-02-17T10:58:40Z")

</div>

While you can set up the client in this way to obtain user JWT tokens to authenticate the API, I wouldn’t recommend this as the final solution because you will need to be responsible for user’s renku credentials. Instead you should implement the standard Authorization Code flow that @andreas linked to above. This will involve you setting up a confidential client in keycloak under the Renku realm, adding to it the renku audience, and using it from your application to authenticate users with Renku. Users will get taken to the renku login screen and then return to your app, having logged in and authorized your app to make requests to the renku API on their behalf.

---

<div class="post-metadata">

**Author:** ![erwan.beguin](https://avatars.discourse-cdn.com/v4/letter/e/d26b3c/32.png) [@erwan.beguin](https://renku.discourse.group/u/erwan.beguin)\
**Post date:** [17 February 2022 12:50 UTC](https://renku.discourse.group/t/api-authentification/544/21 "2022-02-17T12:50:32Z")

</div>

Thank you very much for your help !

I managed to have a working token and I will implement the Authorization code flow shortly

[Next page](https://renku.discourse.group/t/api-authentification/544.md?page=2)
