diff --git a/backend/infrahub/config.py b/backend/infrahub/config.py
index 5a714c8bc6..74f9cb90dc 100644
--- a/backend/infrahub/config.py
+++ b/backend/infrahub/config.py
@@ -451,6 +451,14 @@ class SecurityOIDCProvider2(SecurityOIDCSettings):
model_config = SettingsConfigDict(env_prefix="INFRAHUB_OIDC_PROVIDER2_")
+class SecurityOIDCProviderSettings(BaseModel):
+ """This class is meant to facilitate configuration of OIDC providers when loading configuration from a infrahub.toml file."""
+
+ google: Optional[SecurityOIDCGoogle] = Field(default=None)
+ provider1: Optional[SecurityOIDCProvider1] = Field(default=None)
+ provider2: Optional[SecurityOIDCProvider2] = Field(default=None)
+
+
class SecurityOAuth2BaseSettings(BaseSettings):
"""Baseclass for typing"""
@@ -490,6 +498,14 @@ class SecurityOAuth2Google(SecurityOAuth2Settings):
display_label: str = Field(default="Google")
+class SecurityOAuth2ProviderSettings(BaseModel):
+ """This class is meant to facilitate configuration of OAuth2 providers when loading configuration from a infrahub.toml file."""
+
+ google: Optional[SecurityOAuth2Google] = Field(default=None)
+ provider1: Optional[SecurityOAuth2Provider1] = Field(default=None)
+ provider2: Optional[SecurityOAuth2Provider2] = Field(default=None)
+
+
class MiscellaneousSettings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="INFRAHUB_MISC_")
print_query_details: bool = False
@@ -535,7 +551,9 @@ class SecuritySettings(BaseSettings):
default_factory=generate_uuid, description="The secret key used to validate authentication tokens"
)
oauth2_providers: list[Oauth2Provider] = Field(default_factory=list, description="The selected OAuth2 providers")
+ oauth2_provider_settings: SecurityOAuth2ProviderSettings = Field(default_factory=SecurityOAuth2ProviderSettings)
oidc_providers: list[OIDCProvider] = Field(default_factory=list, description="The selected OIDC providers")
+ oidc_provider_settings: SecurityOIDCProviderSettings = Field(default_factory=SecurityOIDCProviderSettings)
_oauth2_settings: dict[str, SecurityOAuth2Settings] = PrivateAttr(default_factory=dict)
_oidc_settings: dict[str, SecurityOIDCSettings] = PrivateAttr(default_factory=dict)
@@ -547,9 +565,21 @@ def check_oauth2_provider_settings(self) -> Self:
Oauth2Provider.GOOGLE: SecurityOAuth2Google,
}
for oauth2_provider in self.oauth2_providers:
- provider = mapped_providers[oauth2_provider]()
- if isinstance(provider, SecurityOAuth2Settings):
- self._oauth2_settings[oauth2_provider.value] = provider
+ match oauth2_provider:
+ case Oauth2Provider.GOOGLE:
+ if self.oauth2_provider_settings.google:
+ self._oauth2_settings[oauth2_provider.value] = self.oauth2_provider_settings.google
+ case Oauth2Provider.PROVIDER1:
+ if self.oauth2_provider_settings.provider1:
+ self._oauth2_settings[oauth2_provider.value] = self.oauth2_provider_settings.provider1
+ case Oauth2Provider.PROVIDER2:
+ if self.oauth2_provider_settings.provider2:
+ self._oauth2_settings[oauth2_provider.value] = self.oauth2_provider_settings.provider2
+
+ if oauth2_provider.value not in self._oauth2_settings:
+ provider = mapped_providers[oauth2_provider]()
+ if isinstance(provider, SecurityOAuth2Settings):
+ self._oauth2_settings[oauth2_provider.value] = provider
return self
@@ -561,9 +591,21 @@ def check_oidc_provider_settings(self) -> Self:
OIDCProvider.PROVIDER2: SecurityOIDCProvider2,
}
for oidc_provider in self.oidc_providers:
- provider = mapped_providers[oidc_provider]()
- if isinstance(provider, SecurityOIDCSettings):
- self._oidc_settings[oidc_provider.value] = provider
+ match oidc_provider:
+ case OIDCProvider.GOOGLE:
+ if self.oidc_provider_settings.google:
+ self._oidc_settings[oidc_provider.value] = self.oidc_provider_settings.google
+ case OIDCProvider.PROVIDER1:
+ if self.oidc_provider_settings.provider1:
+ self._oidc_settings[oidc_provider.value] = self.oidc_provider_settings.provider1
+ case OIDCProvider.PROVIDER2:
+ if self.oidc_provider_settings.provider2:
+ self._oidc_settings[oidc_provider.value] = self.oidc_provider_settings.provider2
+
+ if oidc_provider.value not in self._oidc_settings:
+ provider = mapped_providers[oidc_provider]()
+ if isinstance(provider, SecurityOIDCSettings):
+ self._oidc_settings[oidc_provider.value] = provider
return self
diff --git a/docs/docs/guides/sso.mdx b/docs/docs/guides/sso.mdx
index 6ac4c558ad..d7c50cf45f 100644
--- a/docs/docs/guides/sso.mdx
+++ b/docs/docs/guides/sso.mdx
@@ -1,6 +1,9 @@
---
title: Configuring Single sign-on
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
# Configuring Single sign-on
In Infrahub you can configure SSO using either Open ID Connect (OIDC) or can use OAuth2.
@@ -40,15 +43,36 @@ Aside from the display label and icon all the other entries will be provided by
An example of what the configuration could look like:
-```bash
-export INFRAHUB_OAUTH2_PROVIDER1_CLIENT_ID=infrahub-sso
-export INFRAHUB_OAUTH2_PROVIDER1_CLIENT_SECRET=edPf4IaquQaqns7t3s95mLhKKYdwL1up
-export INFRAHUB_OAUTH2_PROVIDER1_AUTHORIZATION_URL=http://localhost:8180/realms/infrahub/protocol/openid-connect/auth
-export INFRAHUB_OAUTH2_PROVIDER1_TOKEN_URL=http://localhost:8180/realms/infrahub/protocol/openid-connect/token
-export INFRAHUB_OAUTH2_PROVIDER1_USERINFO_URL=http://localhost:8180/realms/infrahub/protocol/openid-connect/userinfo
-export INFRAHUB_OAUTH2_PROVIDER1_DISPLAY_LABEL="Internal Server (Keycloak)"
-export INFRAHUB_OAUTH2_PROVIDER1_ICON="mdi:security-lock-outline"
-```
+
+
+
+ ```bash
+ export INFRAHUB_OAUTH2_PROVIDER1_CLIENT_ID=infrahub-sso
+ export INFRAHUB_OAUTH2_PROVIDER1_CLIENT_SECRET=edPf4IaquQaqns7t3s95mLhKKYdwL1up
+ export INFRAHUB_OAUTH2_PROVIDER1_AUTHORIZATION_URL=http://localhost:8180/realms/infrahub/protocol/openid-connect/auth
+ export INFRAHUB_OAUTH2_PROVIDER1_TOKEN_URL=http://localhost:8180/realms/infrahub/protocol/openid-connect/token
+ export INFRAHUB_OAUTH2_PROVIDER1_USERINFO_URL=http://localhost:8180/realms/infrahub/protocol/openid-connect/userinfo
+ export INFRAHUB_OAUTH2_PROVIDER1_DISPLAY_LABEL="Internal Server (Keycloak)"
+ export INFRAHUB_OAUTH2_PROVIDER1_ICON="mdi:security-lock-outline"
+ ```
+
+
+
+
+ ```toml
+ [security.oauth2_provider_settings.provider1]
+ client_id = "infrahub-sso"
+ client_secret = "edPf4IaquQaqns7t3s95mLhKKYdwL1up"
+ authorization_url = "http://localhost:8180/realms/infrahub/protocol/openid-connect/auth"
+ token_url = "http://localhost:8180/realms/infrahub/protocol/openid-connect/token"
+ userinfo_url = "http://localhost:8180/realms/infrahub/protocol/openid-connect/userinfo"
+ scopes = ["openid", "profile", "email"]
+ display_label = "Internal Server (Keycloak)"
+ icon = "mdi:security-lock-outline"
+ ```
+
+
+
This could be the configuration of a Keycloak provider, please refer to the documentation of your intended provider for guides on how to create a client and access the required information.
@@ -56,15 +80,43 @@ This could be the configuration of a Keycloak provider, please refer to the docu
In order to activate the above provider we need to add it to the list of active OAuth2 providers.
-```bash
-export INFRAHUB_SECURITY_OAUTH2_PROVIDERS='["provider1"]'
-```
+
+
+
+ ```bash
+ export INFRAHUB_SECURITY_OAUTH2_PROVIDERS='["provider1"]'
+ ```
+
+
+
+
+ ```toml
+ [security]
+ oauth2_providers = ["provider1"]
+ ```
+
+
+
Alternatively if you are setting up multiple providers each with their different settings:
-```bash
-export INFRAHUB_SECURITY_OAUTH2_PROVIDERS='["provider1","provider2"]'
-```
+
+
+
+ ```bash
+ export INFRAHUB_SECURITY_OAUTH2_PROVIDERS='["provider1","provider2"]'
+ ```
+
+
+
+
+ ```toml
+ [security]
+ oauth2_providers = ["provider1", "provider2"]
+ ```
+
+
+
## Setting up OIDC in Infrahub
@@ -89,13 +141,31 @@ Aside from the display label and icon all the other entries will be provided by
An example of what the configuration could look like:
-```bash
-export INFRAHUB_OIDC_PROVIDER1_CLIENT_ID=infrahub-sso
-export INFRAHUB_OIDC_PROVIDER1_CLIENT_SECRET=edPf4IaquQaqns7t3s95mLhKKYdwL1up
-export INFRAHUB_OIDC_PROVIDER1_DISCOVERY_URL=http://localhost:8180/realms/infrahub/.well-known/openid-configuration
-export INFRAHUB_OIDC_PROVIDER1_DISPLAY_LABEL="Internal Server (Keycloak)"
-export INFRAHUB_OIDC_PROVIDER1_ICON="mdi:security-lock-outline"
-```
+
+
+
+ ```bash
+ export INFRAHUB_OIDC_PROVIDER1_CLIENT_ID=infrahub-sso
+ export INFRAHUB_OIDC_PROVIDER1_CLIENT_SECRET=edPf4IaquQaqns7t3s95mLhKKYdwL1up
+ export INFRAHUB_OIDC_PROVIDER1_DISCOVERY_URL=http://localhost:8180/realms/infrahub/.well-known/openid-configuration
+ export INFRAHUB_OIDC_PROVIDER1_DISPLAY_LABEL="Internal Server (Keycloak)"
+ export INFRAHUB_OIDC_PROVIDER1_ICON="mdi:security-lock-outline"
+ ```
+
+
+
+
+ ```toml
+ [security.oidc_provider_settings.provider1]
+ client_id = "infrahub-sso"
+ client_secret = "edPf4IaquQaqns7t3s95mLhKKYdwL1up"
+ discovery_url = "http://localhost:8180/realms/infrahub/.well-known/openid-configuration"
+ display_label = "Internal Server (Keycloak)"
+ icon = "mdi:security-lock-outline"
+ ```
+
+
+
This could be the configuration of a Keycloak provider, please refer to the documentation of your intended provider for guides on how to create a client and access the required information.
@@ -103,15 +173,43 @@ This could be the configuration of a Keycloak provider, please refer to the docu
In order to activate the above provider we need to add it to the list of active OIDC providers.
-```bash
-export INFRAHUB_SECURITY_OIDC_PROVIDERS='["provider1"]'
-```
+
+
+
+ ```bash
+ export INFRAHUB_SECURITY_OIDC_PROVIDERS='["provider1"]'
+ ```
+
+
+
+
+ ```toml
+ [security]
+ oidc_providers = ["provider1"]
+ ```
+
+
+
Alternatively if you are setting up multiple providers each with their different settings:
-```bash
-export INFRAHUB_SECURITY_OIDC_PROVIDERS='["provider1","provider2"]'
-```
+
+
+
+ ```bash
+ export INFRAHUB_SECURITY_OIDC_PROVIDERS='["provider1","provider2"]'
+ ```
+
+
+
+
+ ```toml
+ [security]
+ oidc_providers = ["provider1", "provider2"]
+ ```
+
+
+
## Configuring the redirect URI in the identity provider