From a874dd1524a3b665c64d9b693a2935d3e89fc83d Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 12 Apr 2024 14:01:02 -0500 Subject: [PATCH 1/4] Added SingIn Resolvers Config Details Signed-off-by: Andre Wanlin --- docs/auth/atlassian/provider.md | 7 +++++ docs/auth/github/provider.md | 7 +++++ docs/auth/gitlab/provider.md | 7 +++++ docs/auth/google/gcp-iap-auth.md | 28 +++++++++++++++++++ docs/auth/google/provider.md | 7 +++++ docs/auth/microsoft/provider.md | 7 +++++ docs/auth/oauth2-proxy/provider.md | 10 ++++++- docs/auth/okta/provider.md | 7 +++++ docs/auth/vmware-cloud/provider.md | 7 +++++ .../building-backends/08-migrating.md | 4 +-- 10 files changed, 88 insertions(+), 3 deletions(-) diff --git a/docs/auth/atlassian/provider.md b/docs/auth/atlassian/provider.md index 2680370d93..cdd18bdc33 100644 --- a/docs/auth/atlassian/provider.md +++ b/docs/auth/atlassian/provider.md @@ -47,8 +47,15 @@ auth: clientId: ${AUTH_ATLASSIAN_CLIENT_ID} clientSecret: ${AUTH_ATLASSIAN_CLIENT_SECRET} scope: ${AUTH_ATLASSIAN_SCOPES} + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: usernameMatchingUserEntityName ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + The Atlassian provider is a structure with three configuration keys: - `clientId`: The Key you generated in the developer console. diff --git a/docs/auth/github/provider.md b/docs/auth/github/provider.md index 353b8ebe08..2ff8e0836d 100644 --- a/docs/auth/github/provider.md +++ b/docs/auth/github/provider.md @@ -41,8 +41,15 @@ auth: clientSecret: ${AUTH_GITHUB_CLIENT_SECRET} ## uncomment if using GitHub Enterprise # enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL} + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: usernameMatchingUserEntityName ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + The GitHub provider is a structure with three configuration keys: - `clientId`: The client ID that you generated on GitHub, e.g. diff --git a/docs/auth/gitlab/provider.md b/docs/auth/gitlab/provider.md index ed7fa6aec3..fc4dac8164 100644 --- a/docs/auth/gitlab/provider.md +++ b/docs/auth/gitlab/provider.md @@ -43,8 +43,15 @@ auth: # audience: https://gitlab.company.com ## uncomment if using a custom redirect URI # callbackUrl: https://${BASE_URL}/api/auth/gitlab/handler/frame + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: usernameMatchingUserEntityName ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + The GitLab provider is a structure with three configuration keys: - `clientId`: The Application ID that you generated on GitLab, e.g. diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md index 410008b22e..911ee4e263 100644 --- a/docs/auth/google/gcp-iap-auth.md +++ b/docs/auth/google/gcp-iap-auth.md @@ -27,8 +27,15 @@ auth: gcp-iap: audience: '/projects//global/backendServices/' jwtHeader: x-custom-header # Optional: Only if you are using a custom header for the IAP JWT + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: emailMatchingUserEntityAnnotation ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + The full `audience` value can be obtained by visiting your [Identity-Aware Proxy Google Cloud console](https://console.cloud.google.com/security/iap), selecting your project, finding your Backend Service to proxy, clicking the 3 vertical dots then "Get JWT Audience Code", and copying from the resulting popup, which will look similar to the following: ![Identity-Aware Proxy JWT Audience Code popup](../../assets/auth/gcp-iap-jwt-audience-code-popup.png) @@ -94,6 +101,27 @@ Now the backend is ready to serve auth requests on the `/api/auth/gcp-iap/refresh` endpoint. All that's left is to update the frontend sign-in mechanism to poll that endpoint through the IAP, on the user's behalf. +### New Backend System + +There is a module for this provider that works with the new backend system. + +First you'll want to run this command to add the module: + +```sh + yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gcp-iap-provider +``` + +Then you will need to add this to your backend: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-gcp-iap-provider')); +/* highlight-add-end */ +``` + ## Frontend Changes It is recommended to use the `ProxiedSignInPage` for this provider, which is diff --git a/docs/auth/google/provider.md b/docs/auth/google/provider.md index d3cd8f2dd2..9b611c2fc9 100644 --- a/docs/auth/google/provider.md +++ b/docs/auth/google/provider.md @@ -42,8 +42,15 @@ auth: development: clientId: ${AUTH_GOOGLE_CLIENT_ID} clientSecret: ${AUTH_GOOGLE_CLIENT_SECRET} + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: emailMatchingUserEntityAnnotation ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + The Google provider is a structure with two configuration keys: - `clientId`: The client ID that you generated, e.g. diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index bb8a7db6e4..d3dd32f7c8 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -57,8 +57,15 @@ auth: domainHint: ${AZURE_TENANT_ID} additionalScopes: - Mail.Send + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: emailMatchingUserEntityAnnotation ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + The Microsoft provider is a structure with three mandatory configuration keys: - `clientId`: Application (client) ID, found on App Registration > Overview diff --git a/docs/auth/oauth2-proxy/provider.md b/docs/auth/oauth2-proxy/provider.md index ef11827039..507fc3d2bf 100644 --- a/docs/auth/oauth2-proxy/provider.md +++ b/docs/auth/oauth2-proxy/provider.md @@ -22,9 +22,17 @@ The provider configuration can be added to your `app-config.yaml` under the root auth: environment: development providers: - oauth2Proxy: {} + oauth2Proxy: + development: + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: forwardedUserMatchingUserEntityName ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + Right now no configuration options are supported, but the empty object is needed to enable the provider in the auth backend. diff --git a/docs/auth/okta/provider.md b/docs/auth/okta/provider.md index 2242e4a0f0..ff113d94ed 100644 --- a/docs/auth/okta/provider.md +++ b/docs/auth/okta/provider.md @@ -47,8 +47,15 @@ auth: idp: ${AUTH_OKTA_IDP} # Optional # https://developer.okta.com/docs/reference/api/oidc/#scope-dependent-claims-not-always-returned additionalScopes: ${AUTH_OKTA_ADDITIONAL_SCOPES} # Optional + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: emailMatchingUserEntityAnnotation ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + The values referenced are found on the Application page on your Okta site. - `clientId`: The client ID that you generated on Okta, e.g. diff --git a/docs/auth/vmware-cloud/provider.md b/docs/auth/vmware-cloud/provider.md index 20115f9e75..db62b9e985 100644 --- a/docs/auth/vmware-cloud/provider.md +++ b/docs/auth/vmware-cloud/provider.md @@ -156,8 +156,15 @@ auth: development: clientId: ${APP_ID} organizationId: ${ORG_ID} + signIn: + resolvers: + - resolver: emailMatchingUserEntityProfileEmail + - resolver: emailLocalPartMatchingUserEntityName + - resolver: vmwareCloudSignInResolvers ``` +> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + where `APP_ID` refers to the ID retrieved when creating the OAuth App, and `ORG_ID` is the [long ID of the Organization](https://docs.vmware.com/en/VMware-Cloud-services/services/Using-VMware-Cloud-Services/GUID-CF9E9318-B811-48CF-8499-9419997DC1F8.html#view-the-organization-id-1) diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index 1d7e1dcd03..0fbb368449 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -816,9 +816,9 @@ auth: tenantId: ${AZURE_TENANT_ID} signIn: resolvers: - - resolver: emailMatchingUserEntityAnnotation - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName + - resolver: emailMatchingUserEntityAnnotation ``` > Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. @@ -848,7 +848,7 @@ Additional resolvers: - [usernameMatchingUserEntityName](https://github.com/backstage/backstage/blob/5447cffd23cf00772988fb799ced0ec5e54efb2e/plugins/auth-backend-module-atlassian-provider/src/resolvers.ts#L33C16-L33C46) -##### GCP IAM +##### GCP IAP (Google Identity-Aware Proxy) Setup: From 8383e2ca7d4aceb761ec0cf23efb8ca5643d0415 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Tue, 16 Apr 2024 11:03:28 -0500 Subject: [PATCH 2/4] Added dedicated resolvers section Signed-off-by: Andre Wanlin --- docs/auth/atlassian/provider.md | 14 +++++++++-- docs/auth/github/provider.md | 14 +++++++++-- docs/auth/gitlab/provider.md | 14 +++++++++-- docs/auth/google/gcp-iap-auth.md | 14 +++++++++-- docs/auth/google/provider.md | 14 +++++++++-- docs/auth/microsoft/provider.md | 14 +++++++++-- docs/auth/oauth2-proxy/provider.md | 40 ++++++------------------------ docs/auth/okta/provider.md | 16 +++++++++--- docs/auth/vmware-cloud/provider.md | 20 +++++++++------ 9 files changed, 105 insertions(+), 55 deletions(-) diff --git a/docs/auth/atlassian/provider.md b/docs/auth/atlassian/provider.md index cdd18bdc33..2082c97b85 100644 --- a/docs/auth/atlassian/provider.md +++ b/docs/auth/atlassian/provider.md @@ -54,8 +54,6 @@ auth: - resolver: usernameMatchingUserEntityName ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - The Atlassian provider is a structure with three configuration keys: - `clientId`: The Key you generated in the developer console. @@ -64,6 +62,18 @@ The Atlassian provider is a structure with three configuration keys: **NOTE:** the scopes `offline_access`, `read:jira-work`, and `read:jira-user` are provided by default. +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `usernameMatchingUserEntityName`: Matches the username from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `atlassianAuthApi` reference and diff --git a/docs/auth/github/provider.md b/docs/auth/github/provider.md index 2ff8e0836d..b24e47f0d9 100644 --- a/docs/auth/github/provider.md +++ b/docs/auth/github/provider.md @@ -48,8 +48,6 @@ auth: - resolver: usernameMatchingUserEntityName ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - The GitHub provider is a structure with three configuration keys: - `clientId`: The client ID that you generated on GitHub, e.g. @@ -62,6 +60,18 @@ The GitHub provider is a structure with three configuration keys: `https://your-intermediate-service.com/handler`. Only needed if Backstage is not the immediate receiver (e.g. one OAuth app for many backstage instances). +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `usernameMatchingUserEntityName`: Matches the username from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `githubAuthApi` reference and diff --git a/docs/auth/gitlab/provider.md b/docs/auth/gitlab/provider.md index fc4dac8164..5ba17289d6 100644 --- a/docs/auth/gitlab/provider.md +++ b/docs/auth/gitlab/provider.md @@ -50,8 +50,6 @@ auth: - resolver: usernameMatchingUserEntityName ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - The GitLab provider is a structure with three configuration keys: - `clientId`: The Application ID that you generated on GitLab, e.g. @@ -63,6 +61,18 @@ The GitLab provider is a structure with three configuration keys: `https://$backstage.acme.corp/api/auth/gitlab/handler/frame` Note: Due to a peculiarity with GitLab OAuth, ensure there is no trailing `/` after 'frame' in the URL. +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `usernameMatchingUserEntityName`: Matches the username from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `gitlabAuthApi` reference and diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md index 911ee4e263..a660627b7e 100644 --- a/docs/auth/google/gcp-iap-auth.md +++ b/docs/auth/google/gcp-iap-auth.md @@ -34,8 +34,6 @@ auth: - resolver: emailMatchingUserEntityAnnotation ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - The full `audience` value can be obtained by visiting your [Identity-Aware Proxy Google Cloud console](https://console.cloud.google.com/security/iap), selecting your project, finding your Backend Service to proxy, clicking the 3 vertical dots then "Get JWT Audience Code", and copying from the resulting popup, which will look similar to the following: ![Identity-Aware Proxy JWT Audience Code popup](../../assets/auth/gcp-iap-jwt-audience-code-popup.png) @@ -43,6 +41,18 @@ The full `audience` value can be obtained by visiting your [Identity-Aware Proxy This config section must be in place for the provider to load at all. Now let's add the provider itself. +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `google.com/email` annotation matches. If no match is found it will throw a `NotFoundError`. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + ## Backend Changes This provider is not enabled by default in the auth backend code, because diff --git a/docs/auth/google/provider.md b/docs/auth/google/provider.md index 9b611c2fc9..c5429486ef 100644 --- a/docs/auth/google/provider.md +++ b/docs/auth/google/provider.md @@ -49,14 +49,24 @@ auth: - resolver: emailMatchingUserEntityAnnotation ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - The Google provider is a structure with two configuration keys: - `clientId`: The client ID that you generated, e.g. `10023341500512-beui241gjwwkrdkr2eh7dprewj2pp1q.apps.googleusercontent.com` - `clientSecret`: The client secret tied to the generated client ID. +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `google.com/email` annotation matches. If no match is found it will throw a `NotFoundError`. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `googleAuthApi` reference and diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index d3dd32f7c8..5e4dac32b5 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -64,8 +64,6 @@ auth: - resolver: emailMatchingUserEntityAnnotation ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - The Microsoft provider is a structure with three mandatory configuration keys: - `clientId`: Application (client) ID, found on App Registration > Overview @@ -77,6 +75,18 @@ The Microsoft provider is a structure with three mandatory configuration keys: For more details, see [Home Realm Discovery](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/home-realm-discovery-policy) - `additionalScopes` (optional): List of scopes for the App Registration. The default and mandatory value is ['user.read']. +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `microsoft.com/email` annotation matches. If no match is found it will throw a `NotFoundError`. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `microsoftAuthApiRef` reference and diff --git a/docs/auth/oauth2-proxy/provider.md b/docs/auth/oauth2-proxy/provider.md index 507fc3d2bf..96dc217486 100644 --- a/docs/auth/oauth2-proxy/provider.md +++ b/docs/auth/oauth2-proxy/provider.md @@ -31,43 +31,17 @@ auth: - resolver: forwardedUserMatchingUserEntityName ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. +### Resolvers -Right now no configuration options are supported, but the empty object is needed -to enable the provider in the auth backend. +This provider includes several resolvers out of the box that you can use: -To use the `oauth2Proxy` provider you must also configure it with a sign-in resolver. -For more information about the sign-in process in general, see the -[Sign-in Identities and Resolvers](../identity-resolver.md) documentation. +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `forwardedUserMatchingUserEntityName`: Matches the value in the `x-forwarded-user` header from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. -For the `oauth2Proxy` provider, the sign-in result is quite different than other providers. -Because it's a proxy provider that can be configured to forward information through -arbitrary headers, the auth result simply just gives you access to the HTTP headers -of the incoming request. Using these you can either extract the information directly, -or grab ID or access tokens to look up additional information and/or validate the request. +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. -A simple sign-in resolver might for example look like this: - -```ts -providerFactories: { - ...defaultAuthProviderFactories, - oauth2Proxy: providers.oauth2Proxy.create({ - signIn: { - async resolver({ result }, ctx) { - const name = result.getHeader('x-forwarded-user'); - if (!name) { - throw new Error('Request did not contain a user') - } - return ctx.signInWithCatalogUser({ - entityRef: { name }, - }); - }, - }, - }), -}, -``` - -[An example on how to sign a user in without a matching user](https://github.com/backstage/backstage/blob/master/packages/backend/src/plugins/auth.ts) +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. ## Adding the provider to the Backstage frontend diff --git a/docs/auth/okta/provider.md b/docs/auth/okta/provider.md index ff113d94ed..163612c4a7 100644 --- a/docs/auth/okta/provider.md +++ b/docs/auth/okta/provider.md @@ -29,7 +29,7 @@ To add Okta authentication, you must create an Application from Okta: The configuration examples provided above are suitable for local development. For a production deployment, substitute `http://localhost:7007` with the url that your Backstage instance is available at. -# Configuration +## Configuration The provider configuration can then be added to your `app-config.yaml` under the root `auth` configuration: @@ -54,8 +54,6 @@ auth: - resolver: emailMatchingUserEntityAnnotation ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - The values referenced are found on the Application page on your Okta site. - `clientId`: The client ID that you generated on Okta, e.g. @@ -68,6 +66,18 @@ The values referenced are found on the Application page on your Okta site. `additionalScopes` is an optional value, a string of space separated scopes, that will be combined with the default `scope` value of `openid profile email offline_access` to adjust the `scope` sent to Okta during OAuth. This will have an impact on [the dependent claims returned](https://developer.okta.com/docs/reference/api/oidc/#scope-dependent-claims-not-always-returned). For example, setting the `additionalScopes` value to `groups` will result in the claim returning a list of the groups that the user is a member of that also match the ID token group filter of the client app. +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `emailMatchingUserEntityAnnotation`: Matches the email address from the auth provider with the User entity where the value of the `okta.com/email` annotation matches. If no match is found it will throw a `NotFoundError`. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. + ## Adding the provider to the Backstage frontend To add the provider to the frontend, add the `oktaAuthApi` reference and diff --git a/docs/auth/vmware-cloud/provider.md b/docs/auth/vmware-cloud/provider.md index db62b9e985..62a653baf0 100644 --- a/docs/auth/vmware-cloud/provider.md +++ b/docs/auth/vmware-cloud/provider.md @@ -107,10 +107,6 @@ export default async function createPlugin( In the above, `commonSignInResolvers.emailLocalPartMatchingUserEntityName()` can be replaced with a more suitable resolver for the app in question. -## Configure Sign-in Resolution - -See [Sign-in Identities and Resolvers](../identity-resolver.md) for details. - ## Add to Sign-in Page See the [Sign-In Configuration](../index.md#sign-in-configuration) docs for @@ -163,9 +159,7 @@ auth: - resolver: vmwareCloudSignInResolvers ``` -> Note: the resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. - -where `APP_ID` refers to the ID retrieved when creating the OAuth App, and +Where `APP_ID` refers to the ID retrieved when creating the OAuth App, and `ORG_ID` is the [long ID of the Organization](https://docs.vmware.com/en/VMware-Cloud-services/services/Using-VMware-Cloud-Services/GUID-CF9E9318-B811-48CF-8499-9419997DC1F8.html#view-the-organization-id-1) in VMware Cloud for which you wish to enable sign-in. @@ -176,3 +170,15 @@ library used by this provider requires the use of Express session middleware to do this. Therefore the value `your session secret` under `auth.session.secret` should be replaced with a long, complex and unique string which will act as a key for signing session cookies set by Backstage. + +### Resolvers + +This provider includes several resolvers out of the box that you can use: + +- `emailMatchingUserEntityProfileEmail`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will throw a `NotFoundError`. +- `emailLocalPartMatchingUserEntityName`: Matches the [local part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the email address from the auth provider with the User entity that has a matching `name`. If no match is found it will throw a `NotFoundError`. +- `vmwareCloudSignInResolvers`: Matches the email address from the auth provider with the User entity that has a matching `spec.profile.email`. If no match is found it will sign in the user without associating with a catalog user. + +> Note: The resolvers will be tried in order, but will only be skipped if they throw a `NotFoundError`. + +If these resolvers do not fit your needs you can build a custom resolver, this is covered in the [Building Custom Resolvers](../identity-resolver.md#building-custom-resolvers) section of the Sign-in Identities and Resolvers documentation. From 79d1c082438da505e1a6a62bc89cae12320189bd Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Tue, 30 Apr 2024 08:03:22 -0500 Subject: [PATCH 3/4] Invert sections Signed-off-by: Andre Wanlin --- docs/auth/google/gcp-iap-auth.md | 48 ++++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md index a660627b7e..4be18e5e50 100644 --- a/docs/auth/google/gcp-iap-auth.md +++ b/docs/auth/google/gcp-iap-auth.md @@ -55,9 +55,30 @@ If these resolvers do not fit your needs you can build a custom resolver, this i ## Backend Changes -This provider is not enabled by default in the auth backend code, because -besides the config section above, it also needs to be given one or more -callbacks in actual code as well as described below. +There is a module for this provider that you will need to add to your backend. + +First you'll want to run this command to add the module: + +```sh + yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gcp-iap-provider +``` + +Then you will need to add this to your backend: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-gcp-iap-provider')); +/* highlight-add-end */ +``` + +### Legacy Backend Changes + +If you are still using the legacy backend you will need to make the changes outlined here. + +This provider is not enabled by default in the auth backend code, because besides the config section above, it also needs to be given one or more callbacks in actual code as well as described below. Add a `providerFactories` entry to the router in `packages/backend/src/plugins/auth.ts`. @@ -111,27 +132,6 @@ Now the backend is ready to serve auth requests on the `/api/auth/gcp-iap/refresh` endpoint. All that's left is to update the frontend sign-in mechanism to poll that endpoint through the IAP, on the user's behalf. -### New Backend System - -There is a module for this provider that works with the new backend system. - -First you'll want to run this command to add the module: - -```sh - yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-gcp-iap-provider -``` - -Then you will need to add this to your backend: - -```ts title="packages/backend/src/index.ts" -const backend = createBackend(); - -backend.add(import('@backstage/plugin-auth-backend')); -/* highlight-add-start */ -backend.add(import('@backstage/plugin-auth-backend-module-gcp-iap-provider')); -/* highlight-add-end */ -``` - ## Frontend Changes It is recommended to use the `ProxiedSignInPage` for this provider, which is From 7a4f604177f6de42a2df81f5981704b5b7f0a8bd Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Tue, 30 Apr 2024 11:13:42 -0500 Subject: [PATCH 4/4] Added comment about only picking one resolver Signed-off-by: Andre Wanlin --- docs/auth/atlassian/provider.md | 1 + docs/auth/github/provider.md | 1 + docs/auth/gitlab/provider.md | 1 + docs/auth/google/gcp-iap-auth.md | 1 + docs/auth/google/provider.md | 1 + docs/auth/microsoft/provider.md | 1 + docs/auth/oauth2-proxy/provider.md | 1 + docs/auth/okta/provider.md | 1 + docs/auth/vmware-cloud/provider.md | 1 + 9 files changed, 9 insertions(+) diff --git a/docs/auth/atlassian/provider.md b/docs/auth/atlassian/provider.md index 2082c97b85..d6f19ee791 100644 --- a/docs/auth/atlassian/provider.md +++ b/docs/auth/atlassian/provider.md @@ -49,6 +49,7 @@ auth: scope: ${AUTH_ATLASSIAN_SCOPES} signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: usernameMatchingUserEntityName diff --git a/docs/auth/github/provider.md b/docs/auth/github/provider.md index b24e47f0d9..2c3aaeaf7d 100644 --- a/docs/auth/github/provider.md +++ b/docs/auth/github/provider.md @@ -43,6 +43,7 @@ auth: # enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL} signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: usernameMatchingUserEntityName diff --git a/docs/auth/gitlab/provider.md b/docs/auth/gitlab/provider.md index 5ba17289d6..ff6a341667 100644 --- a/docs/auth/gitlab/provider.md +++ b/docs/auth/gitlab/provider.md @@ -45,6 +45,7 @@ auth: # callbackUrl: https://${BASE_URL}/api/auth/gitlab/handler/frame signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: usernameMatchingUserEntityName diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md index 4be18e5e50..709ef2b521 100644 --- a/docs/auth/google/gcp-iap-auth.md +++ b/docs/auth/google/gcp-iap-auth.md @@ -29,6 +29,7 @@ auth: jwtHeader: x-custom-header # Optional: Only if you are using a custom header for the IAP JWT signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: emailMatchingUserEntityAnnotation diff --git a/docs/auth/google/provider.md b/docs/auth/google/provider.md index c5429486ef..f2d2e8524e 100644 --- a/docs/auth/google/provider.md +++ b/docs/auth/google/provider.md @@ -44,6 +44,7 @@ auth: clientSecret: ${AUTH_GOOGLE_CLIENT_SECRET} signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: emailMatchingUserEntityAnnotation diff --git a/docs/auth/microsoft/provider.md b/docs/auth/microsoft/provider.md index 5e4dac32b5..5c4707c151 100644 --- a/docs/auth/microsoft/provider.md +++ b/docs/auth/microsoft/provider.md @@ -59,6 +59,7 @@ auth: - Mail.Send signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: emailMatchingUserEntityAnnotation diff --git a/docs/auth/oauth2-proxy/provider.md b/docs/auth/oauth2-proxy/provider.md index 96dc217486..aded90a1e7 100644 --- a/docs/auth/oauth2-proxy/provider.md +++ b/docs/auth/oauth2-proxy/provider.md @@ -26,6 +26,7 @@ auth: development: signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: forwardedUserMatchingUserEntityName diff --git a/docs/auth/okta/provider.md b/docs/auth/okta/provider.md index 163612c4a7..0c15746cfd 100644 --- a/docs/auth/okta/provider.md +++ b/docs/auth/okta/provider.md @@ -49,6 +49,7 @@ auth: additionalScopes: ${AUTH_OKTA_ADDITIONAL_SCOPES} # Optional signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: emailMatchingUserEntityAnnotation diff --git a/docs/auth/vmware-cloud/provider.md b/docs/auth/vmware-cloud/provider.md index 62a653baf0..8536eaea7e 100644 --- a/docs/auth/vmware-cloud/provider.md +++ b/docs/auth/vmware-cloud/provider.md @@ -154,6 +154,7 @@ auth: organizationId: ${ORG_ID} signIn: resolvers: + # typically you would pick one of these - resolver: emailMatchingUserEntityProfileEmail - resolver: emailLocalPartMatchingUserEntityName - resolver: vmwareCloudSignInResolvers