405 status on POST api endpoints

I am currently working on a third party app using the renku api to upload files and datasets on a private renku instance.

I was able to implement an authentication workflow and managed to retrieve a working token for a given user. The endpoint api/user is working for this token, passed via a ‘Authorization : Bearer token’ header.

However, using the same authorization header, many POST methods fail with a “405 method not allowed” error.
In particular, I am trying to use two specific endpoints :

  • ‘/renku/datasets.import’
  • /renku/cache.files_upload’

Both of them are failing even with a correct authorization header.

Am I missing something so that a regular user is able to use these endpoints ? Are those endpoints limited to special users ?

1 Like

Any authorized user should be able to use those endpoints, so I suspect the problem is elsewhere, and the API around datasets is admittedly not the easiest to use.

Have you tried interacting with that API via Swagger? Your instance should give you access to the swagger documentation at https://[url-for-renkulab]/swagger/

There is an authorize button towards the top of the page.

Click that and then select oidc (OAuth2, authorization_code with PKCE) in the popup and then you make make authorized invocations against the Renku API.

Try out your flow there, and see if still have the same problems.

Via Swagger the datasets.import endpoint gives me an error 500, so there is something else going on indeed.

I’m guessing I have to check renku’s logs to see what is going on exactly, however is there something I must look out for when using those endpoints ?

The best way to see the error would be to check sentry, if you have sentry deployed and the core-service configured to report to sentry.

You mentioned /renku/cache.files_upload and there indeed you’d get a 405 method not allowed on POST, because the endpoint is /api/renku/cache.files_upload, without the /api you’re essentially trying to post to the Homepage itself instead of the API.

We do have a new release that improves error responses from the core-service to make them more actionable. But that is fresh off the press, we haven’t deployed it to our production yet, either.

After investigation, I managed to get this error message when using the /api/renku/datasets.import endpoint :

error “origin not allowed: “my third party app domain” not matching [‘my renku server domain’]”

But I did setup CORS correctly on my renku server

Indeed, the status code is now a 403 Forbidden however

Is there a way you could show us the CORS configuration?

Via the renku-gateway configuration file, on the GATEWAY_ALLOW_ORIGIN variable

renku-connector is our third party app, our renku serveur is https://renku.k.orion.cloud.inrae.fr

allowOrigin: - http://renku-connector.k.orion.cloud.inrae.fr - https://renku-connector.k.orion.cloud.inrae.fr

The CORS header looks to be correct on that deployment (It’s sent correctly when I curl the API endpoint), so that looks fine.

I tried to register an account to look into the issue you’re having but registration failed. Could be there’s an issue with Keycloak?

403 sounds like the token is wrong or the user has no access to the repository. Or could it be the token has expired? Do you see anything in Sentry?

It’s a possibility that the registration is locked as our renku server is integrated within a bigger authentication structure. However there is indeed an error 500 on login, even though the user is successfully logged in. If the user go back to the root URL, they can use renku normally.

We are currently exploring Sentry to confirm whether or not if Keycloak is the problem. At the very least, it is not because the token is expired as we are generating it just before the target endpoint.

Hi @erwan.beguin, a few more tips that could help us figure this out.

Most likely the problem is with keycloak or the gateway. Checking Sentry will help you get information mostly about the core service. I recommend you check the following pod logs and report back what you see:

  • keycloak: kubectl -n <renku-namespace> logs XXXX-renku-keycloak-0
  • gateway: kubectl -n <renku-namespace> logs XXXX-renku-gateway-auth-XXXXX

Also have you been able to resolve this message you posted about earlier: error “origin not allowed: “my third party app domain” not matching [‘my renku server domain’]”?

Another thing that you could share is the configuration of the client you are using with keycloak. I am assuming that you registered a new client in keycloak to use with your application? If you can share the configuration for that (with any sensitive data removed) that would be helpful.

Sorry for the delay, here’s the logs on the gateway :

[2022-05-04 12:02:43,036] DEBUG in __init__: Hitting gateway auth with args: ImmutableMultiDict([('auth', 'renku')]) [2022-05-04 12:02:43,040] WARNING in web: The user does not have backend access tokens. NoneType: None

Is there a way to have said backend access token ?

Hi @erwan.beguin - this simply means that the user is probably not logged in to the platform (the backend is trying to do something on the user’s behalf but the token is either expired or missing). So if the user logs in the error should go away.

@erwan.beguin our swagger page is not fully configured properly. So if your requests are failing like this when you make them through the swagger page then simply visiting the page where renku is deployed and logging in (as Rok said) will then afterward allow you to successfully make requests from swagger. Just make sure you visit renku from the same browser window as where you are trying to use swagger.

If you are getting this message when you make a request from the app you are developing then it means that you either have not inserted the token in the request, or you have inserted the token in the wrong place. The access token is expected to be in the header for the request under the key Authorization and the value is supposed to be bearer followed by a space and then followed by the token value.

In my development deployment of Renku to get requests from the swagger page to fully work I have to do the following:

  1. Click authorize on the swagger page
  2. Select the OAuth2, authorization_code with PKCE flow, the openid scope and then click authorize
  3. Log into Renku
  4. Open a new tab in the same browser window and visit the renku website and log in fully
  5. Go back to the swagger tab and things will work

We will look into why this is occurring with our swagger page and correct it. But for now hopefully this workaround helps.

This is only affecting the swagger page - it will not affect the app you are developing.

This is a problem for our use case as the user should be able to use this API on our third party app before being redirected to the renku server.

Is there a way to bypass this ?

The API is being used in a third party app that we are developing. Swagger is not part of this development except at the beginning of the development to understand the API.

The logs I posted were a consequence of testing on our third party app, not because of Swagger.

Secondly, our use case for this app states that the user should be able to visit our third party app (which is using Renku’s API) BEFORE logging into renku directly.

Is there a way to prevent that ?

1 Like

Hello @erwan.beguin ,

I fear we currently require the user to visit our login page on the gateway component. That is needed to acquire OAuth tokens from the 3rd party components we use, like GitLab.

If you are logging in through the browser, once you have acquired a valid KeyCloak token, you can redirect the user to <renku_url>/api/auth/login to complete the tokens acquisition phase. That requires passing a redirect_url parameter. The browser will go through the GitLab login page and redirect you back to the URL you passed.

You can see an example of this flow in the UI-server, a lean backend we use to store KeyCloak tokens for our web application. If you check the flow in the browser on the network tab (E.G. logging in into renkulab.io), you will see the endpoints it goes through. There will be a couple of /api/auth/login and /api/auth/next routes, and then it goes back to the URL originally passed as redirect_url – mind that you will see the session cookie instead of authentication headers.