Authentication in Red Hat Developer Hub
Configuring authentication to external services in Red Hat Developer Hub
Abstract
1. Understanding authentication and user provisioning
This module provides an overview of how authentication and user provisioning function within Red Hat Developer Hub. Learn about the process from creating user and group entities in the software catalog to user sign-in, and how authentication and catalog plugins enable each step. Understanding this process is essential for successfully configuring your Developer Hub instance, securing access through authorization, and enabling features that rely on synchronized user and group data.
To fully enable catalog features, provision user and group data from the Identity Provider to the Developer Hub software catalog. Catalog provider plugins handle this task asynchronously. These plugins query the Identity Provider (IdP) for relevant user and group information, and create or update corresponding entities in the Developer Hub catalog. Scheduled provisioning ensures that the catalog accurately reflects the users and groups in your organization.
When a user attempts to access Developer Hub, Developer Hub redirects them to a configured authentication provider, such as Red Hat Build of Keycloak (RHBK), GitHub, or Microsoft Azure. This external IdP is responsible for authenticating the user.
On successful authentication, the Developer Hub authentication plugin, configured in your app-config.yaml
file, processes the response from the IdP, resolves the identity in the Developer Hub software catalog, and establishes a user session within Developer Hub.
Configuring authentication and user provisioning is critical for several reasons.
- It secures your Developer Hub instance by ensuring only authenticated users can gain access.
- It enables authorization by allowing you to define access controls based on user and group memberships synchronized from your IdP.
- Provisioning user and group data to the catalog is necessary for various catalog features that rely on understanding entity ownership and relationships between users, groups, and software components. Without this provisioning step, features like displaying who owns a component in the catalog may not function correctly.
To explore Developer Hub features, you can:
- To use Developer Hub without external IdP, enable the guest user to skip configuring authentication and authorization, log in as the guest user, and access all Developer Hub features.
-
To use Developer Hub without authorization policies and features relying on the software catalog, you can enable the
dangerouslyAllowSignInWithoutUserInCatalog
resolver option. This setting bypasses the check requiring a user to be in the catalog but still enforces authentication.
Developer Hub uses a one-way synchronization model, where user and group data flow from your Identity Provider to the Developer Hub software catalog. As a result, deleting users or groups manually through the Developer Hub Web UI or REST API might be ineffective or cause inconsistencies, since those entities will be recreated during the next ingestion.
2. Authenticating with the Guest user
To explore Developer Hub features, you can skip configuring authentication and authorization. You can configure Developer Hub to log in as a Guest user and access Developer Hub features.
2.1. Authenticating with the Guest user on an Operator-based installation
After an Operator-based installation, you can configure Developer Hub to log in as a Guest user and access Developer Hub features.
Prerequisites
- You installed Developer Hub by using the Operator.
- You added a custom Developer Hub application configuration, and have sufficient permissions to modify it.
Procedure
To enable the guest user in your Developer Hub custom configuration, edit your Developer Hub application configuration with following content:
app-config.yaml
fragmentauth: environment: development providers: guest: dangerouslyAllowOutsideDevelopment: true
Verification
- Go to the Developer Hub login page.
- To log in with the Guest user account, click Enter in the Guest tile.
- In the Developer Hub Settings page, your profile name is Guest.
- You can use Developer Hub features.
2.2. Authenticating with the Guest user on a Helm-based installation
On a Helm-based installation, you can configure Developer Hub to log in as a Guest user and access Developer Hub features.
Prerequisites
- You added a custom Developer Hub application configuration, and have sufficient permissions to modify it.
- You use the Red Hat Developer Hub Helm chart to run Developer Hub.
Procedure
To enable the guest user in your Developer Hub custom configuration, configure your Red Hat Developer Hub Helm Chart with following content:
Red Hat Developer Hub Helm Chart configuration fragment
upstream: backstage: appConfig: app: baseUrl: 'https://{{- include "janus-idp.hostname" . }}' auth: environment: development providers: guest: dangerouslyAllowOutsideDevelopment: true
Verification
- Go to the Developer Hub login page.
- To log in with the Guest user account, click Enter in the Guest tile.
- In the Developer Hub Settings page, your profile name is Guest.
- You can use Developer Hub features.
3. Authenticating with Red Hat Build of Keycloak (RHBK)
To authenticate users with Red Hat Build of Keycloak (RHBK):
3.1. Enabling user authentication with Red Hat Build of Keycloak (RHBK)
To authenticate users with Red Hat Build of Keycloak (RHBK), enable and configure the OpenID Connect (OIDC) authentication provider in Red Hat Developer Hub and provision the users and groups from RHBK to the Developer Hub software catalog.
Prerequisites
- You added a custom Developer Hub application configuration, and have sufficient permissions to modify it.
- You have sufficient permissions in RHSSO to create and manage a realm. Alternatively, you can ask your RHBK administrator to prepare the required RHBK App.
Procedure
To allow Developer Hub to authenticate with RHBK, complete the steps in RHBK, to create a realm and a user and secure the first application:
Use an existing realm, or create a realm, with a distinctive Name such as <my_realm>. Save the value for the next step:
- RHBK realm base URL, such as: <your_rhbk_URL>/realms/<your_realm>.
To register your Developer Hub in RHBK, in the created realm, secure the first application, with:
- Client ID: A distinctive client ID, such as <RHDH>.
-
Valid redirect URIs: Set to the OIDC handler URL:
https://<RHDH_URL>/api/auth/oidc/handler/frame
. - Navigate to the Credentials tab and copy the Client secret.
Save the values for the next step:
- Client ID
- Client Secret
- To prepare for the verification steps, in the same realm, get the credential information for an existing user or create a user. Save the user credential information for the verification steps.
To add your RHSSO credentials to Developer Hub, add the following key/value pairs to your Developer Hub secrets. You can use these secrets in the Developer Hub configuration files by using their respective environment variable name.
AUTHENTICATION_OIDC_CLIENT_ID
- Enter the saved Client ID.
AUTHENTICATION_OIDC_CLIENT_SECRET
- Enter the saved Client Secret.
AUTHENTICATION_OIDC_METADATA_URL
- Enter the saved RHBK realm base URL.
Enable the Keycloak organization plugin (
backstage-plugin-catalog-backend-module-keycloak-dynamic
). The plugin is named after RHBK upstream project. This plugin ingests RHBK users and groups to the Developer Hub software catalog.dynamic-plugins.yaml
file fragmentplugins: - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-keycloak-dynamic' disabled: false
To provision RHBK users and groups to the Developer Hub software catalog, add the
catalog.providers.keycloakOrg
section to your custom Developer Hubapp-config.yaml
configuration file:app-config.yaml
fragment with mandatorykeycloakOrg
fieldscatalog: providers: keycloakOrg: default: baseUrl: ${AUTHENTICATION_OIDC_METADATA_URL} clientId: ${AUTHENTICATION_OIDC_CLIENT_ID} clientSecret: ${AUTHENTICATION_OIDC_CLIENT_SECRET}
baseUrl
- Your RHBK server URL, defined when enabling authentication with RHBK.
clientId
- Your Developer Hub application client ID in RHBK, defined when enabling authentication with RHBK.
clientSecret
- Your Developer Hub application client secret in RHBK, defined when enabling authentication with RHBK.
Optional: Consider adding the following optional fields:
realm
Realm to synchronize. Default value:
master
.app-config.yaml
fragment with optionalrealm
fieldcatalog: providers: keycloakOrg: default: realm: master
loginRealm
Realm used to authenticate. Default value:
master
.app-config.yaml
fragment with optionalloginRealm
fieldcatalog: providers: keycloakOrg: default: loginRealm: master
userQuerySize
User number to query simultaneously. Default value:
100
.app-config.yaml
fragment with optionaluserQuerySize
fieldcatalog: providers: keycloakOrg: default: userQuerySize: 100
groupQuerySize
Group number to query simultaneously. Default value:
100
.app-config.yaml
fragment with optionalgroupQuerySize
fieldcatalog: providers: keycloakOrg: default: groupQuerySize: 100
schedule.frequency
To specify custom schedule frequency. Supports cron, ISO duration, and "human duration" as used in code.
app-config.yaml
fragment with optionalschedule.frequency
fieldcatalog: providers: keycloakOrg: default: schedule: frequency: { hours: 1 }
schedule.timeout
To specify custom timeout. Supports ISO duration and "human duration" as used in code.
app-config.yaml
fragment with optionalschedule.timeout
fieldcatalog: providers: keycloakOrg: default: schedule: timeout: { minutes: 50 }
schedule.initialDelay
To specify custom initial delay. Supports ISO duration and "human duration" as used in code.
app-config.yaml
fragment with optionalschedule.initialDelay
fieldcatalog: providers: keycloakOrg: default: schedule: initialDelay: { seconds: 15}
To set up the RHBK authentication provider in your Developer Hub custom configuration, edit your custom Developer Hub ConfigMap such as
app-config-rhdh
, and add the following lines to theapp-config.yaml
content:Configure mandatory fields:
app-config.yaml
fragment with mandatory fields to enable authentication with RHBKauth: environment: production providers: oidc: production: metadataUrl: ${AUTHENTICATION_OIDC_METADATA_URL} clientId: ${AUTHENTICATION_OIDC_CLIENT_ID} clientSecret: ${AUTHENTICATION_OIDC_CLIENT_SECRET} prompt: auto signInPage: oidc
environment: production
-
Mark the environment as
production
to hide the Guest login in the Developer Hub home page. metadataUrl
,clientId
,clientSecret
- To configure the OIDC provider with your secrets.
sigInPage: oidc
- To enable the OIDC provider as default sign-in provider.
prompt: auto
- To allow the identity provider to automatically determine whether to prompt for credentials or bypass the login redirect if an active RHSSO session exists.
If prompt: auto
is not set, the identity provider defaults to prompt: none
, which assumes that you are already logged in and rejects sign-in requests without an active session.
callbackUrl
RHBK callback URL.
app-config.yaml
fragment with optionalcallbackURL
fieldauth: providers: oidc: production: callbackUrl: ${AUTHENTICATION_OIDC_CALLBACK_URL}
tokenEndpointAuthMethod
Token endpoint authentication method.
app-config.yaml
fragment with optionaltokenEndpointAuthMethod
fieldauth: providers: oidc: production: tokenEndpointAuthMethod: ${AUTHENTICATION_OIDC_TOKEN_ENDPOINT_METHOD}
tokenSignedResponseAlg
Token signed response algorithm.
app-config.yaml
fragment with optionaltokenSignedResponseAlg
fieldauth: providers: oidc: production: tokenSignedResponseAlg: ${AUTHENTICATION_OIDC_SIGNED_RESPONSE_ALG}
scope
RHBK scope.
app-config.yaml
fragment with optionalscope
fieldauth: providers: oidc: production: scope: ${AUTHENTICATION_OIDC_SCOPE}
signIn
resolvers
After successful authentication, the user signing in must be resolved to an existing user in the Developer Hub catalog. To best match users securely for your use case, consider configuring a specific resolver. Enter the resolver list to override the default resolver:
oidcSubClaimMatchingKeycloakUserId
.The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed.
WarningIn production mode, only configure one resolver to ensure users are securely matched.
resolver
Enter the sign-in resolver name. Available values:
oidcSubClaimMatchingKeycloakUserId
:Matches the user with the immutable
sub
parameter from OIDC to the RHBK user ID. Consider using this resolver for enhanced security.emailLocalPartMatchingUserEntityName
:Matches the email local part with the user entity name.
emailMatchingUserEntityProfileEmail
:Matches the email with the user entity profile email.
preferredUsernameMatchingUserEntityName
:Matches the preferred username with the user entity name.
app-config.yaml
fragment with optionalresolvers
listauth: providers: oidc: production: signIn: resolvers: - resolver: oidcSubClaimMatchingKeycloakUserId - resolver: preferredUsernameMatchingUserEntityName - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName
dangerouslyAllowSignInWithoutUserInCatalog: true
Configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.
WarningUse this option to explore Developer Hub features, but do not use it in production.
app-config-rhdh.yaml
fragment with optional field to allow signing in users absent from the software catalogauth: environment: production providers: oidc: production: metadataUrl: ${AUTHENTICATION_OIDC_METADATA_URL} clientId: ${AUTHENTICATION_OIDC_CLIENT_ID} clientSecret: ${AUTHENTICATION_OIDC_CLIENT_SECRET} signIn: resolvers: - resolver: oidcSubClaimMatchingKeycloakUserID dangerouslyAllowSignInWithoutUserInCatalog: true signInPage: oidc
sessionDuration
Lifespan of the user session. Enter a duration in
ms
library format (such as '24h', '2 days'), ISO duration, or "human duration" as used in code.app-config-rhdh.yaml
fragment with optionalsessionDuration
fieldauth: providers: github: production: sessionDuration: { hours: 24 }
auth
backstageTokenExpiration
- To modify the Developer Hub token expiration from its default value of one hour, note that this refers to the validity of short-term cryptographic tokens, not the session duration. The expiration value must be set between 10 minutes and 24 hours.
.
app-config.yaml
fragment with optionalauth.backstageTokenExpiration
fieldauth: backstageTokenExpiration: { minutes: <user_defined_value> }
Security considerationIf multiple valid refresh tokens are issued due to frequent refresh token requests, older tokens will remain valid until they expire. To enhance security and prevent potential misuse of older tokens, enable a refresh token rotation strategy in your RHBK realm.
- From the Configure section of the navigation menu, click Realm Settings.
- From the Realm Settings page, click the Tokens tab.
- From the Refresh tokens section of the Tokens tab, toggle the Revoke Refresh Token to the Enabled position.
Verification
To verify user and group provisioning, check the console logs.
Successful synchronization example:
{"class":"KeycloakOrgEntityProvider","level":"info","message":"Read 3 Keycloak users and 2 Keycloak groups in 1.5 seconds. Committing...","plugin":"catalog","service":"backstage","taskId":"KeycloakOrgEntityProvider:default:refresh","taskInstanceId":"bf0467ff-8ac4-4702-911c-380270e44dea","timestamp":"2024-09-25 13:58:04"} {"class":"KeycloakOrgEntityProvider","level":"info","message":"Committed 3 Keycloak users and 2 Keycloak groups in 0.0 seconds.","plugin":"catalog","service":"backstage","taskId":"KeycloakOrgEntityProvider:default:refresh","taskInstanceId":"bf0467ff-8ac4-4702-911c-380270e44dea","timestamp":"2024-09-25 13:58:04"}
To verify RHBK user authentication:
- Go to the Developer Hub login page.
- Your Developer Hub sign-in page displays Sign in using OIDC and the Guest user sign-in is disabled.
- Log in with OIDC by using the saved Username and Password values.
3.2. Creating a custom transformer to provision users from Red Hat Build of Keycloak (RHBK) to the software catalog
To customize how RHBK users and groups are mapped to Red Hat Developer Hub entities, you can create a backend module that uses the keycloakTransformerExtensionPoint
to provide custom user and group transformers for the Keycloak backend.
Prerequisites
Procedure
-
Create a new backend module with the
yarn new
command. Add your custom user and group transformers to the
keycloakTransformerExtensionPoint
.The following is an example of how the backend module can be defined:
plugins/<module-name>/src/module.ts
import { GroupTransformer, keycloakTransformerExtensionPoint, UserTransformer, } from '@backstage-community/plugin-catalog-backend-module-keycloak'; const customGroupTransformer: GroupTransformer = async ( entity, // entity output from default parser realm, // Keycloak realm name groups, // Keycloak group representation ) => { /* apply transformations */ return entity; }; const customUserTransformer: UserTransformer = async ( entity, // entity output from default parser user, // Keycloak user representation realm, // Keycloak realm name groups, // Keycloak group representation ) => { /* apply transformations */ return entity; }; export const keycloakBackendModuleTransformer = createBackendModule({ pluginId: 'catalog', moduleId: 'keycloak-transformer', register(reg) { reg.registerInit({ deps: { keycloak: keycloakTransformerExtensionPoint, }, async init({ keycloak }) { keycloak.setUserTransformer(customUserTransformer); keycloak.setGroupTransformer(customGroupTransformer); /* highlight-add-end */ }, }); }, });
ImportantThe module’s
pluginId
must be set tocatalog
to match thepluginId
of thekeycloak-backend
; otherwise, the module fails to initialize.Install this new backend module into your Developer Hub backend.
backend.add(import(backstage-plugin-catalog-backend-module-keycloak-transformer))
Verification
Developer Hub imports the users and groups each time when started. Check the console logs to verify that the synchronization is completed.
Successful synchronization example:
{"class":"KeycloakOrgEntityProvider","level":"info","message":"Read 3 Keycloak users and 2 Keycloak groups in 1.5 seconds. Committing...","plugin":"catalog","service":"backstage","taskId":"KeycloakOrgEntityProvider:default:refresh","taskInstanceId":"bf0467ff-8ac4-4702-911c-380270e44dea","timestamp":"2024-09-25 13:58:04"} {"class":"KeycloakOrgEntityProvider","level":"info","message":"Committed 3 Keycloak users and 2 Keycloak groups in 0.0 seconds.","plugin":"catalog","service":"backstage","taskId":"KeycloakOrgEntityProvider:default:refresh","taskInstanceId":"bf0467ff-8ac4-4702-911c-380270e44dea","timestamp":"2024-09-25 13:58:04"}
- After the first import is complete, navigate to the Catalog page and select User to view the list of users.
- When you select a user, you see the information imported from RHBK.
- You can select a group, view the list, and access or review the information imported from RHBK.
- You can log in with an RHBK account.
4. Enabling user authentication with GitHub
To authenticate users with GitHub, configure the GitHub authentication provider in Red Hat Developer Hub and provision the users and groups from GitHub to the Developer Hub software catalog.
Prerequisites
- You added a custom Developer Hub application configuration, and have sufficient permissions to modify it.
- You have sufficient permissions in GitHub to create and manage a GitHub App. Alternatively, you can ask your GitHub administrator to prepare the required GitHub App.
Procedure
To allow Developer Hub to authenticate with GitHub, create a GitHub App. Opt for a GitHub App instead of an OAuth app to use fine-grained permissions and use short-lived tokens.
Register a GitHub App with the following configuration:
- GitHub App name
-
Enter a unique name identifying your GitHub App, such as
authenticating-with-rhdh-<GUID>
. - Homepage URL
-
Enter your Developer Hub URL:
https://<my_developer_hub_url>
. - Authorization callback URL
-
Enter your Developer Hub authentication backend URL:
https://<my_developer_hub_url>/api/auth/github/handler/frame
. - Webhook
- Clear "Active", as this is not needed for authentication and catalog providers.
- Organization permissions
-
Enable
Read-only
access to Members. - Where can this GitHub App be installed?
-
Select
Only on this account
.
- In the General → Clients secrets section, click Generate a new client secret.
- In the Install App tab, choose an account to install your GitHub App on.
Save the following values for the next step:
- Client ID
- Client secret
To add your GitHub credentials to Developer Hub, add the following key/value pairs to your Developer Hub secrets. You can use these secrets in the Developer Hub configuration files by using their respective environment variable name.
AUTHENTICATION_GITHUB_CLIENT_ID
- Enter the saved Client ID.
AUTHENTICATION_GITHUB_CLIENT_SECRET
- Enter the saved Client Secret.
AUTHENTICATION_GITHUB_HOST_DOMAIN
-
Enter the GitHub host domain:
github.com
. AUTHENTICATION_GITHUB_ORGANIZATION
-
Enter your GitHub organization name, such as
<your_github_organization_name>
.
Enable the GitHub organization provisioning plugin (
backstage-plugin-catalog-backend-module-github-org
). This plugin ingests GitHub users and groups to the Developer Hub software catalog.dynamic-plugins.yaml
file fragmentplugins: - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org' disabled: false
To provision GitHub users and groups to the Developer Hub software catalog, add the
catalog.providers.githubOrg
section to your custom Developer Hubapp-config.yaml
configuration file:app-config.yaml
fragment with mandatorycatalog.providers.githubOrg
fieldscatalog: providers: githubOrg: id: githuborg githubUrl: "${AUTHENTICATION_GITHUB_HOST_DOMAIN}" orgs: [ "${AUTHENTICATION_GITHUB_ORGANIZATION}" ] schedule: frequency: minutes: 30 initialDelay: seconds: 15 timeout: minutes: 15
id
-
Enter a stable identifier for this provider, such as
githuborg
. Entities from this provider are associated with this identifier, therefore you must take care not to change it over time since that might lead to orphaned entities and/or conflicts. githubUrl
-
Enter the configured secret variable name:
${AUTHENTICATION_GITHUB_HOST_DOMAIN}
. orgs
-
Enter the configured secret variable name:
${AUTHENTICATION_GITHUB_ORGANIZATION}
. schedule.frequency
- Enter your schedule frequency, in the cron, ISO duration, or "human duration" format.
schedule.timeout
- Enter your schedule timeout, in the ISO duration or "human duration" format.
schedule.initialDelay
- Enter your schedule initial delay, in the ISO duration or "human duration" format.
To set up the GitHub authentication provider, add the
auth.providers.github
section to theapp-config.yaml
file content:app-config.yaml
file fragment with mandatory fields to enable authentication with GitHubauth: environment: production providers: github: production: clientId: ${AUTHENTICATION_GITHUB_CLIENT_ID} clientSecret: ${AUTHENTICATION_GITHUB_CLIENT_SECRET} signInPage: github
environment
-
Enter
production
to disable the Guest login option in the Developer Hub login page. clientId
-
Enter the configured secret variable name:
${AUTHENTICATION_GITHUB_CLIENT_ID}
. clientSecret
-
Enter the configured secret variable name:
${AUTHENTICATION_GITHUB_CLIENT_SECRET}
. signInPage
-
Enter
github
to enable the GitHub provider as your Developer Hub sign-in provider.
Optional: Consider adding the following optional fields:
app-config.yaml
file fragment including optional fields to enable authentication with GitHubauth: environment: production providers: github: production: clientId: ${AUTHENTICATION_GITHUB_CLIENT_ID} clientSecret: ${AUTHENTICATION_GITHUB_CLIENT_SECRET} callbackUrl: <your_intermediate_service_url/handler> sessionDuration: { hours: 24 } signIn: resolvers: - resolver: usernameMatchingUserEntityName dangerouslyAllowSignInWithoutUserInCatalog: true signInPage: github
callbackUrl
- Enter the callback URL that GitHub uses when initiating an OAuth flow, such as: <your_intermediate_service_url/handler>. Define it when Developer Hub is not the immediate receiver, such as in cases when you use one OAuth app for many Developer Hub instances.
sessionDuration
-
Enter the user session lifespan, in
ms
library format (such as '24h', '2 days'), ISO duration, or "human duration". signIn
resolvers
- After successful authentication, Developer Hub resolves the user signing in to an existing user in the Developer Hub catalog. To best match users securely for your use case, consider configuring a specific resolver.
Enter the resolver list to override the default resolver:
usernameMatchingUserEntityName
.The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed.
WarningIn production mode, only configure one resolver to ensure users are securely matched.
resolver
Enter the sign-in resolver name. Available resolvers:
-
usernameMatchingUserEntityName
-
preferredUsernameMatchingUserEntityName
-
emailMatchingUserEntityProfileEmail
-
dangerouslyAllowSignInWithoutUserInCatalog: true
Configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.
WarningUse
dangerouslyAllowSignInWithoutUserInCatalog
to explore Developer Hub features, but do not use it in production.
Verification
To verify user and group provisioning, check the console logs.
Successful synchronization example:
{"class":"GithubMultiOrgEntityProvider","level":"info","message":"Reading GitHub users and teams for org: rhdh-dast","plugin":"catalog","service":"backstage","target":"https://github.com","taskId":"GithubMultiOrgEntityProvider:githuborg:refresh","taskInstanceId":"801b3c6c-167f-473b-b43e-e0b4b780c384","timestamp":"2024-09-09 23:55:58"} {"class":"GithubMultiOrgEntityProvider","level":"info","message":"Read 7 GitHub users and 2 GitHub groups in 0.4 seconds. Committing...","plugin":"catalog","service":"backstage","target":"https://github.com","taskId":"GithubMultiOrgEntityProvider:githuborg:refresh","taskInstanceId":"801b3c6c-167f-473b-b43e-e0b4b780c384","timestamp":"2024-09-09 23:55:59"}
To verify GitHub authentication:
- Go to the Developer Hub login page.
- Your Developer Hub sign-in page displays Sign in using GitHub and the Guest user sign-in is disabled.
- Log in with a GitHub account.
5. Authentication with Microsoft Azure
To authenticate users with Microsoft Azure:
5.1. Enabling authentication with Microsoft Azure
Red Hat Developer Hub includes a Microsoft Azure authentication provider that can authenticate users by using OAuth.
Prerequisites
You have the permission to register an application in Microsoft Azure.
- You added a custom Developer Hub application configuration, and have sufficient permissions to modify it.
Procedure
To allow Developer Hub to authenticate with Microsoft Azure, create an OAuth application in Microsoft Azure.
In the Azure portal go to App registrations, create a New registration with the configuration:
- Name
- The application name in Azure, such as <My Developer Hub>.
On the Home > App registrations > <My Developer Hub> > Manage > Authentication page, Add a platform, with the following configuration:
- Redirect URI
-
Enter the backend authentication URI set in Developer Hub:
https://<my_developer_hub_url>/api/auth/microsoft/handler/frame
- Front-channel logout URL
- Leave blank.
- Implicit grant and hybrid flows
- Leave all checkboxes cleared.
On the Home > App registrations > <My Developer Hub> > Manage > API permissions page, Add a Permission, then add the following Delegated permission for the Microsoft Graph API:
-
email
-
offline_access
-
openid
-
profile
-
User.Read.All
-
GroupMember.Read.All
-
Optional custom scopes for the Microsoft Graph API that you define both in this section and in the
app-config.yaml
Developer Hub configuration file.
-
Your company might require you to grant admin consent for these permissions. Even if your company does not require admin consent, you might do so as it means users do not need to individually consent the first time they access backstage. To grant administrator consent, a directory administrator must go to the admin consent page and click Grant admin consent for COMPANY NAME.
- On the Home > App registrations > <My Developer Hub> > Manage > Certificates & Secrets page, in the Client secrets tab, create a New client secret.
Save for the next step:
- Directory (tenant) ID
- Application (client) ID
Application (client) secret
To add your Microsoft Azure credentials to Developer Hub, add the following key/value pairs to your Developer Hub secrets:
AUTH_AZURE_TENANT_ID
- Enter your saved Directory (tenant) ID.
AUTH_AZURE_CLIENT_ID
- Enter your saved Application (client) ID.
AUTH_AZURE_CLIENT_SECRET
- Enter your saved Application (client) secret.
Set up the Microsoft Azure authentication provider in your
app-config.yaml
file:app-config.yaml
file fragmentauth: environment: production 1 providers: microsoft: production: clientId: ${AUTH_AZURE_CLIENT_ID} 2 clientSecret: ${AUTH_AZURE_CLIENT_SECRET} tenantId: ${AUTH_AZURE_TENANT_ID} signInPage: microsoft 3
Optional: Consider adding following optional fields:
domainHint
Optional for single-tenant applications. You can reduce login friction for users with accounts in multiple tenants by automatically filtering out accounts from other tenants. If you want to use this parameter for a single-tenant application, uncomment and enter the tenant ID. If your application registration is multi-tenant, leave this parameter blank. For more information, see Home Realm Discovery.
app-config.yaml
file fragment with optionaldomainHint
fieldauth: environment: production providers: microsoft: production: domainHint: ${AUTH_AZURE_TENANT_ID}
additionalScopes
Optional for additional scopes. To add scopes for the application registration, uncomment and enter the list of scopes that you want to add. The default and mandatory value lists:
'openid', 'offline_access', 'profile', 'email', 'User.Read'
.app-config.yaml
file fragment with optionaladditionalScopes
fieldauth: environment: production providers: microsoft: production: additionalScopes: - Mail.Send
sessionDuration
Lifespan of the user session. Enter a duration in
ms
library format (such as '24h', '2 days'), ISO duration, or "human duration" as used in code.app-config-rhdh.yaml
fragment with optionalsessionDuration
fieldauth: providers: microsoft: production: sessionDuration: { hours: 24 }
signIn
resolvers
-
After successful authentication, the user signing in must be resolved to an existing user in the Developer Hub catalog. To best match users securely for your use case, consider configuring a specific resolver. Enter the resolver list to override the default resolver:
emailLocalPartMatchingUserEntityName
.
The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed.
WarningIn production mode, only configure one resolver to ensure users are securely matched.
resolver
Enter the sign-in resolver name. Available resolvers:
-
userIdMatchingUserEntityAnnotation
-
emailLocalPartMatchingUserEntityName
-
emailMatchingUserEntityProfileEmail
-
dangerouslyAllowSignInWithoutUserInCatalog: true
Configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.
WarningUse
dangerouslyAllowSignInWithoutUserInCatalog
to explore Developer Hub features, but do not use it in production.app-config-rhdh.yaml
fragment with optional field to allow signing in users absent from the software catalogauth: environment: production providers: microsoft: production: clientId: ${AUTH_AZURE_CLIENT_ID} clientSecret: ${AUTH_AZURE_CLIENT_SECRET} tenantId: ${AUTH_AZURE_TENANT_ID} signIn: resolvers: - resolver: usernameMatchingUserEntityName dangerouslyAllowSignInWithoutUserInCatalog: true signInPage: microsoft
This step is optional for environments with outgoing access restrictions, such as firewall rules. If your environment has such restrictions, ensure that your RHDH backend can access the following hosts:
-
login.microsoftonline.com
: For obtaining and exchanging authorization codes and access tokens. -
graph.microsoft.com
: For retrieving user profile information (as referenced in the source code). If this host is unreachable, you might see an Authentication failed, failed to fetch user profile error when attempting to log in.
5.2. Provisioning users from Microsoft Azure to the software catalog
To authenticate users with Microsoft Azure, after Enabling authentication with Microsoft Azure, provision users from Microsoft Azure to the Developer Hub software catalog.
Prerequisites
Procedure
Enable the
backstage-plugin-catalog-backend-module-msgraph-dynamic
plugin.dynamic-plugins.yaml
file fragmentplugins: - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-msgraph-dynamic' disabled: false
To enable Microsoft Azure member discovery, edit
app-config.yaml
, your custom Developer Hub configuration file::app-config.yaml
fragment with mandatorymicrosoftGraphOrg
fieldscatalog: providers: microsoftGraphOrg: providerId: target: https://graph.microsoft.com/v1.0 tenantId: ${AUTH_AZURE_TENANT_ID} clientId: ${AUTH_AZURE_CLIENT_ID} clientSecret: ${AUTH_AZURE_CLIENT_SECRET} schedule: frequency: { hours: 1 } timeout: { minutes: 50 } initialDelay: { minutes: 50 }
target: https://graph.microsoft.com/v1.0
- Defines the MSGraph API endpoint the provider is connecting to. You might change this parameter to use a different version, such as the beta endpoint.
tenandId
,clientId
andclientSecret
- Use the Developer Hub application information you created in Microsoft Azure and configured in OpenShift as secrets.
schedule
frequency
- Enter the schedule frequency as cron, ISO duration, or human duration as used in code.
timeout
- Enter the schedule timeout as ISO duration or human duration as used in code.
initialDelay
Enter the schedule initial delay as ISO duration or human duration as used in code.
TipIn a large organization, this plugin can take a long time. Therefore, avoid setting a low frequency or timeout when importing a large number of users and groups for the first time.
Optional: Consider adding the following optional microsoftGraphOrg.providerId
fields:
authority: https://login.microsoftonline.com
Defines the authority used. Change the value to use a different authority, such as Azure US government. Default value:
https://login.microsoftonline.com
.app-config.yaml
fragment with optionalqueryMode
fieldcatalog: providers: microsoftGraphOrg: providerId: authority: https://login.microsoftonline.com/
queryMode: basic | advanced
By default, the Microsoft Graph API only provides the
basic
feature set for querying. Certain features requireadvanced
querying capabilities. See Microsoft Azure Advanced queries.app-config.yaml
fragment with optionalqueryMode
fieldcatalog: providers: microsoftGraphOrg: providerId: queryMode: advanced
user.expand
To include the expanded resource or collection referenced by a single relationship (navigation property) in your results. Only one relationship can be expanded in a single request. See Microsoft Graph query expand parameter. This parameter can be combined with ] or xref:userFilter[.
app-config.yaml
fragment with optionaluser.expand
fieldcatalog: providers: microsoftGraphOrg: providerId: user: expand: manager
user.filter
To filter users. See Microsoft Graph API and Microsoft Graph API query filter parameters syntax. This parameter and ???TITLE??? are mutually exclusive, only one can be specified.
app-config.yaml
fragment with optionaluser.filter
fieldcatalog: providers: microsoftGraphOrg: providerId: user: filter: accountEnabled eq true and userType eq 'member'
user.loadPhotos: true | false
Load photos by default. Set to
false
to not load user photos.app-config.yaml
fragment with optionaluser.loadPhotos
fieldcatalog: providers: microsoftGraphOrg: providerId: user: loadPhotos: true
user.select
Define the Microsoft Graph resource types to retrieve.
app-config.yaml
fragment with optionaluser.select
fieldcatalog: providers: microsoftGraphOrg: providerId: user: select: ['id', 'displayName', 'description']
userGroupMember.filter
To use group membership to get users. To filter groups and fetch their members. This parameter and ???TITLE??? are mutually exclusive, only one can be specified.
app-config.yaml
fragment with optionaluserGroupMember.filter
fieldcatalog: providers: microsoftGraphOrg: providerId: userGroupMember: filter: "displayName eq 'Backstage Users'"
userGroupMember.search
To use group membership to get users. To search for groups and fetch their members. This parameter and ???TITLE??? are mutually exclusive, only one can be specified.
app-config.yaml
fragment with optionaluserGroupMember.search
fieldcatalog: providers: microsoftGraphOrg: providerId: userGroupMember: search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
group.expand
Optional parameter to include the expanded resource or collection referenced by a single relationship (navigation property) in your results. Only one relationship can be expanded in a single request. See https://docs.microsoft.com/en-us/graph/query-parameters#expand-parameter This parameter can be combined with ] instead of xref:userFilter[.
app-config.yaml
fragment with optionalgroup.expand
fieldcatalog: providers: microsoftGraphOrg: providerId: group: expand: member
group.filter
To filter groups. See Microsoft Graph API query group syntax.
app-config.yaml
fragment with optionalgroup.filter
fieldcatalog: providers: microsoftGraphOrg: providerId: group: filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified')
group.search
To search for groups. See Microsoft Graph API query search parameter.
app-config.yaml
fragment with optionalgroup.search
fieldcatalog: providers: microsoftGraphOrg: providerId: group: search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
group.select
To define the Microsoft Graph resource types to retrieve.
app-config.yaml
fragment with optionalgroup.select
fieldcatalog: providers: microsoftGraphOrg: providerId: group: select: ['id', 'displayName', 'description']
Verification
Check the console logs to verify that the synchronization is completed.
Successful synchronization example:
backend:start: {"class":"MicrosoftGraphOrgEntityProvider$1","level":"info","message":"Read 1 msgraph users and 1 msgraph groups in 2.2 seconds. Committing...","plugin":"catalog","service":"backstage","taskId":"MicrosoftGraphOrgEntityProvider:default:refresh","taskInstanceId":"88a67ce1-c466-41a4-9760-825e16b946be","timestamp":"2024-06-26 12:23:42"} backend:start: {"class":"MicrosoftGraphOrgEntityProvider$1","level":"info","message":"Committed 1 msgraph users and 1 msgraph groups in 0.0 seconds.","plugin":"catalog","service":"backstage","taskId":"MicrosoftGraphOrgEntityProvider:default:refresh","taskInstanceId":"88a67ce1-c466-41a4-9760-825e16b946be","timestamp":"2024-06-26 12:23:42"}
- Log in with a Microsoft Azure account.