Skip to content

add 'as' parameter to getDelegatedAzureToken()#328

Open
kevinushey wants to merge 1 commit into
mainfrom
feature/delegated-azure-token-as
Open

add 'as' parameter to getDelegatedAzureToken()#328
kevinushey wants to merge 1 commit into
mainfrom
feature/delegated-azure-token-as

Conversation

@kevinushey

Copy link
Copy Markdown
Contributor

Addresses rstudio/rstudio#17619.

Summary

getDelegatedAzureToken() gains an as = c("list", "AzureToken") parameter. The default ("list") is unchanged. With as = "AzureToken", the token is wrapped in an R6 object compatible with the AzureToken class from the AzureAuth package, so it can be passed directly to packages like AzureGraph and Microsoft365R:

token <- getDelegatedAzureToken("https://graph.microsoft.com/", as = "AzureToken")
gr <- AzureGraph::ms_graph$new(token = token)
site <- Microsoft365R::get_sharepoint_site(
  site_url = "https://example.sharepoint.com/sites/my-site",
  token = token
)

Design notes

  • The wrapper is a standalone R6 class with class name AzureToken, so it passes AzureAuth::is_azure_token() without requiring AzureAuth to be installed. Only R6 is needed (added to Suggests), and only for the as = "AzureToken" path.
  • It exposes the surface those packages actually use: credentials (with token_type, access_token, and expires_on), version = 1 with resource set (so AzureGraph::find_resource_host() can parse the host), plus validate(), can_refresh(), refresh(), hash(), cache(), and print().
  • refresh() simply re-calls getDelegatedAzureToken(): Workbench owns the OIDC refresh token and performs a fresh token refresh server-side on every request, so auto-refresh in long-running AzureGraph sessions works without exposing any client credentials to the session.
  • Also fixes a pre-existing inconsistency: the direct Workbench RPC path (non-RStudio IDEs) returned the raw token endpoint response with a relative expires_in, while RStudio sessions returned an absolute expires_at. Both paths now return expires_at.

The diff includes cosmetic regeneration of unrelated man/*.Rd files from the roxygen2 8.0.0 update picked up by devtools::document().

Testing

  • New tests cover as validation, expires_in normalization, the AzureToken interface surface, expiry validation, and refresh (via local_mocked_bindings).
  • Full suite passes: 39 pass, 0 fail, 1 pre-existing skip.

With as = "AzureToken", the token is wrapped in an R6 object compatible
with the AzureToken class from the AzureAuth package, so it can be passed
directly to packages like AzureGraph and Microsoft365R. The object's
refresh() method requests a new delegated token from Workbench.

Also normalizes the token shape across IDEs: the direct Workbench RPC
path now converts the relative 'expires_in' to an absolute 'expires_at',
matching what RStudio sessions already returned.

Addresses rstudio/rstudio#17619.

@zachhannum zachhannum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome, LGTM! I think we should update the example(s) in our docs once this lands: https://docs.posit.co/ide/server-pro/user/posit-workbench/managed-credentials/azure.html#microsoft-graph-api

The current Graph example chickens out and just calls the API directly 😆

@lindsay-lintelman

Copy link
Copy Markdown

This is awesome, LGTM! I think we should update the example(s) in our docs once this lands: https://docs.posit.co/ide/server-pro/user/posit-workbench/managed-credentials/azure.html#microsoft-graph-api

The current Graph example chickens out and just calls the API directly 😆

@zachhannum FYI I made a draft PR here for the doc update: https://github.com/rstudio/rstudio-pro/pull/11390

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants