Microsoft Entra ID (using OpenID Connect)
Advanced
About OpenID Connect
OpenID Connect is an authentication layer built on top of OAuth 2.0 that allows applications to verify the identity of users and obtain basic profile information. It provides a standardized way for applications to authenticate users through external identity providers without requiring users to create separate accounts for each application.
When Package Manager is configured with OpenID Connect:
- Users authenticate through your organization’s identity provider (such as Okta, Microsoft Entra ID, or other OIDC-compliant providers)
- Package Manager receives identity information and group memberships from the provider
- Access to repositories and Package Manager features is controlled through scope mappings based on user roles and group memberships
- Users benefit from single sign-on (SSO) across your organization’s applications
OpenID Connect is particularly useful for organizations that want to centralize user management and provide seamless access to Package Manager without requiring separate credentials.
Package Manager can integrate with Microsoft Entra ID through the use of the OpenID Connect authentication provider.
Using this integration, user authentication is provided by Microsoft Entra ID. Group membership details can also be provided by Microsoft Entra ID for scope mapping.
Configuration example
This is an example of configuring OpenID Connect authentication with Microsoft Entra ID. You will need to modify the values to match your Entra ID application. See the Configuration section below for more details on each individual setting.
For additional information about configuring Microsoft Entra ID authorization, refer to the Microsoft documentation:
- Register an application in Microsoft Entra ID
- Configure group claims for applications by using Microsoft Entra ID
/etc/rstudio-pm/rstudio-pm.gcfg
; Address must be configured when using OpenID Connect authentication.
; Address is a public URL for this Posit Package Manager server in the format
; of http(s)://[HOST:PORT]. If Package Manager is deployed behind an HTTP proxy,
; provide the URL as seen by users through the proxy.
[Server]
Address = "https://packagemanager.example.com"
[OpenIDConnect]
Issuer = "https://login.microsoftonline.com/{tenant-id}/v2.0"
ClientId = "0ebfafe9-237f-4e38-a85b-a0e5d6c06782"
; Include a ClientSecret if your Entra ID application requires it
;ClientSecret = "<secret>"
; Force users to authenticate with Entra ID every time they sign in to
; Package Manager, rather than relying on existing sessions.
;RequireLogin = true
; Specify how long Package Manager will accept a user's authentication before
; requiring them to reauthenticate with Entra ID (defaults to 12 hours).
;MaxAuthenticationAge = "24h"
; When troubleshooting an OpenID Connect problem, more verbose logging
; is produced by uncommenting the following line:
;Logging = true
; Basic repository access for all Entra ID users. Don't include this unless you need
; to grant a default level of access to all authenticated users.
;Scope = "repos:read:*"
; Example group-based scope mapping
; Uncomment and modify based on your Entra ID groups
;[GroupToScopeMapping "PackageManager-Admins"]
;Scope = "global:admin:*"
;[GroupToScopeMapping "PackageManager-Developers"]
;Scope = "sources:write:*"
Notes on Microsoft Entra ID groups
To correctly pass group names for users within Microsoft Entra ID environments synced with on-premises Active Directory infrastructures, use the Microsoft Entra ID interface to set the Group claim to map to the source attribute of
sAMAccountName
(rather than the default ofGroup ID
).For a Microsoft Entra ID environment not synchronized with an on-premises Active Directory, the group names are not available to Package Manager over OpenID claims. This limitation restricts group-based scope mapping functionality and may require alternative approaches such as role-based mappings or manual scope assignment.
Entra ID limits the number of group names sent over OpenID claims. This number is 100 groups according to the Microsoft Entra ID documentation. If a user is a member to more than 100 groups, Package Manager cannot obtain any groups during authentication.
Configuring Authenticated Repositories
This section provides step-by-step instructions for creating and configuring authenticated repositories using OpenID Connect.
Create the authenticated repository
Create a new repository that requires authentication by running
rspm create repo
with the--authenticated
flag:Terminal
# Create an authenticated CRAN repository: rspm create repo --name=cran --description='Access CRAN packages' --authenticated rspm subscribe --repo=cran --source=cran # Create an authenticated PyPI repository: rspm create repo --name=pypi --type=python --description='Access PyPI packages' --authenticated rspm subscribe --repo=pypi --source=pypi # Create an authenticated Bioconductor repository: rspm create repo --type=bioconductor --name=bioconductor --description='Access Bioconductor packages' --authenticated
Or edit an existing repository to require authentication:
Terminal
rspm edit repo --name=cran --authenticated
Configure repository access
Users need the
repos:read
scope to access authenticated repositories. You can grant this access in several ways:Grant access to all authenticated users:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect] Scope = "repos:read:*"
Grant access based on group membership:
/etc/rstudio-pm/rstudio-pm.gcfg
[GroupToScopeMapping "PackageManager-Users"] Scope = "repos:read:cran" Scope = "repos:read:pypi" Scope = "repos:read:internal-dev"
Grant access based on roles:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect] RoleClaim = "roles" [RoleToScopeMapping "developer"] Scope = "repos:read:*"
Refer to the OpenID Connect Scope Mapping Guide for detailed examples of scope mapping configurations.
Configure client access
Instruct users to configure Python to use OpenID Connect for authentication.
WarningAs of this release, client support for R package installation from authenticated repositories using OpenID Connect is in development and is expected to be available for Posit Workbench, Posit Connect, and open source R in the near future. Token-based authentication is currently available as an alternative.
Configuration
Defining an OpenID Connect issuer
Package Manager requires metadata for the OpenID Connect identity provider that it is being integrated with. This is specified through the configuration option OpenIDConnect.Issuer
. The issuer must be an HTTPS URL and the location of the /.well-known/openid-configuration
discovery metadata for OpenID Connect.
The HTTPS certificate associated with the issuer URL must be valid and associated with a valid certificate authority. Self-signed certificates will not be accepted.
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
Issuer = "https://openid.example.com"
In the example above the metadata URL would be https://openid.example.com/.well-known/openid-configuration
Obtaining a client ID and client secret
In order for Package Manager to use OpenID Connect authentication, you will need a client ID. Some OpenID Connect providers also require a client secret.
If you want to support device authorization to allow users to authenticate from command line applications, you will need your OpenID Connect application to support device authorization. If your provider is not able to support device authorization, you can use Package Manager’s internal device authorization flow by setting the Authentication.DeviceAuthType
configuration option to internal
.
Different vendors require specific steps in order to obtain a client ID and a client secret. You will likely be asked for some information about Package Manager during this process, for example:
Application Type: “Native Application”
Redirect URL: Use your Package Manager server address with the path
/__login__/callback
(i.e.https://packagemanager.example.com/__login__/callback
).Logout URL: Use your Package Manager server address with the path
/__logout__
(i.e.https://packagemanager.example.com/__logout__
).Origin URL: Use your Package Manager server URL (i.e.
https://packagemanager.example.com
).Grant types: Authorization Code, Device Authorization.
Please consult your OpenID Connect authentication provider’s documentation for further information.
We recommend using a distinct set of credentials for each application you configure to use with OpenID Connect.
Add the client ID and secret to your configuration file as shown in the example below.
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
ClientId = "<CLIENT ID>"
ClientSecret = "<CLIENT SECRET>"
With OpenIDConnect.ClientId
and either OpenIDConnect.ClientSecret
or OpenIDConnect.ClientSecretFile
configured, you can use your account to sign in to Package Manager.
The ClientSecret
or ClientSecretFile
can be encrypted to avoid leakage of the credential. See the Property Types configuration appendix for details.
PKCE (Proof Key for Code Exchange) Configuration
PKCE is a security extension to OAuth 2.0 that helps prevent authorization code interception attacks. Package Manager provides configuration options to control PKCE usage:
OpenIDConnect.DisablePKCE
: Controls PKCE for the authorization code flowOpenIDConnect.EnableDevicePKCE
: Controls PKCE for device authorization flow
Default PKCE Behavior
By default, Package Manager:
- Enables PKCE for authorization code flows (web-based login)
- Disables PKCE for device authorization flows (command-line authentication)
Security Recommendations
For optimal security, we recommend using PKCE in all scenarios where it is supported.
Configuration Examples
For maximum security (recommended):
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
ClientId = "<CLIENT ID>"
ClientSecret = "<CLIENT SECRET>"
; PKCE is enabled by default for authorization code flow
; DisablePKCE = false ; (default)
For public clients without client secrets:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
ClientId = "<CLIENT ID>"
; No ClientSecret specified
; PKCE is enabled by default for authorization code flow
For providers that don’t support PKCE:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
ClientId = "<CLIENT ID>"
ClientSecret = "<CLIENT SECRET>"
DisablePKCE = true
For device flows with PKCE support:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
ClientId = "<CLIENT ID>"
EnableDevicePKCE = true
Some OpenID Connect providers may not support PKCE for all flow types. Consult your provider’s documentation and test your configuration thoroughly. If you encounter authentication issues, you may need to disable PKCE for specific flows.
Session Management and Reauthentication
Package Manager provides configuration options to control how user sessions are managed and when users must reauthenticate:
Require Login on Each Access
The OpenIDConnect.RequireLogin
setting forces users to authenticate with the OpenID Connect provider every time they sign in to Package Manager, rather than relying on existing sessions.
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
RequireLogin = true
When to use RequireLogin
:
- High-security environments where fresh authentication is required for each login
- Shared or public workstations where sessions should not persist
- Compliance requirements that mandate reauthentication for each session
- Testing scenarios where you need to verify authentication flows repeatedly
Enabling RequireLogin
may impact user experience as users will need to authenticate every time they sign in to Package Manager, even if they have recently authenticated.
Maximum Authentication Age
The OpenIDConnect.MaxAuthenticationAge
setting specifies how long Package Manager will accept a user’s authentication before requiring them to reauthenticate with the OpenID Connect provider.
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
MaxAuthenticationAge = "24h"
Common authentication age configurations:
1h
- High security environments, frequent reauthentication8h
- Standard work day, reauthenticate daily24h
- Moderate security, reauthenticate daily168h
(7 days) - Low security environments, weekly reauthentication
When to configure MaxAuthenticationAge
:
- Compliance requirements that specify maximum session durations
- Environments with varying security requirements based on data sensitivity
- Organizations that want to balance security with user convenience
- Scenarios where you want to ensure users reauthenticate periodically without forcing authentication on every access
The MaxAuthenticationAge
setting cannot be set to zero unless RequireLogin
is enabled. Setting MaxAuthenticationAge
to zero forces authentication on every access, which is equivalent to enabling RequireLogin
. For clarity and to avoid confusion, use RequireLogin = true
instead when you want to force authentication on every access.
Combined Session Management Example
For high-security environments, you might combine these settings:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
ClientId = "<CLIENT ID>"
ClientSecret = "<CLIENT SECRET>"
RequireLogin = false
MaxAuthenticationAge = "4h"
This configuration allows users to maintain sessions for up to 4 hours before requiring reauthentication, providing a balance between security and usability.
Global Authentication Session Settings
In addition to the OpenID Connect-specific session settings above, Package Manager has global authentication settings that control session behavior for all authentication methods:
Authentication Lifetime
The Authentication.Lifetime
setting controls the maximum duration for any authenticated session in Package Manager, regardless of activity:
/etc/rstudio-pm/rstudio-pm.gcfg
[Authentication]
Lifetime = "72h" ; Default: users must reauthenticate every 3 days
This setting acts as an absolute session limit. Even if a user remains active, they will be required to reauthenticate after this period expires.
Authentication Inactivity
The Authentication.Inactivity
setting specifies how long a session can remain idle before requiring reauthentication:
/etc/rstudio-pm/rstudio-pm.gcfg
[Authentication]
Inactivity = "24h" ; Default: idle sessions expire after 24 hours
Important interactions:
- If
Authentication.Inactivity
is greater thanAuthentication.Lifetime
, it has no effect - Set to zero (
0
) to disable inactivity-based session expiration - Inactivity is reset by user activity in Package Manager
How Session Settings Work Together
The various session settings work together to provide layered session control:
OpenIDConnect.MaxAuthenticationAge
: Controls how fresh the authentication with the OpenID Connect provider must beOpenIDConnect.RequireLogin
: Forces fresh authentication with the provider on every accessAuthentication.Lifetime
: Sets the absolute maximum session duration in Package ManagerAuthentication.Inactivity
: Expires idle sessions to reduce security exposure
Example configuration for high-security environment:
/etc/rstudio-pm/rstudio-pm.gcfg
[Authentication]
Lifetime = "8h" ; Maximum 8-hour sessions
Inactivity = "2h" ; Expire after 2 hours of inactivity
[OpenIDConnect]
MaxAuthenticationAge = "4h" ; Require fresh OIDC auth every 4 hours
RequireLogin = false ; Don't force login on every access
This example ensures users reauthenticate with the OpenID Connect provider every 4 hours, sessions expire after 2 hours of inactivity, and no session lasts longer than 8 hours regardless of activity.
Access Control and Scope Mapping
Package Manager uses scope-based access control to determine what actions users can perform. When using OpenID Connect authentication, user access is controlled through scope mappings based on:
- Base scopes: Default scopes assigned to all users of this provider via
OpenIDConnect.Scope
- Group-based scopes: Additional scopes assigned based on group membership via
GroupToScopeMapping
sections - Role-based scopes: Additional scopes assigned based on user roles via
RoleToScopeMapping
sections
Available Package Manager Scopes
Package Manager supports the following scopes for token-based access:
Scope | Description |
---|---|
global:admin |
Grants full access to manage the Package Manager server. |
sources:write:<sources> |
Grants read and write access to sources, such as uploading packages, removing packages, creating Git builders, and importing Git credentials. Access can be limited to specific sources. Replace <sources> with a comma-separated list of sources, or use * for all sources. |
repos:read:<repos> |
Grants read access to authenticated repositories. Access can be limited to specific repositories. Replace <repos> with a comma-separated list of repos, or use * for all repos. |
blocklist:admin |
Grants full access to manage the blocklist. |
blocklist:read |
Grants read access to the blocklist. |
metadata:admin |
Grants full access to manage metadata. |
Basic Scope Configuration
You can assign default scopes to all users authenticating through the OpenID Connect provider:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
Scope = "repos:read:*"
For more advanced scope mapping examples, see the OpenID Connect Scope Mapping Guide.
Customizing OpenID Connect
The Package Manager default configuration relies on standard OpenID Connect values for authentication. However, some vendors may use proprietary values. This is especially true for OpenID scopes and claims. Package Manager offers some options that allow adjusting these values to match your OpenID Connect authentication service provider.
Customizing scopes
Package Manager support for OpenID Connect relies on the standard OpenID Connect scopes openid
, email
and profile
.
You can include additional scopes if necessary by using the configuration option OpenIDConnect.CustomScope
. You should define one additional scope per line. For example:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
CustomScope = "my_custom_scope1"
CustomScope = "my_custom_scope2"
Custom scopes are generally expected by the authentication provider in order to return non-standard claims.
Customizing claims
By default, the returning JWT (JSON Web Token) IDToken
payload is expected to return the following claims:
sub
- This will be user unique identifier (UniqueID) in Package Manager. Configurable via the optionOpenIDConnect.UniqueIdClaim
.preferred_username
- This will be the user’s username in Package Manager. This value becomes thesub
claim in Package Manager tokens and is logged when the user authenticates with the token. Configurable via the optionOpenIDConnect.UsernameClaim
.groups
(optional, but default for Okta) - This will be the group memberships used for scope mapping in Package Manager. Configurable via the optionsOpenIDConnect.GroupsClaim
andOpenIDConnect.NoAutoGroupsScope
. Package Manager will not apply group-based scope mappings if not present or blank.
Package Manager does not store (apart from logging) user profile information like username, first name, last name, or email address from OpenID Connect tokens. Information from the ID token is only used for authentication and authorization. Username and email information may be recorded in some logs.
Additional OpenID Connect options
In the event that a claim cannot present groups as a list of distinct values, you may use the OpenIDConnect.GroupsSeparator
setting to specify a separator string that will be used to split a single value into a list. For example, if the groups attribute contains a value of the form, group_1|group_2
, set:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
GroupsSeparator = "|"
Similarly, for role claims, you can use OpenIDConnect.RolesSeparator
:
/etc/rstudio-pm/rstudio-pm.gcfg
[OpenIDConnect]
RolesSeparator = "|"
For detailed examples of scope mapping configurations, see the OpenID Connect Scope Mapping Guide.