diff --git a/assemblies/assembly-authenticating-with-rhbk.adoc b/assemblies/assembly-authenticating-with-rhbk.adoc index db5f8a0e43..67c29a685d 100644 --- a/assemblies/assembly-authenticating-with-rhbk.adoc +++ b/assemblies/assembly-authenticating-with-rhbk.adoc @@ -4,7 +4,7 @@ = Authenticating with {rhbk-brand-name} ({rhbk}) -include::modules/authentication/proc-enabling-user-authentication-with-rhbk.adoc[leveloffset=+1] +include::modules/authentication/proc-enabling-user-authentication-with-rhbk-with-optional-steps.adoc[leveloffset=+1] include::modules/authentication/proc-creating-a-custom-transformer-to-provision-users-from-rhbk-to-the-software-catalog.adoc[leveloffset=+1] diff --git a/assemblies/assembly-enabling-authentication-with-github.adoc b/assemblies/assembly-enabling-authentication-with-github.adoc index 93848481ba..5458760c23 100644 --- a/assemblies/assembly-enabling-authentication-with-github.adoc +++ b/assemblies/assembly-enabling-authentication-with-github.adoc @@ -4,7 +4,7 @@ [id='enabling-authentication-with-github'] = Enabling authentication with GitHub -include::modules/authentication/proc-enabling-user-authentication-with-github.adoc[leveloffset=+1] +include::modules/authentication/proc-enabling-user-authentication-with-github-with-optional-steps.adoc[leveloffset=+1] include::modules/authentication/proc-enabling-user-authentication-with-github-as-an-auxiliary-authentication-provider.adoc[leveloffset=+1] diff --git a/assemblies/assembly-enabling-authentication-with-mandatory-steps-only.adoc b/assemblies/assembly-enabling-authentication-with-mandatory-steps-only.adoc index c6399552c9..8d8c9d42f5 100644 --- a/assemblies/assembly-enabling-authentication-with-mandatory-steps-only.adoc +++ b/assemblies/assembly-enabling-authentication-with-mandatory-steps-only.adoc @@ -10,11 +10,11 @@ include::modules/authentication/con-understanding-authentication-and-user-provis include::assembly-authenticating-with-the-guest-user.adoc[leveloffset=+1] -include::modules/authentication/proc-enabling-user-authentication-with-rhbk.adoc[leveloffset=+1] +include::modules/authentication/proc-enabling-user-authentication-with-rhbk-with-mandatory-steps.adoc[leveloffset=+1] -include::modules/authentication/proc-enabling-user-authentication-with-github.adoc[leveloffset=+1] +include::modules/authentication/proc-enabling-user-authentication-with-github-with-mandatory-steps.adoc[leveloffset=+1] -include::modules/authentication/proc-enabling-user-authentication-with-microsoft-azure.adoc[leveloffset=+1] +include::modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-mandatory-steps.adoc[leveloffset=+1] diff --git a/assemblies/assembly-enabling-authentication.adoc b/assemblies/assembly-enabling-authentication.adoc index 0dc5223f54..a160edfcf9 100644 --- a/assemblies/assembly-enabling-authentication.adoc +++ b/assemblies/assembly-enabling-authentication.adoc @@ -16,5 +16,5 @@ include::assembly-authenticating-with-rhbk.adoc[leveloffset=+1] include::assembly-enabling-authentication-with-github.adoc[leveloffset=+1] -include::modules/authentication/proc-enabling-user-authentication-with-microsoft-azure.adoc[leveloffset=+1] +include::modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-optional-steps.adoc[leveloffset=+1] diff --git a/modules/authentication/proc-creating-a-custom-transformer-to-provision-users-from-rhbk-to-the-software-catalog.adoc b/modules/authentication/proc-creating-a-custom-transformer-to-provision-users-from-rhbk-to-the-software-catalog.adoc index 659e51ab43..3e2ea37164 100644 --- a/modules/authentication/proc-creating-a-custom-transformer-to-provision-users-from-rhbk-to-the-software-catalog.adoc +++ b/modules/authentication/proc-creating-a-custom-transformer-to-provision-users-from-rhbk-to-the-software-catalog.adoc @@ -7,7 +7,7 @@ Customize how {product} provisions users and groups to {product} software catalo by creating a backend module that uses the `keycloakTransformerExtensionPoint` to offer custom user and group transformers for the Keycloak backend. .Prerequisites -* You have xref:enabling-user-authentication-with-rhbk[enabled provisioning users from {rhbk-brand-name} ({rhbk}) to the software catalog]. +* You have xref:enabling-user-authentication-with-rhbk-with-optional-steps[enabled provisioning users from {rhbk-brand-name} ({rhbk}) to the software catalog]. .Procedure . Create a new backend module with the `yarn new` command. diff --git a/modules/authentication/proc-enabling-user-authentication-with-github-as-an-auxiliary-authentication-provider.adoc b/modules/authentication/proc-enabling-user-authentication-with-github-as-an-auxiliary-authentication-provider.adoc index ad26bf65fd..98ffd30369 100644 --- a/modules/authentication/proc-enabling-user-authentication-with-github-as-an-auxiliary-authentication-provider.adoc +++ b/modules/authentication/proc-enabling-user-authentication-with-github-as-an-auxiliary-authentication-provider.adoc @@ -3,14 +3,17 @@ [id="enabling-user-authentication-with-github-as-an-auxiliary-authentication-provider"] = Enabling user authentication with GitHub as an auxiliary authentication provider -To allow users to access GitHub templates or plugins that require GitHub authentication, configure GitHub as an auxiliary authentication provider. This method relies on a primary authentication provider for user identity management, and skips resolving user identity from this provider. +If your primary authentication provider is not GitHub, users might lack the permissions needed for templates or plugins that require GitHub access. The recommended solution is to configure GitHub as an auxiliary authentication provider. This approach uses the primary provider for user identity management and the auxiliary provider to grant the necessary GitHub permissions, without re-resolving the user's identity. + +Give users access to these features by configuring GitHub as an auxiliary authentication provider. .Prerequisites -* You have {configuring-book-link}[added a custom {product-short} application configuration] with another authentication provider enabled, and have enough permissions to change it. +include::snip-enabling-user-authentication-with-github-common-prerequisites.adoc[] +* You have configured a primary authentication provider to provision user and group identities to the {product} software catalog, and establish {product-short} user sessions. -include::snip-enabling-user-authentication-with-github-common-steps.adoc[] -. To set up the GitHub authentication provider as an auxiliary authentication provider, add the `auth.providers.github` section to your `{my-app-config-file}` file: +.Procedure +. Add the `auth.providers.github` section to your `{my-app-config-file}` file: + [source,yaml] ---- @@ -31,11 +34,14 @@ Enter the configured secret variable name: `$\{GITHUB_CLIENT_ID}`. Enter the configured secret variable name: `$\{GITHUB_CLIENT_SECRET}`. `disableIdentityResolution`:: -Enter `true`to skip user identity resolution for this provider to enable sign-in from an auxiliary authentication provider. +Enter `true` to skip user identity resolution for this provider to enable sign-in from an auxiliary authentication provider. ++ +[WARNING] +==== Do not enable this setting on the primary authentication provider you plan on using for sign-in and identity management. +==== .Verification - . Go to the {product-short} login page. . Log in with your primary authentication provider account. . In the top user menu, go to *Settings* > *Authentication Providers*. diff --git a/modules/authentication/proc-enabling-user-authentication-with-github-with-mandatory-steps.adoc b/modules/authentication/proc-enabling-user-authentication-with-github-with-mandatory-steps.adoc new file mode 100644 index 0000000000..818d65ba00 --- /dev/null +++ b/modules/authentication/proc-enabling-user-authentication-with-github-with-mandatory-steps.adoc @@ -0,0 +1,14 @@ +:_mod-docs-content-type: PROCEDURE + +[id="enabling-user-authentication-with-github-with-mandatory-steps"] += Enabling user authentication with GitHub + +Authenticate users with GitHub by provisioning the users and groups from GitHub to the {product-short} software catalog, and configuring the GitHub authentication provider in {product}. + +include::snip-enabling-user-authentication-with-github-common-prerequisites.adoc[] + +include::snip-enabling-user-authentication-with-github-common-first-steps.adoc[] ++ +Optional: To configure optional fields, see {configuring-book-link}[{configuring-book-title}]. + +include::snip-enabling-user-authentication-with-github-common-verification-steps.adoc[] diff --git a/modules/authentication/proc-enabling-user-authentication-with-github-with-optional-steps.adoc b/modules/authentication/proc-enabling-user-authentication-with-github-with-optional-steps.adoc new file mode 100644 index 0000000000..900dd40e4a --- /dev/null +++ b/modules/authentication/proc-enabling-user-authentication-with-github-with-optional-steps.adoc @@ -0,0 +1,18 @@ +:_mod-docs-content-type: PROCEDURE + +[id="enabling-user-authentication-with-github-with-optional-steps"] += Enabling user authentication with GitHub, with optional steps + +Authenticate users with GitHub by provisioning the users and groups from GitHub to the {product-short} software catalog, and configuring the GitHub authentication provider in {product}. + +include::snip-enabling-user-authentication-with-github-common-prerequisites.adoc[] + +include::snip-enabling-user-authentication-with-github-common-first-steps.adoc[] + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-github-optional-authentication-provider-steps.adoc[] +-- + +include::snip-enabling-user-authentication-with-github-common-verification-steps.adoc[] diff --git a/modules/authentication/proc-enabling-user-authentication-with-github.adoc b/modules/authentication/proc-enabling-user-authentication-with-github.adoc deleted file mode 100644 index e4f5779469..0000000000 --- a/modules/authentication/proc-enabling-user-authentication-with-github.adoc +++ /dev/null @@ -1,158 +0,0 @@ -:_mod-docs-content-type: PROCEDURE - -[id="enabling-user-authentication-with-github"] -= Enabling user authentication with GitHub - -Authenticate users with GitHub by provisioning the users and groups from GitHub to the {product-short} software catalog, and configuring the GitHub authentication provider in {product}. - -.Prerequisites -* You {configuring-book-link}[added a custom {product-short} application configuration], and have enough permissions to change it. - -include::snip-enabling-user-authentication-with-github-common-steps.adoc[] - -. Provision GitHub users and groups to the {product-short} software catalog by adding the `catalog.providers.githubOrg` section to your custom {product-short} `{my-app-config-file}` configuration file: -+ -[id=githubProviderId] -[source,yaml] ----- -catalog: - providers: - githubOrg: - id: githuborg - githubUrl: "${GITHUB_URL}" - orgs: [ "${GITHUB_ORG}" ] - 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 or conflicts. - -`githubUrl`:: -Enter the configured secret variable name: `$\{GITHUB_URL}`. - -`orgs`:: -Enter the configured secret variable name: `$\{GITHUB_ORG}`. - -`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 your `{my-app-config-file}` file: -+ -[source,yaml] ----- -auth: - environment: production - providers: - github: - production: - clientId: ${GITHUB_CLIENT_ID} - clientSecret: ${GITHUB_CLIENT_SECRET} -signInPage: github ----- - -`environment`:: -Enter `production` to disable the Guest login option in the {product-short} login page. - -`clientId`:: -Enter the configured secret variable name: `$\{GITHUB_CLIENT_ID}`. - -`clientSecret`:: -Enter the configured secret variable name: `$\{GITHUB_CLIENT_SECRET}`. - -`signInPage`:: -Enter `github` to enable the GitHub provider as your {product-short} sign-in provider. -+ -Optional: Consider adding optional fields. -ifeval::["{optional-steps}" == "disable"] -See {configuring-book-link}[{configuring-book-title}]. -endif::[] -ifeval::["{optional-steps}" == "enable"] -[source,yaml,subs="+quotes"] ----- -auth: - environment: production - providers: - github: - production: - clientId: ${GITHUB_CLIENT_ID} - clientSecret: ${GITHUB_CLIENT_SECRET} - callbackUrl: ____ - 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: ____. -Define it when {product-short} is not the immediate receiver, such as in cases when you use one OAuth app for many {product-short} 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, {product-short} resolves the user signing in to an existing user in the {product-short} 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. -+ -[WARNING] -==== -Make sure users are securely matched in production mode, by configuring only one resolver. -==== - -`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 {product-short} software catalog. -+ -[WARNING] -==== -Do not use `dangerouslyAllowSignInWithoutUserInCatalog` in production. Use this configuration only to explore {product-short} features. -==== -endif::[] - -.Verification -. Verify user and group provisioning by checking the console logs. -+ -Successful synchronization example: -+ -[source,json] ----- -{"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 {product-short} login page. -.. Your {product-short} sign-in page displays *Sign in using GitHub* and the Guest user sign-in is disabled. -.. Log in with a GitHub account. - -.Additional resources -* {integrating-with-github-book-link}[{integrating-with-github-book-title}] - diff --git a/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-mandatory-steps.adoc b/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-mandatory-steps.adoc new file mode 100644 index 0000000000..714fd643f1 --- /dev/null +++ b/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-mandatory-steps.adoc @@ -0,0 +1,14 @@ +:_mod-docs-content-type: PROCEDURE + +[id="enabling-user-authentication-with-microsoft-azure-with-mandatory-steps"] += Enabling user authentication with {azure-brand-name} + +include::snip-enabling-user-authentication-with-microsoft-azure-common-first-steps.adoc[] ++ +Optional: To configure optional fields, see {configuring-book-link}[{configuring-book-title}]. + +include::snip-enabling-user-authentication-with-microsoft-azure-common-authentication-provider-steps.adoc[] ++ +Optional: To configure optional fields, see {configuring-book-link}[{configuring-book-title}]. + +include::snip-enabling-user-authentication-with-microsoft-azure-common-verification-steps.adoc[] diff --git a/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-optional-steps.adoc b/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-optional-steps.adoc new file mode 100644 index 0000000000..d7899d6c86 --- /dev/null +++ b/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure-with-optional-steps.adoc @@ -0,0 +1,26 @@ +:_mod-docs-content-type: PROCEDURE + +[id="enabling-user-authentication-with-microsoft-azure-with-optional-steps"] += Enabling user authentication with {azure-brand-name}, with optional steps + +include::snip-enabling-user-authentication-with-microsoft-azure-common-first-steps.adoc[] + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-microsoft-azure-optional-catalog-provider-steps.adoc[] +-- + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-microsoft-azure-common-authentication-provider-steps.adoc[] +-- + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-microsoft-azure-optional-authentication-provider-steps.adoc[] +-- + +include::snip-enabling-user-authentication-with-microsoft-azure-common-verification-steps.adoc[] diff --git a/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure.adoc b/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure.adoc deleted file mode 100644 index f59c7f15e2..0000000000 --- a/modules/authentication/proc-enabling-user-authentication-with-microsoft-azure.adoc +++ /dev/null @@ -1,483 +0,0 @@ -:_mod-docs-content-type: PROCEDURE - -[id="enabling-user-authentication-with-microsoft-azure"] -= Enabling user authentication with {azure-brand-name} - -Authenticate users with {azure-brand-name} by provisioning the users and groups from {azure-short} to the {product-short} software catalog, and configuring the {azure-short} authentication provider in {product}. - -.Prerequisites -* You have the permission to register an application in {azure-short}. -Alternatively, you can ask your {azure-short} administrator to prepare the required {azure-short} application. - -* You {configuring-book-link}[added a custom {product-short} application configuration], and have enough permissions to change it. - -* Your {product-short} backend can access the following hosts: - -`login.microsoftonline.com`:: -The {azure-brand-name} authorization server, which enables the authentication flow. - -`graph.microsoft.com`:: -The server for retrieving organization data, including user and group data, to import into the {product-short} catalog. - -.Procedure -:my-product-app-name-in-azure: -. To allow {product-short} to authenticate with {azure-short}, link:https://learn.microsoft.com/en-us/entra/identity-platform/scenario-web-app-sign-user-app-registration?tabs=aspnetcore#register-an-app-by-using-the-azure-portal[Register an app by using the {azure-short} portal]. - -.. Sign in to the link:https://entra.microsoft.com/[Microsoft Entra admin center]. - -.. Optional: If you have access to many tenants, use the *Settings* icon in the top menu to switch to the tenant in which you want to register the application from the *Directories + subscriptions* menu. - -.. Browse to *Applications > App registrations*, and create a **New registration** with the configuration: - -Name:: -Enter a name to identify your application in {azure-short}, such as __{my-product-app-name-in-azure}__. - -Supported account types:: -Select *Accounts in this organizational directory only*. - -Redirect URI:: - -Select a platform::: -Select *Web*. - -URL::: -Enter the backend authentication URI set in {product-short}: `pass:c,a,q[{my-product-url}/api/auth/microsoft/handler/frame]` - -.. On the *Applications > App registrations > __{my-product-app-name-in-azure}__ > Manage > API permissions* page, *Add a Permission*, *Microsoft Graph*, select the following permissions: - -Application Permissions:: -`GroupMember.Read.All`::: -`User.Read.All`::: -Enter permissions that enable provisioning user and groups to the {product-short} software catalog. -+ -Optional: *Grant admin consent* for these permissions. -Even if your company does not require admin consent, consider doing so as it means users do not need to individually consent the first time they access {product-short}. - -Delegated Permissions:: -`User.Read`::: -`email`::: -`offline_access`::: -`openid`::: -`profile`::: -Enter permissions that enable authenticating users. -+ -Optional: Enter optional custom scopes for the Microsoft Graph API that you define both here and in your `{my-app-config-file}` {product-short} configuration file. - - -.. On the *Applications > App registrations > __{my-product-app-name-in-azure}__ > Manage > Certificates & secrets* page, in the *Client secrets* tab, create a *New client secret*. - -.. Save the following values for the next step: -- **Directory (tenant) ID** -- **Application (client) ID** -- **Application (client) Secret ID** - -. To add your {azure-short} credentials to {product-short}, add the following key/value pairs to {configuring-book-link}#provisioning-your-custom-configuration[your {product-short} secrets]: - -`AUTHENTICATION_AZURE_TENANT_ID`:: -Enter your saved *Directory (tenant) ID*. - -`AUTHENTICATION_AZURE_CLIENT_ID`:: -Enter your saved *Application (client) ID*. - -`AUTHENTICATION_AZURE_CLIENT_SECRET`:: -Enter your saved *Application (client) secret*. - -. Enable the Microsoft Graph organization provisioning plugin (`backstage-plugin-catalog-backend-module-msgraph-dynamic`) in your `dynamic-plugins.yaml` -file. -This plugin imports {azure-short} users and groups to the {product-short} software catalog. -+ -[source,yaml] ----- -plugins: - - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-msgraph-dynamic' - disabled: false ----- - -. To provision {azure-short} users and groups to the {product-short} software catalog, add the `catalog.providers.microsoftGraphOrg` section to your custom {product-short} `{my-app-config-file}` configuration file: -+ -[id=microsoftGraphOrgProviderId] -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - target: https://graph.microsoft.com/v1.0 - tenantId: ${AUTHENTICATION_AZURE_TENANT_ID} - clientId: ${AUTHENTICATION_AZURE_CLIENT_ID} - clientSecret: ${AUTHENTICATION_AZURE_CLIENT_SECRET} - schedule: - frequency: - hours: 1 - timeout: - minutes: 50 - initialDelay: - minutes: 50 ----- - -`target`:: -Enter `\https://graph.microsoft.com/v1.0` to define the MSGraph API endpoint the provider is connecting to. -You might change this parameter to use a different version, such as the link:https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-beta#call-the-beta-endpoint[beta endpoint]. - -`tenandId`:: -Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_TENANT_ID}`. - -`clientId`:: -Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_CLIENT_ID}`. - -`clientSecret`:: -Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_CLIENT_SECRET}`. - -`schedule`:: - -`frequency`::: -Enter the schedule frequency in the cron, ISO duration, or human duration format. -In a large organization, user provisioning might take a long time, therefore avoid using a low value. - -`timeout`::: -Enter the schedule timeout in the ISO duration or human duration format. -In a large organization, user provisioning might take a long time, therefore avoid using a low value. - -`initialDelay`::: -Enter the schedule initial delay in the ISO duration or human duration format. -+ -Optional: Consider adding optional fields. -ifeval::["{optional-steps}" == "disable"] -See {configuring-book-link}[{configuring-book-title}]. -endif::[] -ifeval::["{optional-steps}" == "enable"] -[id=authority] -`authority`:: -Enter your link:https://learn.microsoft.com/en-us/graph/deployments#app-registration-and-token-service-root-endpoints[{azure-short} authority URL] if it is different from the default: `\https://login.microsoftonline.com`. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - authority: https://login.microsoftonline.com/ ----- - -[id=queryMode] -`queryMode: basic | advanced`:: -Enter `advanced` when the default `basic` query mode is insufficient for your queries to the Microsoft Graph API. -See link:https://learn.microsoft.com/en-us/graph/aad-advanced-queries[{azure-brand-name} advanced queries]. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - queryMode: advanced ----- - -[id=userExpand] -`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 https://learn.microsoft.com/en-us/graph/query-parameters#expand-parameter[Microsoft Graph query expand parameter]. -This parameter can be combined with xref:userGroupMemberFilter[`userGroupMember.filter`] or xref:userFilter[`user.filter`]. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - user: - expand: manager ----- - -[id=userFilter] -`user.filter`:: -To filter users. -See link:https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0#properties[Microsoft Graph API] and link:https://learn.microsoft.com/en-us/graph/query-parameters#filter-parameter[Microsoft Graph API query filter parameters syntax]. -This parameter and xref:userGroupMemberFilter[`userGroupMember.filter`] are mutually exclusive, only one can be specified. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - user: - filter: accountEnabled eq true and userType eq 'member' ----- - -[id=userLoadPhotos] -`user.loadPhotos: true | false`:: -{product-short} loads photos by default. -Enter `false` to avoid loading user photos. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - user: - loadPhotos: true ----- - -[id=userSelect] -`user.select`:: -Enter the link:https://learn.microsoft.com/en-us/graph/api/resources/schemaextension?view=graph-rest-1.0[Microsoft Graph resource type] list to retrieve. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - user: - select: ['id', 'displayName', 'description'] ----- - -[id="userGroupMemberFilter"] -`userGroupMember.filter`::: -To use group membership to get users. -To filter groups and fetch their members. -This parameter and xref:userFilter[`user.filter`] are mutually exclusive, only one can be specified. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - userGroupMember: - filter: "displayName eq 'Backstage Users'" ----- - -[id="userGroupMemberSearch"] -`userGroupMember.search`:: -To use group membership to get users. -To search for groups and fetch their members. -This parameter and xref:userFilter[`user.filter`] are mutually exclusive, only one can be specified. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - userGroupMember: - search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")' ----- - -[id=groupExpand] -`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 link:https://learn.microsoft.com/en-us/graph/query-parameters#expand-parameter[Customize Microsoft Graph responses with query parameters]. -This parameter can be combined with xref:userGroupMemberFilter[`userGroupMember.filter`] instead of xref:userFilter[`user.filter`]. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - group: - expand: member ----- - -[id=groupFilter] -`group.filter`:: -To filter groups. -See link:https://learn.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0#properties[Microsoft Graph API query group syntax]. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - group: - filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified') ----- - -[id=groupSearch] -`group.search`:: -To search for groups. -See link:https://learn.microsoft.com/en-us/graph/search-query-parameter[Microsoft Graph API query search parameter]. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - group: - search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")' ----- - -[id=groupSelect] -`group.select`:: -Enter the link:https://learn.microsoft.com/en-us/graph/api/resources/schemaextension?view=graph-rest-1.0[Microsoft Graph resource type] list to retrieve. -+ -[source,yaml] ----- -catalog: - providers: - microsoftGraphOrg: - providerId: - group: - select: ['id', 'displayName', 'description'] ----- -endif::[] - -. To set up the {azure-short} authentication provider, add the `auth.providers.microsoft` section to your `{my-app-config-file}` file content: -+ -[source,yaml,subs="+quotes,+attributes"] ----- -auth: - environment: production - providers: - microsoft: - production: - clientId: ${AUTHENTICATION_AZURE_CLIENT_ID} - clientSecret: ${AUTHENTICATION_AZURE_CLIENT_SECRET} - tenantId: ${AUTHENTICATION_AZURE_TENANT_ID} -signInPage: microsoft ----- - -`environment`:: -Enter `production` to disable the **Guest** login option in the {product-short} login page. - -`clientId`:: -Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_CLIENT_ID}`. - -`clientSecret`:: -Enter the configured secret variable name: -`$\{AUTHENTICATION_AZURE_CLIENT_SECRET}`. - -`tenantId`:: -Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_TENANT_ID}`. - -`signInPage`:: -Enter `microsoft` to set the {azure-short} provider as your {product-short} sign-in provider. -+ -Optional: Add optional fields. -ifeval::["{optional-steps}" == "disable"] -See {configuring-book-link}[{configuring-book-title}]. -endif::[] -ifeval::["{optional-steps}" == "enable"] -`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 link:https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/home-realm-discovery-policy[Home Realm Discovery]. -+ -[source,yaml,subs="+quotes,+attributes"] ----- -auth: - environment: production - providers: - microsoft: - production: - domainHint: ${AUTHENTICATION_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 following scopes: -* `openid` -* `offline_access` -* `profile` -* `email` -* `User.Read` -+ -[source,yaml,subs="+quotes,+attributes"] ----- -auth: - environment: production - providers: - microsoft: - production: - additionalScopes: - - Mail.Send ----- - -`sessionDuration`:: -Lifespan of the user session. -Enter a duration in `ms` library (such as '24h', '2 days'), ISO duration, or "human duration" format. -+ -[source,yaml,subs="+quotes"] ----- -auth: - providers: - microsoft: - production: - sessionDuration: - hours: 24 ----- - -`signIn`:: - -`resolvers`::: -After successful authentication, {product-short} resolves the user signing in to an existing user in the {product-short} catalog. -To best match users securely for your use case, consider configuring a specific resolver. -+ -Enter the resolver list to override the default resolver: `userIdMatchingUserEntityAnnotation`. -+ -The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed. -+ -WARNING: In production mode, only configure one resolver to ensure users are securely matched. -+ -[source,yaml] ----- -auth: - environment: production - providers: - microsoft: - production: - clientId: ${AUTHENTICATION_AZURE_CLIENT_ID} - clientSecret: ${AUTHENTICATION_AZURE_CLIENT_SECRET} - tenantId: ${AUTHENTICATION_AZURE_TENANT_ID} - signIn: - resolvers: - - resolver: usernameMatchingUserEntityName - dangerouslyAllowSignInWithoutUserInCatalog: true -signInPage: microsoft ----- - -`resolver`:::: -Enter the sign-in resolver name. -Available resolvers: - -`emailMatchingUserEntityAnnotation`::::: -This resolver looks up the user by matching their Microsoft email to the email entity annotation. - -`emailLocalPartMatchingUserEntityName`::::: -This resolver looks up the user by matching their Microsoft email user name to the user entity name. - -`emailMatchingUserEntityProfileEmail`::::: -This resolver looks up the user by matching their Microsoft email to the user entity profile email. - -`dangerouslyAllowSignInWithoutUserInCatalog: true`:::: -Configure the sign-in resolver to bypass the user provisioning requirement in the {product-short} software catalog. -+ -WARNING: Use `dangerouslyAllowSignInWithoutUserInCatalog` to explore {product-short} features, but do not use it in production. -endif::[] - -.Verification -. To verify user and group provisioning, check the console logs for `MicrosoftGraphOrgEntityProvider` events. -+ -Successful synchronization example: -+ -[source] ----- -2025-06-23T13:37:55.804Z catalog info Read 9 msgraph users and 3 msgraph groups in 1.5 seconds. Committing... class="MicrosoftGraphOrgEntityProvider" taskId="MicrosoftGraphOrgEntityProvider:providerId:refresh" taskInstanceId="e104a116-6481-4ceb-9bc4-0f8f9581f959" trace_id="e4c633659cffd6b1529afa55a5bfbad7" span_id="76affd0420e8baa6" trace_flags="01" - -2025-06-23T13:37:55.811Z catalog info Committed 9 msgraph users and 3 msgraph groups in 0.0 seconds. class="MicrosoftGraphOrgEntityProvider" taskId="MicrosoftGraphOrgEntityProvider:providerId:refresh" taskInstanceId="e104a116-6481-4ceb-9bc4-0f8f9581f959" trace_id="e4c633659cffd6b1529afa55a5bfbad7" span_id="76affd0420e8baa6" trace_flags="01" ----- - -. To verify {azure-short} user authentication: -.. Go to the {product-short} login page. -.. Your {product-short} sign-in page displays *Sign in using Microsoft* and the Guest user sign-in is disabled. -.. Log in with an {azure-short} account. diff --git a/modules/authentication/proc-enabling-user-authentication-with-rhbk-with-mandatory-steps.adoc b/modules/authentication/proc-enabling-user-authentication-with-rhbk-with-mandatory-steps.adoc new file mode 100644 index 0000000000..de8b9c4a6b --- /dev/null +++ b/modules/authentication/proc-enabling-user-authentication-with-rhbk-with-mandatory-steps.adoc @@ -0,0 +1,18 @@ +:_mod-docs-content-type: PROCEDURE +[id="enabling-user-authentication-with-rhbk-with-mandatory-steps"] += Enabling user authentication with {rhbk-brand-name} ({rhbk}) + + +include::snip-enabling-user-authentication-with-rhbk-common-first-steps.adoc[] ++ +Optional: To configure optional fields, see {configuring-book-link}[{configuring-book-title}]. + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-rhbk-common-authentication-provider-steps.adoc[] ++ +Optional: To configure optional fields, see {configuring-book-link}[{configuring-book-title}]. +-- + +include::snip-enabling-user-authentication-with-rhbk-verification-steps.adoc[] diff --git a/modules/authentication/proc-enabling-user-authentication-with-rhbk-with-optional-steps.adoc b/modules/authentication/proc-enabling-user-authentication-with-rhbk-with-optional-steps.adoc new file mode 100644 index 0000000000..f8c1be24ba --- /dev/null +++ b/modules/authentication/proc-enabling-user-authentication-with-rhbk-with-optional-steps.adoc @@ -0,0 +1,25 @@ +:_mod-docs-content-type: PROCEDURE +[id="enabling-user-authentication-with-rhbk-with-optional-steps"] += Enabling user authentication with {rhbk-brand-name} ({rhbk}), with optional steps + +include::snip-enabling-user-authentication-with-rhbk-common-first-steps.adoc[] + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-rhbk-optional-catalog-provider-steps.adoc[] +-- + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-rhbk-common-authentication-provider-steps.adoc[] +-- + +. {empty} ++ +-- +include::snip-enabling-user-authentication-with-rhbk-optional-authentication-provider-steps.adoc[] +-- + +include::snip-enabling-user-authentication-with-rhbk-verification-steps.adoc[] diff --git a/modules/authentication/proc-enabling-user-authentication-with-rhbk.adoc b/modules/authentication/proc-enabling-user-authentication-with-rhbk.adoc deleted file mode 100644 index fefdc4bb7f..0000000000 --- a/modules/authentication/proc-enabling-user-authentication-with-rhbk.adoc +++ /dev/null @@ -1,362 +0,0 @@ -:_mod-docs-content-type: PROCEDURE -[id="enabling-user-authentication-with-rhbk"] -= Enabling user authentication with {rhbk-brand-name} ({rhbk}) - -Authenticate users with {rhbk-brand-name} ({rhbk}), -by provisioning the users and groups from {rhbk} to the {product-short} software catalog, and configuring the OpenID Connect (OIDC) authentication provider in {product}. - -.Prerequisites -* You {configuring-book-link}[added a custom {product-short} application configuration], and have enough permissions to change it. -* You have enough permissions in {rhsso} to create and manage a realm and a client. -Alternatively, your {rhbk} administrator can prepare in {rhbk} the required realm and client for you. - -.Procedure -. To allow {product-short} to authenticate with {rhbk}, complete the steps in {rhbk}, to {rhbk-docs-link}/html/getting_started_guide/getting-started-zip-#getting-started-zip-create-a-realm[create a realm and a user] and {rhbk-docs-link}/html/getting_started_guide/getting-started-zip-#getting-started-zip-secure-the-first-application[secure the first application]: - -.. Use an existing realm, or {rhbk-docs-link}/html/getting_started_guide/getting-started-zip-#getting-started-zip-create-a-realm[create a realm], with a distinctive **Name** such as ____. -Save the value for the next step: -* **{rhbk} realm base URL**, such as: ____/realms/____. - -.. To register your {product-short} in {rhbk}, in the created realm, {rhbk-docs-link}/html-single/getting_started_guide/index#getting-started-zip-secure-the-first-application[secure the first application], with: -... **Client ID**: A distinctive client ID, such as __<{product-very-short}>__. -... **Valid redirect URIs**: Set to the OIDC handler URL: `pass:c,a,q[{my-product-url}/api/auth/oidc/handler/frame]`. -... Go 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 {rhbk-docs-link}/html-single/getting_started_guide/index#getting-started-zip-create-a-user[create a user]. Save the user credential information for the verification steps. - -. To add your {rhsso} credentials to {product-short}, add the following key/value pairs to {configuring-dynamic-plugins-book-link}#provisioning-your-custom-configuration[your {product-short} secrets]. -You can use these secrets in the {product-short} configuration files by using their environment variable name. -+ -`KEYCLOAK_CLIENT_ID`:: -Enter the saved **Client ID**. - -`KEYCLOAK_CLIENT_SECRET`:: -Enter the saved **Client Secret**. - -`KEYCLOAK_BASE_URL`:: -Enter the saved **{rhbk} realm base URL**. - -. Enable the Keycloak organization plugin (`backstage-plugin-catalog-backend-module-keycloak-dynamic`) in your `dynamic-plugins.yaml` file. -The plugin is named after {rhbk} upstream project. -This plugin imports {rhbk} users and groups to the {product-short} software catalog. -+ -[source,yaml] ----- -plugins: - - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-keycloak-dynamic' - disabled: false ----- - -. To provision {rhbk} users and groups to the {product-short} software catalog, add the `catalog.providers.keycloakOrg` section to your custom {product-short} `{my-app-config-file}` configuration file: -+ -[id=keycloakOrgProviderId] -[source,yaml] ----- -catalog: - providers: - keycloakOrg: - default: - baseUrl: ${KEYCLOAK_BASE_URL} - clientId: ${KEYCLOAK_CLIENT_ID} - clientSecret: ${KEYCLOAK_CLIENT_SECRET} - realm: master - loginRealm: master ----- - -`baseUrl`:: -Enter your {rhbk} server URL, defined earlier. - -`clientId`:: -Enter your {product-short} application client ID in {rhbk}, defined earlier. - -`clientSecret`:: -Enter your {product-short} application client secret in {rhbk}, defined earlier. - -`realm`:: -Enter the realm name to provision users, such as `master`. - -`loginRealm`:: -Enter the realm name to authenticate users, such as `master`. -+ -Optional: Add optional fields. -ifeval::["{optional-steps}" == "disable"] -See {configuring-book-link}[{configuring-book-title}]. -endif::[] -ifeval::["{optional-steps}" == "enable"] -`userQuerySize`:: -Enter the user count to query simultaneously. -Default value: `100`. -+ -[source,yaml] ----- -catalog: - providers: - keycloakOrg: - default: - userQuerySize: 100 ----- - -`groupQuerySize`:: -Enter the group count to query simultaneously. -Default value: `100`. -+ -[source,yaml] ----- -catalog: - providers: - keycloakOrg: - default: - groupQuerySize: 100 ----- - -`schedule.frequency`:: -Enter the schedule frequency. -Supports cron, ISO duration, and "human duration" as used in code. -+ -[source,yaml] ----- -catalog: - providers: - keycloakOrg: - default: - schedule: - frequency: { hours: 1 } ----- - -`schedule.timeout`:: -Enter the timeout for the user provisioning job. -Supports ISO duration and "human duration" as used in code. -+ -[source,yaml] ----- -catalog: - providers: - keycloakOrg: - default: - schedule: - timeout: { minutes: 50 } ----- - -`schedule.initialDelay`:: -Enter the initial delay to wait for before starting the user provisioning job. -Supports ISO duration and "human duration" as used in code. -+ -[source,yaml] ----- -catalog: - providers: - keycloakOrg: - default: - schedule: - initialDelay: { seconds: 15} ----- -endif::[] - -. To set up the {rhbk} authentication provider in your {product-short} custom configuration, edit your custom {product-short} ConfigMap such as `app-config-rhdh`, and add the following lines to the `{my-app-config-file}` content: -+ -[source,yaml] ----- -auth: - environment: production - providers: - oidc: - production: - metadataUrl: ${KEYCLOAK_BASE_URL} - clientId: ${KEYCLOAK_CLIENT_ID} - clientSecret: ${KEYCLOAK_CLIENT_SECRET} - prompt: auto -signInPage: oidc ----- - -`environment: production`:: -Mark the environment as `production` to hide the Guest login in the {product-short} 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. -+ -[NOTE] -==== -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. -==== -+ -Optional: Add optional fields. -ifeval::["{optional-steps}" == "disable"] -See {configuring-book-link}[{configuring-book-title}]. -endif::[] -ifeval::["{optional-steps}" == "enable"] -`callbackUrl`:: -{rhbk} callback URL. -+ -[source,yaml] ----- -auth: - providers: - oidc: - production: - callbackUrl: ${KEYCLOAK_CALLBACK_URL} ----- - -`tokenEndpointAuthMethod`:: -Token endpoint authentication method. -+ -[source,yaml] ----- -auth: - providers: - oidc: - production: - tokenEndpointAuthMethod: ${KEYCLOAK_TOKEN_ENDPOINT_METHOD} ----- - -`tokenSignedResponseAlg`:: -Token signed response algorithm. -+ -[source,yaml] ----- -auth: - providers: - oidc: - production: - tokenSignedResponseAlg: ${KEYCLOAK_SIGNED_RESPONSE_ALG} ----- - -`additionalScopes`:: -Enter additional {rhbk} scopes to request for during the authentication flow. -+ -[source,yaml] ----- -auth: - providers: - oidc: - production: - additionalScopes: ${KEYCLOAK_SCOPE} ----- - -`signIn`:: -`resolvers`::: -After successful authentication, the user signing in must be resolved to an existing user in the {product-short} 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`. -+ -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. -+ -The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed. -+ -[WARNING] -==== -In production mode, only configure one resolver to ensure users are securely matched. -==== -+ -[source,yaml] ----- -auth: - 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 {product-short} software catalog. -+ -[WARNING] -==== -Use this option to explore {product-short} features, but do not use it in production. -==== -+ -[source,yaml] ----- -auth: - environment: production - providers: - oidc: - production: - metadataUrl: ${KEYCLOAK_BASE_URL} - clientId: ${KEYCLOAK_CLIENT_ID} - clientSecret: ${KEYCLOAK_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. -+ -[source,yaml,subs="+quotes"] ----- -auth: - providers: - github: - production: - sessionDuration: { hours: 24 } ----- - -`auth`:: - -`backstageTokenExpiration`::: -To modify the {product-short} 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. -+ -[source,yaml,subs="+quotes"] ----- -auth: - backstageTokenExpiration: { minutes: __ } ----- -+ -[WARNING] -==== -For security, consider that if 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. -==== -endif::[] - -.Verification - -. To verify user and group provisioning, check the console logs. -+ -Successful synchronization example: -+ -[source] ----- -2025-06-27T16:02:34.647Z catalog info Read 5 Keycloak users and 3 Keycloak groups in 0.4 seconds. Committing... class="KeycloakOrgEntityProvider" taskId="KeycloakOrgEntityProvider:default:refresh" taskInstanceId="db55c34b-46b3-402b-b12f-2fbc48498e82" trace_id="606f80a9ce00d1c86800718c4522f7c6" span_id="7ebc2a254a546e90" trace_flags="01" - -2025-06-27T16:02:34.650Z catalog info Committed 5 Keycloak users and 3 Keycloak groups in 0.0 seconds. class="KeycloakOrgEntityProvider" taskId="KeycloakOrgEntityProvider:default:refresh" taskInstanceId="db55c34b-46b3-402b-b12f-2fbc48498e82" trace_id="606f80a9ce00d1c86800718c4522f7c6" span_id="7ebc2a254a546e90" trace_flags="01" ----- - -. To verify {rhbk} user authentication: -.. Go to the {product-short} login page. -.. Your {product-short} 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. diff --git a/modules/authentication/snip-enabling-user-authentication-with-github-common-first-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-github-common-first-steps.adoc new file mode 100644 index 0000000000..77f694c023 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-github-common-first-steps.adoc @@ -0,0 +1,130 @@ +:_mod-docs-content-type: SNIPPET +.Procedure +. Allow {product-short} to authenticate with GitHub, by creating a GitHub App. ++ +[NOTE] +==== +Use a GitHub App instead of an OAuth app to use fine-grained permissions, use short-lived tokens, scale with the number of installations by avoiding rate limits, and have a more transparent integration by avoiding to request user input. +==== + +.. link:https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app[Register a GitHub App] with the following configuration: + +GitHub App name:: +Enter a unique name identifying your GitHub App, such as `authenticating-with-rhdh-____`. + +Homepage URL:: +Enter your {product-short} URL: `pass:c,a,q[{my-product-url}]`. + +Authorization callback URL:: +Enter your {product-short} authentication backend URL: `pass:c,a,q[{my-product-url}/api/auth/github/handler/frame]`. + +Webhook:: +Clear "Active". + +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** + +. Add your GitHub credentials to {product-short} by adding the following key/value pairs to {configuring-book-link}#provisioning-your-custom-configuration[your {product-short} secrets]. +You can use these secrets in the {product-short} configuration files by using their environment variable name. + +`GITHUB_CLIENT_ID`:: +Enter the saved **Client ID**. + +`GITHUB_CLIENT_SECRET`:: +Enter the saved **Client Secret**. + +`GITHUB_URL`:: +Enter the GitHub host domain: `github.com`. + +`GITHUB_ORG`:: +Enter your GitHub organization name, such as `____`. + +. Enable the GitHub catalog provider plugin in your `dynamic-plugins.yaml` file to import GitHub users and groups to the {product-short} software catalog. ++ +[source,yaml] +---- +plugins: + - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org' + disabled: false +---- + +. Enable provisioning GitHub users and groups to the {product-short} software catalog by adding the GitHub catalog provider section to your `{my-app-config-file}` file: ++ +[id=githubProviderId] +[source,yaml] +---- +catalog: + providers: + githubOrg: + id: githuborg + githubUrl: "${GITHUB_URL}" + orgs: [ "${GITHUB_ORG}" ] + schedule: + frequency: + minutes: 30 + initialDelay: + seconds: 15 + timeout: + minutes: 15 +---- + +`id`:: +Enter a stable identifier for this provider, such as `githuborg`. +[WARNING] +==== +Entities from this provider are associated with this identifier. +Therefore, do not to change the identifier over time since that might lead to orphaned entities or conflicts. +==== + +`githubUrl`:: +Enter the configured secret variable name: `$\{GITHUB_URL}`. + +`orgs`:: +Enter the configured secret variable name: `$\{GITHUB_ORG}`. + +`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. + +. Enable the GitHub authentication provider, by adding the GitHub authentication provider section to your `{my-app-config-file}` file: ++ +[source,yaml] +---- +auth: + environment: production + providers: + github: + production: + clientId: ${GITHUB_CLIENT_ID} + clientSecret: ${GITHUB_CLIENT_SECRET} +signInPage: github +---- + +`environment`:: +Enter `production` to disable the Guest login option in the {product-short} login page. + +`clientId`:: +Enter the configured secret variable name: `$\{GITHUB_CLIENT_ID}`. + +`clientSecret`:: +Enter the configured secret variable name: `$\{GITHUB_CLIENT_SECRET}`. + +`signInPage`:: +Enter `github` to enable the GitHub provider as your {product-short} sign-in provider. diff --git a/modules/authentication/snip-enabling-user-authentication-with-github-common-prerequisites.adoc b/modules/authentication/snip-enabling-user-authentication-with-github-common-prerequisites.adoc new file mode 100644 index 0000000000..e3d100ebb6 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-github-common-prerequisites.adoc @@ -0,0 +1,9 @@ +:_mod-docs-content-type: SNIPPET +.Prerequisites +* You have enough permissions in GitHub to create and manage a link:https://docs.github.com/en/apps/overview[GitHub App]. ++ +[TIP] +==== +Alternatively, ask your GitHub administrator to prepare the required GitHub App. +==== +* You have {configuring-book-link}[added a custom {product-short} application configuration], and have enough permissions to change it. diff --git a/modules/authentication/snip-enabling-user-authentication-with-github-common-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-github-common-steps.adoc deleted file mode 100644 index de3796dc0e..0000000000 --- a/modules/authentication/snip-enabling-user-authentication-with-github-common-steps.adoc +++ /dev/null @@ -1,64 +0,0 @@ -:_mod-docs-content-type: SNIPPET - -* You have enough permissions in GitHub to create and manage a link:https://docs.github.com/en/apps/overview[GitHub App]. -Alternatively, you can ask your GitHub administrator to prepare the required GitHub App. - -.Procedure -. To allow {product-short} to authenticate with GitHub, create a GitHub App. -Opt for a GitHub App instead of an OAuth app to use fine-grained permissions, use short-lived tokens, scale with the number of installations by avoiding rate limits, and have a more transparent integration by avoiding to request user input. - -.. link:https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app[Register a GitHub App] with the following configuration: - -GitHub App name:: -Enter a unique name identifying your GitHub App, such as `authenticating-with-rhdh-____`. - -Homepage URL:: -Enter your {product-short} URL: `pass:c,a,q[{my-product-url}]`. - -Authorization callback URL:: -Enter your {product-short} authentication backend URL: `pass:c,a,q[{my-product-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 {product-short}, add the following key/value pairs to {configuring-book-link}#provisioning-your-custom-configuration[your {product-short} secrets]. -You can use these secrets in the {product-short} configuration files by using their environment variable name. - -`GITHUB_CLIENT_ID`:: -Enter the saved **Client ID**. - -`GITHUB_CLIENT_SECRET`:: -Enter the saved **Client Secret**. - -`GITHUB_URL`:: -Enter the GitHub host domain: `github.com`. - -`GITHUB_ORG`:: -Enter your GitHub organization name, such as `____`. - -. Enable the GitHub organization provisioning plugin (`backstage-plugin-catalog-backend-module-github-org`). -This plugin imports GitHub users and groups to the {product-short} software catalog. -+ -`dynamic-plugins.yaml` file fragment: -+ -[source,yaml] ----- -plugins: - - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org' - disabled: false ----- diff --git a/modules/authentication/snip-enabling-user-authentication-with-github-common-verification-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-github-common-verification-steps.adoc new file mode 100644 index 0000000000..905c9f88d7 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-github-common-verification-steps.adoc @@ -0,0 +1,19 @@ +:_mod-docs-content-type: SNIPPET +.Verification +. Verify user and group provisioning by checking the console logs. ++ +Successful synchronization example: ++ +[source,json] +---- +{"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 {product-short} login page. +.. Your {product-short} sign-in page displays *Sign in using GitHub* and the Guest user sign-in is disabled. +.. Log in with a GitHub account. + +.Additional resources +* {integrating-with-github-book-link}[{integrating-with-github-book-title}] diff --git a/modules/authentication/snip-enabling-user-authentication-with-github-optional-authentication-provider-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-github-optional-authentication-provider-steps.adoc new file mode 100644 index 0000000000..e307f94f41 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-github-optional-authentication-provider-steps.adoc @@ -0,0 +1,58 @@ +:_mod-docs-content-type: SNIPPET +Optional: Add optional fields to the GitHub authentication provider section in your `{my-app-config-file}` file: + +[source,yaml,subs="+quotes"] +---- +auth: + environment: production + providers: + github: + production: + clientId: ${GITHUB_CLIENT_ID} + clientSecret: ${GITHUB_CLIENT_SECRET} + callbackUrl: ____ + 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: ____. +Define it when {product-short} is not the immediate receiver, such as in cases when you use one OAuth app for many {product-short} 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, {product-short} resolves the user signing in to an existing user in the {product-short} catalog. +Configure a specific resolver to best match users securely for your use case.. ++ +Enter the resolver list to override the default resolver: `usernameMatchingUserEntityName`. ++ +The authentication provider tries each sign-in resolver in order until it succeeds. If none of the attempts succeed, the sign-in fails. ++ +[WARNING] +==== +In production mode, configure only one resolver to make sure users are securely matched. +==== + +`resolver`:::: +Enter the sign-in resolver name. +Available resolvers: + +* `usernameMatchingUserEntityName` +* `preferredUsernameMatchingUserEntityName` +* `emailMatchingUserEntityProfileEmail` + +`dangerouslyAllowSignInWithoutUserInCatalog`:::: +Enter `true` to configure the sign-in resolver to bypass the user provisioning requirement in the {product-short} software catalog. ++ +[WARNING] +==== +In production more, do not enable `dangerouslyAllowSignInWithoutUserInCatalog`. +==== diff --git a/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-authentication-provider-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-authentication-provider-steps.adoc new file mode 100644 index 0000000000..768dbb6395 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-authentication-provider-steps.adoc @@ -0,0 +1,32 @@ +:_mod-docs-content-type: SNIPPET + +Enable {azure-short} authentication, by adding the Microsoft authentication provider to your `{my-app-config-file}` file content: + +[source,yaml,subs="+quotes,+attributes"] +---- +auth: + environment: production + providers: + microsoft: + production: + clientId: ${AUTHENTICATION_AZURE_CLIENT_ID} + clientSecret: ${AUTHENTICATION_AZURE_CLIENT_SECRET} + tenantId: ${AUTHENTICATION_AZURE_TENANT_ID} +signInPage: microsoft +---- + +`environment`:: +Enter `production` to disable the **Guest** login option in the {product-short} login page. + +`clientId`:: +Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_CLIENT_ID}`. + +`clientSecret`:: +Enter the configured secret variable name: +`$\{AUTHENTICATION_AZURE_CLIENT_SECRET}`. + +`tenantId`:: +Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_TENANT_ID}`. + +`signInPage`:: +Enter `microsoft` to set the {azure-short} provider as your {product-short} sign-in provider. diff --git a/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-first-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-first-steps.adoc new file mode 100644 index 0000000000..3980cbd94a --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-first-steps.adoc @@ -0,0 +1,142 @@ +:_mod-docs-content-type: SNIPPET + +Authenticate users with {azure-brand-name} by provisioning the users and groups from {azure-short} to the {product-short} software catalog, and configuring the {azure-short} authentication provider in {product}. + +.Prerequisites +* You have the permission to register an application in {azure-short}. ++ +[TIP] +==== +Alternatively, ask your {azure-short} administrator to prepare the required {azure-short} application. +==== + +* You {configuring-book-link}[added a custom {product-short} application configuration], and have enough permissions to change it. + +* Your {product-short} backend can access the following hosts: + +`login.microsoftonline.com`:: +The {azure-brand-name} authorization server, which enables the authentication flow. + +`graph.microsoft.com`:: +The server for retrieving organization data, including user and group data, to import into the {product-short} catalog. + +.Procedure +:my-product-app-name-in-azure: +. Register your {product-short} app in {azure-short}, link:https://learn.microsoft.com/en-us/entra/identity-platform/scenario-web-app-sign-user-app-registration?tabs=aspnetcore#register-an-app-by-using-the-azure-portal[by using the {azure-short} portal]. + +.. Sign in to the link:https://entra.microsoft.com/[Microsoft Entra admin center]. + +.. Optional: If you have access to multiple tenants, use the *Settings* icon in the top menu to switch to the tenant in which you want to register the application from the *Directories + subscriptions* menu. + +.. Browse to *Applications > App registrations*, and create a **New registration** with the configuration: + +Name:: +Enter a name to identify your application in {azure-short}, such as __{my-product-app-name-in-azure}__. + +Supported account types:: +Select *Accounts in this organizational directory only*. + +Redirect URI:: + +Select a platform::: +Select *Web*. + +URL::: +Enter the backend authentication URI set in {product-short}: `pass:c,a,q[{my-product-url}/api/auth/microsoft/handler/frame]` + +.. On the *Applications > App registrations > __{my-product-app-name-in-azure}__ > Manage > API permissions* page, *Add a Permission*, *Microsoft Graph*, select the following permissions: + +Application Permissions:: +`GroupMember.Read.All`::: +`User.Read.All`::: +Enter permissions that enable provisioning user and groups to the {product-short} software catalog. ++ +Optional: *Grant admin consent* for these permissions. +Even if your company does not require admin consent, consider doing so as it means users do not need to individually consent the first time they access {product-short}. + +Delegated Permissions:: +`User.Read`::: +`email`::: +`offline_access`::: +`openid`::: +`profile`::: +Enter permissions that enable authenticating users. ++ +Optional: Enter optional custom scopes for the Microsoft Graph API that you define both here and in your `{my-app-config-file}` {product-short} configuration file. + +.. On the *Applications > App registrations > __{my-product-app-name-in-azure}__ > Manage > Certificates & secrets* page, in the *Client secrets* tab, create a *New client secret*. + +.. Save the following values for the next step: +- **Directory (tenant) ID** +- **Application (client) ID** +- **Application (client) Secret ID** + +. Add your {azure-short} credentials to {product-short}, by adding the following key/value pairs to {configuring-book-link}#provisioning-your-custom-configuration[your {product-short} secrets]: + +`AUTHENTICATION_AZURE_TENANT_ID`:: +Enter your saved *Directory (tenant) ID*. + +`AUTHENTICATION_AZURE_CLIENT_ID`:: +Enter your saved *Application (client) ID*. + +`AUTHENTICATION_AZURE_CLIENT_SECRET`:: +Enter your saved *Application (client) secret*. + +. Enable the Microsoft Graph catalog provider plugin in your `dynamic-plugins.yaml` +file. +This plugin imports {azure-short} users and groups to the {product-short} software catalog. ++ +[source,yaml] +---- +plugins: + - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-msgraph-dynamic' + disabled: false +---- + +. Enable provisioning {azure-short} users and groups to the {product-short} software catalog, by adding the Microsoft Graph catalog provider section in your `{my-app-config-file}` file: ++ +[id=microsoftGraphOrgProviderId] +[source,yaml] +---- +catalog: + providers: + microsoftGraphOrg: + providerId: + target: https://graph.microsoft.com/v1.0 + tenantId: ${AUTHENTICATION_AZURE_TENANT_ID} + clientId: ${AUTHENTICATION_AZURE_CLIENT_ID} + clientSecret: ${AUTHENTICATION_AZURE_CLIENT_SECRET} + schedule: + frequency: + hours: 1 + timeout: + minutes: 50 + initialDelay: + minutes: 50 +---- + +`target`:: +Enter `\https://graph.microsoft.com/v1.0` to define the MSGraph API endpoint the provider is connecting to. +You might change this parameter to use a different version, such as the link:https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-beta#call-the-beta-endpoint[beta endpoint]. + +`tenandId`:: +Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_TENANT_ID}`. + +`clientId`:: +Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_CLIENT_ID}`. + +`clientSecret`:: +Enter the configured secret variable name: `$\{AUTHENTICATION_AZURE_CLIENT_SECRET}`. + +`schedule`:: + +`frequency`::: +Enter the schedule frequency in the cron, ISO duration, or human duration format. +In a large organization, user provisioning might take a long time, therefore avoid using a low value. + +`timeout`::: +Enter the schedule timeout in the ISO duration or human duration format. +In a large organization, user provisioning might take a long time, therefore avoid using a low value. + +`initialDelay`::: +Enter the schedule initial delay in the ISO duration or human duration format. diff --git a/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-verification-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-verification-steps.adoc new file mode 100644 index 0000000000..f94fedbc83 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-common-verification-steps.adoc @@ -0,0 +1,17 @@ +:_mod-docs-content-type: SNIPPET +.Verification +. To verify user and group provisioning, check the console logs for `MicrosoftGraphOrgEntityProvider` events. ++ +Successful synchronization example: ++ +[source] +---- +2025-06-23T13:37:55.804Z catalog info Read 9 msgraph users and 3 msgraph groups in 1.5 seconds. Committing... class="MicrosoftGraphOrgEntityProvider" taskId="MicrosoftGraphOrgEntityProvider:providerId:refresh" taskInstanceId="e104a116-6481-4ceb-9bc4-0f8f9581f959" trace_id="e4c633659cffd6b1529afa55a5bfbad7" span_id="76affd0420e8baa6" trace_flags="01" + +2025-06-23T13:37:55.811Z catalog info Committed 9 msgraph users and 3 msgraph groups in 0.0 seconds. class="MicrosoftGraphOrgEntityProvider" taskId="MicrosoftGraphOrgEntityProvider:providerId:refresh" taskInstanceId="e104a116-6481-4ceb-9bc4-0f8f9581f959" trace_id="e4c633659cffd6b1529afa55a5bfbad7" span_id="76affd0420e8baa6" trace_flags="01" +---- + +. To verify {azure-short} user authentication: +.. Go to the {product-short} login page. +.. Your {product-short} sign-in page displays *Sign in using Microsoft* and the Guest user sign-in is disabled. +.. Log in with an {azure-short} account. diff --git a/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-optional-authentication-provider-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-optional-authentication-provider-steps.adoc new file mode 100644 index 0000000000..e309f93fe5 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-optional-authentication-provider-steps.adoc @@ -0,0 +1,79 @@ +:_mod-docs-content-type: SNIPPET + +Optional: Add optional fields to the Microsoft authentication provider section in your `{my-app-config-file}` file: + +[source,yaml,subs="+quotes,+attributes"] +---- +auth: + environment: production + providers: + microsoft: + production: + clientId: ${AUTHENTICATION_AZURE_CLIENT_ID} + clientSecret: ${AUTHENTICATION_AZURE_CLIENT_SECRET} + tenantId: ${AUTHENTICATION_AZURE_TENANT_ID} + domainHint: ${AUTHENTICATION_AZURE_TENANT_ID} + additionalScopes: + - Mail.Send + sessionDuration: + hours: 24 + signIn: + resolvers: + - resolver: usernameMatchingUserEntityName + dangerouslyAllowSignInWithoutUserInCatalog: true +signInPage: microsoft +---- + +`domainHint`:: +* Leave this parameter empty, or enter the tenant ID when your application registration is single-tenant. +* Leave this parameter empty when your application registration is multi-tenant. +* Enter the tenant ID to reduce login friction for users with accounts in multiple tenants, by automatically filtering out accounts from other tenants. ++ +For more information, see link:https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/home-realm-discovery-policy[Home Realm Discovery]. + +`additionalScopes`:: +Enter the list of additional scopes to add scopes for the application registration. +The default and mandatory value lists following scopes: +* `openid` +* `offline_access` +* `profile` +* `email` +* `User.Read` + +`sessionDuration`:: +Lifespan of the user session. +Enter a duration in `ms` library (such as '24h', '2 days'), ISO duration, or "human duration" format. + +`signIn.resolvers`:: +After successful authentication, {product-short} resolves the user signing in to an existing user in the {product-short} catalog. +To best match users securely for your use case, consider configuring a specific resolver. ++ +Enter the resolver list to override the default resolver: `userIdMatchingUserEntityAnnotation`. ++ +The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed. ++ +[WARNING] +==== +In production mode, configure only one resolver to make sure users are securely matched. +==== + +`resolver`:: +Enter the sign-in resolver name. +Available resolvers: + +`emailMatchingUserEntityAnnotation`::: +Use this resolver to look up the user by matching their Microsoft email to the email entity annotation. + +`emailLocalPartMatchingUserEntityName`::: +Use this resolver to look up the user by matching their Microsoft email user name to the user entity name. + +`emailMatchingUserEntityProfileEmail`::: +Use this resolver to look up the user by matching their Microsoft email to the user entity profile email. + +`dangerouslyAllowSignInWithoutUserInCatalog`:: +Enter `true` to configure the sign-in resolver to bypass the user provisioning requirement in the {product-short} software catalog. ++ +[WARNING] +==== +In production mode, do not enable `dangerouslyAllowSignInWithoutUserInCatalog`. +==== diff --git a/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-optional-catalog-provider-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-optional-catalog-provider-steps.adoc new file mode 100644 index 0000000000..f285638eae --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-microsoft-azure-optional-catalog-provider-steps.adoc @@ -0,0 +1,91 @@ +:_mod-docs-content-type: SNIPPET + +Optional: Add optional fields to the Microsoft authentication provider section in your `{my-app-config-file}` file: + +[source,yaml] +---- +catalog: + providers: + microsoftGraphOrg: + providerId: + authority: https://login.microsoftonline.com/ + queryMode: advanced + user: + expand: manager + filter: accountEnabled eq true and userType eq 'member' + loadPhotos: true + select: ['id', 'displayName', 'description'] + userGroupMember: + filter: "displayName eq 'Backstage Users'" + search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")' + group: + expand: member + filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified') + search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")' + select: ['id', 'displayName', 'description'] +---- + +`authority`:: +Enter your link:https://learn.microsoft.com/en-us/graph/deployments#app-registration-and-token-service-root-endpoints[{azure-short} authority URL] if it is different from the default: `\https://login.microsoftonline.com`. + +`queryMode`:: +Enter `advanced` when the default `basic` query mode is insufficient for your queries to the Microsoft Graph API. +See link:https://learn.microsoft.com/en-us/graph/aad-advanced-queries[{azure-brand-name} advanced queries]. + +`user`:: +Add this section to configure optional user query parameters. + +`expand`::: +Enter your expansion parameter to include the expanded resource or collection referenced by a single relationship (navigation property) in your results. +A single request can expand only one relationship. +See https://learn.microsoft.com/en-us/graph/query-parameters#expand-parameter[Microsoft Graph query expand parameter]. ++ +You can combine this parameter with `userGroupMember.filter` or `user.filter`. + +`filter`::: +Enter your user filter. +See link:https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0#properties[Microsoft Graph API] and link:https://learn.microsoft.com/en-us/graph/query-parameters#filter-parameter[Microsoft Graph API query filter parameters syntax]. ++ +This parameter and `userGroupMember.filter` are mutually exclusive, specify only one. + +`loadPhotos`::: +{product-short} loads photos by default. +Enter `false` to avoid loading user photos. + +`select`::: +Enter the link:https://learn.microsoft.com/en-us/graph/api/resources/schemaextension?view=graph-rest-1.0[Microsoft Graph resource type] list to retrieve. + +`userGroupMember`:: +Add this section to use group membership to get users. + +`filter`::: +Enter your filter to filter groups and fetch their members. ++ +This parameter and `user.filter` are mutually exclusive, specify only one. + +`search`::: +Enter your search query to search for groups and fetch their members. ++ +This parameter and `user.filter` are mutually exclusive, specify only one. + +`group`:: +Enter your configuration to get groups. + +`expand`::: +Enter your expansion parameter to include the expanded resource or collection referenced by a single relationship (navigation property) in your results. +A single request can expand only one relationship. +See link:https://learn.microsoft.com/en-us/graph/query-parameters#expand-parameter[Customize Microsoft Graph responses with query parameters]. ++ +You can combine this parameter with +`user.filter` or `userGroupMember.filter`. + +`filter`::: +Enter your group filter parameter. +See link:https://learn.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0#properties[Microsoft Graph API query group syntax]. + +`search`::: +Enter your group search parameter. +See link:https://learn.microsoft.com/en-us/graph/search-query-parameter[Microsoft Graph API query search parameter]. + +`select`::: +Enter the link:https://learn.microsoft.com/en-us/graph/api/resources/schemaextension?view=graph-rest-1.0[Microsoft Graph resource type] list to retrieve. diff --git a/modules/authentication/snip-enabling-user-authentication-with-rhbk-common-authentication-provider-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-rhbk-common-authentication-provider-steps.adoc new file mode 100644 index 0000000000..436742593c --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-rhbk-common-authentication-provider-steps.adoc @@ -0,0 +1,31 @@ +:_mod-docs-content-type: SNIPPET + +Enable the {rhbk} authentication provider, by adding the OIDC provider section in your `{my-app-config-file}` file: + +[source,yaml] +---- +auth: + environment: production + providers: + oidc: + production: + metadataUrl: ${KEYCLOAK_BASE_URL} + clientId: ${KEYCLOAK_CLIENT_ID} + clientSecret: ${KEYCLOAK_CLIENT_SECRET} + prompt: auto +signInPage: oidc +---- + +`environment: production`:: +Mark the environment as `production` to hide the Guest login in the {product-short} home page. + +`metadataUrl`, `clientId`, `clientSecret`:: +Configure the OIDC provider with your secrets. + +`prompt`:: +Enter `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. ++ +The identity provider defaults to `none`, which assumes that you are already logged in. Sign-in requests without an active session are rejected. + +`signInPage`:: +Enter `oidc` to enable the OIDC provider as default sign-in provider. diff --git a/modules/authentication/snip-enabling-user-authentication-with-rhbk-common-first-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-rhbk-common-first-steps.adoc new file mode 100644 index 0000000000..d761eb73e4 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-rhbk-common-first-steps.adoc @@ -0,0 +1,87 @@ +:_mod-docs-content-type: SNIPPET + +Authenticate users with {rhbk-brand-name} ({rhbk}), by provisioning the users and groups from {rhbk} to the {product-short} software catalog, and configuring the OpenID Connect (OIDC) authentication provider in {product}. + +.Prerequisites +* You {configuring-book-link}[added a custom {product-short} application configuration], and have enough permissions to change it. +* You have enough permissions in {rhsso} to create and manage a realm and a client. ++ +[TIP] +==== +Alternatively, ask your {rhbk} administrator to prepare in {rhbk} the required realm and client. +==== + +.Procedure +. Register your {product-short} app in {rhbk}: + +.. Use an existing realm, or {rhbk-docs-link}/html/getting_started_guide/getting-started-zip-#getting-started-zip-create-a-realm[create a realm], with a distinctive **Name** such as ____. +Save the value for the next step: +* **{rhbk} realm base URL**, such as: ____/realms/____. + +.. To register your {product-short} in {rhbk}, in the created realm, {rhbk-docs-link}/html-single/getting_started_guide/index#getting-started-zip-secure-the-first-application[secure the first application], with: +... **Client ID**: A distinctive client ID, such as __<{product-very-short}>__. +... **Valid redirect URIs**: Set to the OIDC handler URL: `pass:c,a,q[{my-product-url}/api/auth/oidc/handler/frame]`. +... Go 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 {rhbk-docs-link}/html-single/getting_started_guide/index#getting-started-zip-create-a-user[create a user]. +Save the user credential information for the verification steps. + +. Add your {rhsso} credentials to {product-short}, by +adding the following key/value pairs to {configuring-dynamic-plugins-book-link}#provisioning-your-custom-configuration[your {product-short} secrets]. +You can use these secrets in the {product-short} configuration files by using their environment variable name. ++ +`KEYCLOAK_CLIENT_ID`:: +Enter the saved **Client ID**. + +`KEYCLOAK_CLIENT_SECRET`:: +Enter the saved **Client Secret**. + +`KEYCLOAK_BASE_URL`:: +Enter the saved **{rhbk} realm base URL**. + +. Enable the Keycloak catalog provider plugin in your `dynamic-plugins.yaml` file. ++ +The plugin is named after {rhbk} upstream project. ++ +This plugin imports {rhbk} users and groups to the {product-short} software catalog. ++ +[source,yaml] +---- +plugins: + - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-keycloak-dynamic' + disabled: false +---- + +. Enable provisioning {rhbk} users and groups to the {product-short} software catalog, by adding the `catalog.providers.keycloakOrg` section to your `{my-app-config-file}` file: ++ +[id=keycloakOrgProviderId] +[source,yaml] +---- +catalog: + providers: + keycloakOrg: + default: + baseUrl: ${KEYCLOAK_BASE_URL} + clientId: ${KEYCLOAK_CLIENT_ID} + clientSecret: ${KEYCLOAK_CLIENT_SECRET} + realm: master + loginRealm: master +---- + +`baseUrl`:: +Enter your {rhbk} server URL, defined earlier. + +`clientId`:: +Enter your {product-short} application client ID in {rhbk}, defined earlier. + +`clientSecret`:: +Enter your {product-short} application client secret in {rhbk}, defined earlier. + +`realm`:: +Enter the realm name to provision users, such as `master`. + +`loginRealm`:: +Enter the realm name to authenticate users, such as `master`. diff --git a/modules/authentication/snip-enabling-user-authentication-with-rhbk-optional-authentication-provider-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-rhbk-optional-authentication-provider-steps.adoc new file mode 100644 index 0000000000..df79906ec2 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-rhbk-optional-authentication-provider-steps.adoc @@ -0,0 +1,96 @@ +:_mod-docs-content-type: SNIPPET + +Optional: Add optional fields to the OIDC authentication provider section in your `{my-app-config-file}` file: + +[source,yaml] +---- +auth: + providers: + oidc: + production: + metadataUrl: ${KEYCLOAK_BASE_URL} + clientId: ${KEYCLOAK_CLIENT_ID} + clientSecret: ${KEYCLOAK_CLIENT_SECRET} + callbackUrl: ${KEYCLOAK_CALLBACK_URL} + tokenEndpointAuthMethod: ${KEYCLOAK_TOKEN_ENDPOINT_METHOD} + tokenSignedResponseAlg: ${KEYCLOAK_SIGNED_RESPONSE_ALG} + additionalScopes: ${KEYCLOAK_SCOPE} + signIn: + resolvers: + - resolver: oidcSubClaimMatchingKeycloakUserId + - resolver: preferredUsernameMatchingUserEntityName + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + dangerouslyAllowSignInWithoutUserInCatalog: true + sessionDuration: { hours: 24 } + backstageTokenExpiration: { minutes: __ } +signInPage: oidc +---- + +`callbackUrl`:: +{rhbk} callback URL. + +`tokenEndpointAuthMethod`:: +Enter your token endpoint authentication method. + +`tokenSignedResponseAlg`:: +Token signed response algorithm. + +`additionalScopes`:: +Enter additional {rhbk} scopes to request for during the authentication flow. + +`signIn`:: +`resolvers`::: +After successful authentication, the user signing in must be resolved to an existing user in the {product-short} 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`. ++ +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. ++ +The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed. ++ +[WARNING] +==== +In production mode, configure only one resolver to make sure users are securely matched. +==== + +`dangerouslyAllowSignInWithoutUserInCatalog: true`:::: +Configure the sign-in resolver to bypass the user provisioning requirement in the {product-short} software catalog. ++ +[WARNING] +==== +In production mode, do not enable the `dangerouslyAllowSignInWithoutUserInCatalog` option. +==== + +`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. + +`backstageTokenExpiration`:: +Enter a value to modify the {product-short} token expiration from its default value of one hour. +It refers to the validity of short-term cryptographic tokens, not to the session duration. +The expiration value must be set between 10 minutes and 24 hours. ++ +[WARNING] +==== +If multiple valid refresh tokens are issued due to frequent refresh token requests, older tokens will remain valid until they expire. +Enhance security and prevent potential misuse of older tokens by enabling 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. +==== diff --git a/modules/authentication/snip-enabling-user-authentication-with-rhbk-optional-catalog-provider-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-rhbk-optional-catalog-provider-steps.adoc new file mode 100644 index 0000000000..03807ca6d6 --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-rhbk-optional-catalog-provider-steps.adoc @@ -0,0 +1,43 @@ +:_mod-docs-content-type: SNIPPET + +Optional: Add optional fields to the keycloackOrg catalog provider section in your `{my-app-config-file}` file: + +[source,yaml] +---- +catalog: + providers: + keycloakOrg: + default: + baseUrl: ${KEYCLOAK_BASE_URL} + clientId: ${KEYCLOAK_CLIENT_ID} + clientSecret: ${KEYCLOAK_CLIENT_SECRET} + realm: master + loginRealm: master + userQuerySize: 100 + groupQuerySize: 100 + schedule: + frequency: { hours: 1 } + timeout: { minutes: 50 } + initialDelay: { seconds: 15} +---- + +`userQuerySize`:: +Enter the user count to query simultaneously. +Default value: `100`. + +`groupQuerySize`:: +Enter the group count to query simultaneously. +Default value: `100`. + +`schedule`:: +`frequency`::: +Enter the schedule frequency. +Supports cron, ISO duration, and "human duration" as used in code. + +`timeout`::: +Enter the timeout for the user provisioning job. +Supports ISO duration and "human duration" as used in code. + +`initialDelay`::: +Enter the initial delay to wait for before starting the user provisioning job. +Supports ISO duration and "human duration" as used in code. diff --git a/modules/authentication/snip-enabling-user-authentication-with-rhbk-verification-steps.adoc b/modules/authentication/snip-enabling-user-authentication-with-rhbk-verification-steps.adoc new file mode 100644 index 0000000000..08abe1adaa --- /dev/null +++ b/modules/authentication/snip-enabling-user-authentication-with-rhbk-verification-steps.adoc @@ -0,0 +1,17 @@ +:_mod-docs-content-type: SNIPPET +.Verification +. To verify user and group provisioning, check the console logs. ++ +Successful synchronization example: ++ +[source] +---- +2025-06-27T16:02:34.647Z catalog info Read 5 Keycloak users and 3 Keycloak groups in 0.4 seconds. Committing... class="KeycloakOrgEntityProvider" taskId="KeycloakOrgEntityProvider:default:refresh" taskInstanceId="db55c34b-46b3-402b-b12f-2fbc48498e82" trace_id="606f80a9ce00d1c86800718c4522f7c6" span_id="7ebc2a254a546e90" trace_flags="01" + +2025-06-27T16:02:34.650Z catalog info Committed 5 Keycloak users and 3 Keycloak groups in 0.0 seconds. class="KeycloakOrgEntityProvider" taskId="KeycloakOrgEntityProvider:default:refresh" taskInstanceId="db55c34b-46b3-402b-b12f-2fbc48498e82" trace_id="606f80a9ce00d1c86800718c4522f7c6" span_id="7ebc2a254a546e90" trace_flags="01" +---- + +. To verify {rhbk} user authentication: +.. Go to the {product-short} login page. +.. Your {product-short} 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. diff --git a/modules/configuring/snip-provisioning-your-custom-configuration-appconfig-step-with-optional-steps-disabled.adoc b/modules/configuring/snip-provisioning-your-custom-configuration-appconfig-step-with-optional-steps-disabled.adoc index 5f68885c65..f37c087ba1 100644 --- a/modules/configuring/snip-provisioning-your-custom-configuration-appconfig-step-with-optional-steps-disabled.adoc +++ b/modules/configuring/snip-provisioning-your-custom-configuration-appconfig-step-with-optional-steps-disabled.adoc @@ -18,25 +18,9 @@ techdocs: ttl: 3600000 catalog: providers: - github: - providerId: - organization: "${GITHUB_INTEGRATION_ORGANIZATION}" - schedule: - frequency: - minutes: 30 - initialDelay: - seconds: 15 - timeout: - minutes: 15 + __ integrations: - github: - - host: ${GITHUB_INTEGRATION_HOST_DOMAIN} - apps: - - appId: ${GITHUB_INTEGRATION_APP_ID} - clientId: ${GITHUB_INTEGRATION_CLIENT_ID} - clientSecret: ${GITHUB_INTEGRATION_CLIENT_SECRET} - privateKey: | - ${GITHUB_INTEGRATION_PRIVATE_KEY_FILE} + __ permission: enabled: true rbac: @@ -60,9 +44,9 @@ Optionally, customize the width of the branding logo by changing value for the ` `cache`::: Enable the Techdocs cache. `catalog`:: `provider`::: -`github`:::: Enable GitHub repository discovery. +Enter your catalog provider configuration. `integrations`:: -`github`::: Enable GitHub repository discovery. +Enter your repository discovery configuration. [id='enabling-and-giving-access-to-rbac'] `permissions`:: Enable Role-based access control. Enter your policy administrator name.