Conversation
3517a65 to
f26af60
Compare
f26af60 to
e86d80a
Compare
| token = cachedApiKey, | ||
| private_key = secret(""), | ||
| # Open a special "you're already authenticated" page as the "claim URL". | ||
| claim_url = sub("/__api__$", "/connect/#/auth-success", serverUrl), |
There was a problem hiding this comment.
Just confirming we know that serverUrl does not have a trailing slash?
There was a problem hiding this comment.
Also I thought the convention was that the success page was served by localhost, no?
There was a problem hiding this comment.
I'm pretty sure that that URL is normalized beforehand, yes.
And as for a locally-served page: we could do that, but it's dramatically more complicated and would require additional dependencies. I added this static success page to the Connect server this week instead.
| # Attempt exchange an identity token sourced from Posit Workbench for an | ||
| # ephemeral Connect API key. Returns NULL if this exchange fails or an API key | ||
| # otherwise. | ||
| attemptIdentityFederation <- function(serverUrl) { |
There was a problem hiding this comment.
I can trace through the R code to see where the argument comes from, but where exactly does serverUrl originate? Is it pulling from a workbench setting in this case? Or does the user have to know and specify the Connect server URL?
There was a problem hiding this comment.
They have to know it, though it does get validated in various places so internally at this point we can be sure it's an actual Connect URL.
e86d80a to
fe95320
Compare
This commit teaches rsconnect to automatically exchange a Posit Workbench user's identity token (if there is one) for an ephemeral Connect API key using the server's token exchange endpoint. This enables Workbench users to authenticate without the need to configure API keys or go through the token auth flow, provided that identity federation has been configured on the Connect server side. All of this is opportunistic, falling back to existing paths if there is no token or if the Connect server won't accept it. The majority of the complexity in the implementation is due to the fact that we want to be as backward compatible with RStudio as possible, and RStudio very much expects to run the user through the token auth flow. Finally, note that we're using the brand new `rstudioapi::getIdentityToken()` here, so this needs a version bump for the `rstudioapi` dependency. Unit tests are included. Part of posit-dev/connect#28149. Signed-off-by: Aaron Jacobs <aaron.jacobs@posit.co>
fe95320 to
951eb40
Compare
| } | ||
|
|
||
| # For standard Connect servers where there are no persisted credentials, try | ||
| # identity federation (added in v2026.01.0). |
There was a problem hiding this comment.
Would there be any value here in trying to determine the version of the connect server before attempting identity federation? I guess the end result is the same (no successful auth) - and maybe its more complicated to try to determine the server version vs just relying on sensible error handling.
There was a problem hiding this comment.
I kind of felt like that would complicate things, especially because we also don't know if identity federation is actually enabled on this server or whether it has an integration configured for Workbench. Not a lot to be gained by being clever about just the version.
| private_key = NULL, | ||
| apiKey = NULL | ||
| ) { | ||
| # Detect when the "token" is actually an API key by looking for an empty |
There was a problem hiding this comment.
I know you called out why this is required above - but it remains unfortunate :(
|
I'm not an R expert, but to me this all makes sense and looks good. Especially given that @atheriel has been battle-testing this for awhile now, and that it has solid test coverage, I think it makes sense to merge. |
This commit teaches rsconnect to automatically exchange a Posit Workbench user's identity token (if there is one) for an ephemeral Connect API key using the server's token exchange endpoint.
This enables Workbench users to authenticate without the need to configure API keys or go through the token auth flow, provided that identity federation has been configured on the Connect server side.
All of this is opportunistic, falling back to existing paths if there is no token or if the Connect server won't accept it.
The majority of the complexity in the implementation is due to the fact that we want to be as backward compatible with RStudio as possible, and RStudio very much expects to run the user through the token auth flow.
Finally, note that we're using the brand new
rstudioapi::getIdentityToken()here, so this needs a version bump for therstudioapidependency.Unit tests are included.
Part of https://github.com/posit-dev/connect/issues/28149.