diff --git a/backend/src/ee/routes/v1/saml-router.ts b/backend/src/ee/routes/v1/saml-router.ts index 00dd09c33..6ed079a61 100644 --- a/backend/src/ee/routes/v1/saml-router.ts +++ b/backend/src/ee/routes/v1/saml-router.ts @@ -27,6 +27,7 @@ type TSAMLConfig = { cert: string; audience: string; wantAuthnResponseSigned?: boolean; + wantAssertionsSigned?: boolean; disableRequestedAuthnContext?: boolean; }; @@ -82,6 +83,10 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => { samlConfig.audience = `spn:${ssoConfig.issuer}`; } } + if (ssoConfig.authProvider === SamlProviders.GOOGLE_SAML) { + samlConfig.wantAssertionsSigned = false; + } + (req as unknown as FastifyRequest).ssoConfig = ssoConfig; done(null, samlConfig); } catch (error) { diff --git a/backend/src/ee/services/saml-config/saml-config-types.ts b/backend/src/ee/services/saml-config/saml-config-types.ts index a2c2c63c0..9d13cb342 100644 --- a/backend/src/ee/services/saml-config/saml-config-types.ts +++ b/backend/src/ee/services/saml-config/saml-config-types.ts @@ -4,7 +4,8 @@ import { ActorType } from "@app/services/auth/auth-type"; export enum SamlProviders { OKTA_SAML = "okta-saml", AZURE_SAML = "azure-saml", - JUMPCLOUD_SAML = "jumpcloud-saml" + JUMPCLOUD_SAML = "jumpcloud-saml", + GOOGLE_SAML = "google-saml" } export type TCreateSamlCfgDTO = { diff --git a/docs/documentation/platform/sso/google-saml.mdx b/docs/documentation/platform/sso/google-saml.mdx new file mode 100644 index 000000000..743c4e3ff --- /dev/null +++ b/docs/documentation/platform/sso/google-saml.mdx @@ -0,0 +1,95 @@ +--- +title: "Google SAML" +description: "Configure Google SAML for Infisical SSO" +--- + + + Google SAML SSO feature is a paid feature. + + If you're using Infisical Cloud, then it is available under the **Pro Tier**. If you're self-hosting Infisical, + then you should contact team@infisical.com to purchase an enterprise license to use it. + + + + + In Infisical, head to your Organization Settings > Authentication > SAML SSO Configuration and select **Set up SAML SSO**. + + Next, note the **ACS URL** and **SP Entity ID** to use when configuring the Google SAML application. + + ![Google SAML initial configuration](../../../images/sso/google-saml/init-config.png) + + + 2.1. In your [Google Admin console](https://support.google.com/a/answer/182076), head to Menu > Apps > Web and mobile apps and + create a **custom SAML app**. + + ![Google SAML app creation](../../../images/sso/google-saml/create-custom-saml-app.png) + + 2.2. In the **App details** tab, give the application a unique name like Infisical. + + ![Google SAML app naming](../../../images/sso/google-saml/name-custom-saml-app.png) + + 2.3. In the **Google Identity Provider details** tab, copy the **SSO URL**, **Entity ID** and **Certificate**. + + ![Google SAML custom app details](../../../images/sso/google-saml/custom-saml-app-config.png) + + 2.4. Back in Infisical, set **SSO URL**, **IdP Entity ID**, and **Certificate** to the corresponding items from step 2.3. + + ![Google SAML Infisical config](../../../images/sso/google-saml/infisical-config.png) + + 2.5. Back in the Google Admin console, in the **Service provider details** tab, set the **ACS URL** and **Entity ID** to the corresponding items from step 1. + + Also, check the **Signed response** checkbox. + + ![Google SAML app config 2](../../../images/sso/google-saml/custom-saml-app-config-2.png) + + 2.6. In the **Attribute mapping** tab, configure the following map: + + - **First name** -> **firstName** + - **Last name** -> **lastName** + - **Primary email** -> **email** + + ![Google SAML attribute mapping](../../../images/sso/google-saml/attribute-mapping.png) + + Click **Finish**. + + + Back in your [Google Admin console](https://support.google.com/a/answer/182076), head to Menu > Apps > Web and mobile apps > your SAML app + and press on **User access**. + + ![Google SAML user access](../../../images/sso/google-saml/user-access.png) + + To assign everyone in your organization to the application, click **On for everyone** or **Off for everyone** and then click **Save**. + + You can also assign an organizational unit or set of users to an application; you can learn more about that [here](https://support.google.com/a/answer/6087519?hl=en#add_custom_saml&turn_on&verify_sso&&zippy=%2Cstep-add-the-custom-saml-app%2Cstep-turn-on-your-saml-app%2Cstep-verify-that-sso-is-working-with-your-custom-app). + + ![Google SAML user access assignment](../../../images/sso/google-saml/user-access-assign.png) + + + Enabling SAML SSO allows members in your organization to log into Infisical via Google Workspace. + + ![Google SAML enable](../../../images/sso/google-saml/enable-saml.png) + + + Enforcing SAML SSO ensures that members in your organization can only access Infisical + by logging into the organization via Google. + + To enforce SAML SSO, you're required to test out the SAML connection by successfully authenticating at least one Google user with Infisical; + Once you've completed this requirement, you can toggle the **Enforce SAML SSO** button to enforce SAML SSO. + + + We recommend ensuring that your account is provisioned the application in Google + prior to enforcing SAML SSO to prevent any unintended issues. + + + + + + If you're configuring SAML SSO on a self-hosted instance of Infisical, make sure to + set the `AUTH_SECRET` and `SITE_URL` environment variable for it to work: + + - `AUTH_SECRET`: A secret key used for signing and verifying JWT. This can be a random 32-byte base64 string generated with `openssl rand -base64 32`. + - `SITE_URL`: The URL of your self-hosted instance of Infisical - should be an absolute URL including the protocol (e.g. https://app.infisical.com) + + +References: +- Google's guide to [set up your own custom SAML app](https://support.google.com/a/answer/6087519?hl=en#add_custom_saml&turn_on&verify_sso&&zippy=%2Cstep-add-the-custom-saml-app%2Cstep-turn-on-your-saml-app%2Cstep-verify-that-sso-is-working-with-your-custom-app). \ No newline at end of file diff --git a/docs/documentation/platform/sso/overview.mdx b/docs/documentation/platform/sso/overview.mdx index cd2f8ff31..e1fd25957 100644 --- a/docs/documentation/platform/sso/overview.mdx +++ b/docs/documentation/platform/sso/overview.mdx @@ -22,3 +22,4 @@ your IdP cannot and will not have access to the decryption key needed to decrypt - [Okta SAML](/documentation/platform/sso/okta) - [Azure SAML](/documentation/platform/sso/azure) - [JumpCloud SAML](/documentation/platform/sso/jumpcloud) +- [Google SAML](/documentation/platform/sso/google-saml) diff --git a/docs/images/sso/google-saml/attribute-mapping.png b/docs/images/sso/google-saml/attribute-mapping.png new file mode 100644 index 000000000..b5702cd2b Binary files /dev/null and b/docs/images/sso/google-saml/attribute-mapping.png differ diff --git a/docs/images/sso/google-saml/create-custom-saml-app.png b/docs/images/sso/google-saml/create-custom-saml-app.png new file mode 100644 index 000000000..6139932f1 Binary files /dev/null and b/docs/images/sso/google-saml/create-custom-saml-app.png differ diff --git a/docs/images/sso/google-saml/custom-saml-app-config-2.png b/docs/images/sso/google-saml/custom-saml-app-config-2.png new file mode 100644 index 000000000..9839dd0c4 Binary files /dev/null and b/docs/images/sso/google-saml/custom-saml-app-config-2.png differ diff --git a/docs/images/sso/google-saml/custom-saml-app-config.png b/docs/images/sso/google-saml/custom-saml-app-config.png new file mode 100644 index 000000000..8f4ad5928 Binary files /dev/null and b/docs/images/sso/google-saml/custom-saml-app-config.png differ diff --git a/docs/images/sso/google-saml/enable-saml.png b/docs/images/sso/google-saml/enable-saml.png new file mode 100644 index 000000000..7a90eed55 Binary files /dev/null and b/docs/images/sso/google-saml/enable-saml.png differ diff --git a/docs/images/sso/google-saml/infisical-config.png b/docs/images/sso/google-saml/infisical-config.png new file mode 100644 index 000000000..250b4ed37 Binary files /dev/null and b/docs/images/sso/google-saml/infisical-config.png differ diff --git a/docs/images/sso/google-saml/init-config.png b/docs/images/sso/google-saml/init-config.png new file mode 100644 index 000000000..c4b967e54 Binary files /dev/null and b/docs/images/sso/google-saml/init-config.png differ diff --git a/docs/images/sso/google-saml/name-custom-saml-app.png b/docs/images/sso/google-saml/name-custom-saml-app.png new file mode 100644 index 000000000..580896d05 Binary files /dev/null and b/docs/images/sso/google-saml/name-custom-saml-app.png differ diff --git a/docs/images/sso/google-saml/user-access-assign.png b/docs/images/sso/google-saml/user-access-assign.png new file mode 100644 index 000000000..afa115c65 Binary files /dev/null and b/docs/images/sso/google-saml/user-access-assign.png differ diff --git a/docs/images/sso/google-saml/user-access.png b/docs/images/sso/google-saml/user-access.png new file mode 100644 index 000000000..bd69c2277 Binary files /dev/null and b/docs/images/sso/google-saml/user-access.png differ diff --git a/docs/mint.json b/docs/mint.json index 852b93853..8f1835d5f 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -146,7 +146,8 @@ "documentation/platform/sso/gitlab", "documentation/platform/sso/okta", "documentation/platform/sso/azure", - "documentation/platform/sso/jumpcloud" + "documentation/platform/sso/jumpcloud", + "documentation/platform/sso/google-saml" ] }, { diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/OrgSSOSection.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/OrgSSOSection.tsx index 23900708d..51f887abb 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/OrgSSOSection.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/OrgSSOSection.tsx @@ -19,7 +19,8 @@ import { SSOModal } from "./SSOModal"; const ssoAuthProviderMap: { [key: string]: string } = { "okta-saml": "Okta SAML", "azure-saml": "Azure SAML", - "jumpcloud-saml": "JumpCloud SAML" + "jumpcloud-saml": "JumpCloud SAML", + "google-saml": "Google SAML" }; export const OrgSSOSection = (): JSX.Element => { diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/SSOModal.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/SSOModal.tsx index 0716a5cda..11e7e51ee 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/SSOModal.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgAuthTab/SSOModal.tsx @@ -21,13 +21,15 @@ import { UsePopUpState } from "@app/hooks/usePopUp"; enum AuthProvider { OKTA_SAML = "okta-saml", AZURE_SAML = "azure-saml", - JUMPCLOUD_SAML = "jumpcloud-saml" + JUMPCLOUD_SAML = "jumpcloud-saml", + GOOGLE_SAML = "google-saml" } const ssoAuthProviders = [ { label: "Okta SAML", value: AuthProvider.OKTA_SAML }, { label: "Azure SAML", value: AuthProvider.AZURE_SAML }, - { label: "JumpCloud SAML", value: AuthProvider.JUMPCLOUD_SAML } + { label: "JumpCloud SAML", value: AuthProvider.JUMPCLOUD_SAML }, + { label: "Google SAML", value: AuthProvider.GOOGLE_SAML } ]; const schema = yup @@ -140,7 +142,15 @@ export const SSOModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props) issuer: "IdP Entity ID", issuerPlaceholder: "xxx" }; - + case AuthProvider.GOOGLE_SAML: + return { + acsUrl: "ACS URL", + entityId: "SP Entity ID", + entryPoint: "SSO URL", + entryPointPlaceholder: "https://accounts.google.com/o/saml2/idp?idpid=xxx", + issuer: "IdP Entity ID", + issuerPlaceholder: "https://accounts.google.com/o/saml2/idp?idpid=xxx" + }; default: return { acsUrl: "ACS URL",