diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6a1b46fdd..48016f96c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added an optional `webUrl` field to the GitLab connection config, used to build links to repositories in the GitLab web UI when the API host differs from the browsable host. [#1457](https://github.com/sourcebot-dev/sourcebot/pull/1457)
+- [EE] Added Idira SSO support through OpenID Connect. [#1459](https://github.com/sourcebot-dev/sourcebot/pull/1459)
### Fixed
- Prevented focus rings in workspace connector dialogs from being clipped. [#1457](https://github.com/sourcebot-dev/sourcebot/pull/1457)
diff --git a/docs/docs/configuration/idp.mdx b/docs/docs/configuration/idp.mdx
index b5fffa1d7..da56c15d1 100644
--- a/docs/docs/configuration/idp.mdx
+++ b/docs/docs/configuration/idp.mdx
@@ -601,6 +601,57 @@ A JumpCloud connection can be used for [authentication](/docs/configuration/auth
+### Idira
+
+[Idira custom OpenID Connect application documentation](https://docs.cyberark.com/manage/latest/en/content/identity/applications/appscustom/openidaddconfigapp.htm)
+
+An Idira connection can be used for [authentication](/docs/configuration/auth). Sourcebot uses Idira's OpenID Connect support to authenticate users.
+
+
+
+
+ In the Idira Admin Portal, go to **Manage > Identities > Web apps**, add the custom **OpenID Connect** application, and configure its Trust settings.
+
+ When configuring the application:
+ - Add `/api/auth/callback/idira` to the **Authorized Redirect URIs** (ex. https://sourcebot.coolcorp.com/api/auth/callback/idira)
+ - Keep exact redirect URI matching enabled
+ - Grant the users, groups, or roles that should be able to sign in permission to run the application
+
+ From the application's Trust page, note the `CLIENT_ID` and `ISSUER`. Generate a client secret and store it securely. Idira displays the secret only until you confirm that you have saved it.
+
+
+ Provide the client id, secret, and issuer URL to Sourcebot using environment variables. These variables can be named whatever you like
+ (ex. `IDIRA_IDENTITY_PROVIDER_CLIENT_ID`, `IDIRA_IDENTITY_PROVIDER_CLIENT_SECRET`, and `IDIRA_IDENTITY_PROVIDER_ISSUER`).
+
+
+ Add the Idira provider to the `identityProviders` object in the [config file](/docs/configuration/config-file):
+
+ ```json wrap icon="code"
+ {
+ "$schema": "https://raw.githubusercontent.com/sourcebot-dev/sourcebot/main/schemas/v3/index.json",
+ "identityProviders": {
+ "idira": {
+ "provider": "idira",
+ "purpose": "sso",
+ "clientId": {
+ "env": "IDIRA_IDENTITY_PROVIDER_CLIENT_ID"
+ },
+ "clientSecret": {
+ "env": "IDIRA_IDENTITY_PROVIDER_CLIENT_SECRET"
+ },
+ "issuer": {
+ "env": "IDIRA_IDENTITY_PROVIDER_ISSUER"
+ }
+ }
+ }
+ }
+ ```
+
+ If you use a custom identity provider id instead of `idira`, use that id in the callback URL as described in [multiple identity providers](#configuring-multiple-providers-of-the-same-type).
+
+
+
+
### Google Cloud IAP
[Google Cloud IAP Documentation](https://cloud.google.com/iap/docs)
@@ -688,5 +739,3 @@ Each provider keeps the same fields documented above. The only differences are:
Each instance needs its own OAuth client (its own `clientId` and `clientSecret`) registered with the matching callback URL.
-
-
diff --git a/docs/snippets/schemas/v3/identityProvider.schema.mdx b/docs/snippets/schemas/v3/identityProvider.schema.mdx
index 8280622b2..0be1f8f6d 100644
--- a/docs/snippets/schemas/v3/identityProvider.schema.mdx
+++ b/docs/snippets/schemas/v3/identityProvider.schema.mdx
@@ -991,6 +991,119 @@
"issuer"
]
},
+ "IdiraIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
"BitbucketServerIdentityProviderConfig": {
"type": "object",
"additionalProperties": false,
@@ -2078,6 +2191,119 @@
"issuer"
]
},
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
{
"type": "object",
"additionalProperties": false,
diff --git a/docs/snippets/schemas/v3/index.schema.mdx b/docs/snippets/schemas/v3/index.schema.mdx
index 172d04988..a9603abdc 100644
--- a/docs/snippets/schemas/v3/index.schema.mdx
+++ b/docs/snippets/schemas/v3/index.schema.mdx
@@ -5962,6 +5962,119 @@
"issuer"
]
},
+ "IdiraIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
"BitbucketServerIdentityProviderConfig": {
"type": "object",
"additionalProperties": false,
@@ -7049,6 +7162,119 @@
"issuer"
]
},
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
{
"type": "object",
"additionalProperties": false,
@@ -8145,6 +8371,119 @@
"issuer"
]
},
+ "IdiraIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
"BitbucketServerIdentityProviderConfig": {
"type": "object",
"additionalProperties": false,
@@ -9232,6 +9571,119 @@
"issuer"
]
},
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
{
"type": "object",
"additionalProperties": false,
diff --git a/packages/schemas/src/v3/identityProvider.schema.ts b/packages/schemas/src/v3/identityProvider.schema.ts
index 1c17b57f9..a95db0c1a 100644
--- a/packages/schemas/src/v3/identityProvider.schema.ts
+++ b/packages/schemas/src/v3/identityProvider.schema.ts
@@ -990,6 +990,119 @@ const schema = {
"issuer"
]
},
+ "IdiraIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
"BitbucketServerIdentityProviderConfig": {
"type": "object",
"additionalProperties": false,
@@ -2077,6 +2190,119 @@ const schema = {
"issuer"
]
},
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
{
"type": "object",
"additionalProperties": false,
diff --git a/packages/schemas/src/v3/identityProvider.type.ts b/packages/schemas/src/v3/identityProvider.type.ts
index 980aaa7b8..936bdb72b 100644
--- a/packages/schemas/src/v3/identityProvider.type.ts
+++ b/packages/schemas/src/v3/identityProvider.type.ts
@@ -11,6 +11,7 @@ export type IdentityProviderConfig =
| AuthentikIdentityProviderConfig
| BitbucketCloudIdentityProviderConfig
| JumpCloudIdentityProviderConfig
+ | IdiraIdentityProviderConfig
| BitbucketServerIdentityProviderConfig;
export interface GitHubIdentityProviderConfig {
@@ -416,6 +417,53 @@ export interface JumpCloudIdentityProviderConfig {
googleCloudSecret: string;
};
}
+export interface IdiraIdentityProviderConfig {
+ provider: "idira";
+ /**
+ * Optional human-readable label shown on the login screen. Defaults to 'Idira'.
+ */
+ displayName?: string;
+ purpose: "sso";
+ clientId:
+ | {
+ /**
+ * The name of the environment variable that contains the token.
+ */
+ env: string;
+ }
+ | {
+ /**
+ * The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets
+ */
+ googleCloudSecret: string;
+ };
+ clientSecret:
+ | {
+ /**
+ * The name of the environment variable that contains the token.
+ */
+ env: string;
+ }
+ | {
+ /**
+ * The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets
+ */
+ googleCloudSecret: string;
+ };
+ issuer:
+ | {
+ /**
+ * The name of the environment variable that contains the token.
+ */
+ env: string;
+ }
+ | {
+ /**
+ * The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets
+ */
+ googleCloudSecret: string;
+ };
+}
export interface BitbucketServerIdentityProviderConfig {
provider: "bitbucket-server";
/**
diff --git a/packages/schemas/src/v3/index.schema.ts b/packages/schemas/src/v3/index.schema.ts
index 2112b3d5b..48e42f300 100644
--- a/packages/schemas/src/v3/index.schema.ts
+++ b/packages/schemas/src/v3/index.schema.ts
@@ -5961,6 +5961,119 @@ const schema = {
"issuer"
]
},
+ "IdiraIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
"BitbucketServerIdentityProviderConfig": {
"type": "object",
"additionalProperties": false,
@@ -7048,6 +7161,119 @@ const schema = {
"issuer"
]
},
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
{
"type": "object",
"additionalProperties": false,
@@ -8144,6 +8370,119 @@ const schema = {
"issuer"
]
},
+ "IdiraIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
"BitbucketServerIdentityProviderConfig": {
"type": "object",
"additionalProperties": false,
@@ -9231,6 +9570,119 @@ const schema = {
"issuer"
]
},
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "clientSecret": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ },
+ "issuer": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "env": {
+ "type": "string",
+ "description": "The name of the environment variable that contains the token."
+ }
+ },
+ "required": [
+ "env"
+ ],
+ "additionalProperties": false
+ },
+ {
+ "type": "object",
+ "properties": {
+ "googleCloudSecret": {
+ "type": "string",
+ "description": "The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets"
+ }
+ },
+ "required": [
+ "googleCloudSecret"
+ ],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": [
+ "provider",
+ "purpose",
+ "clientId",
+ "clientSecret",
+ "issuer"
+ ]
+ },
{
"type": "object",
"additionalProperties": false,
diff --git a/packages/schemas/src/v3/index.type.ts b/packages/schemas/src/v3/index.type.ts
index 088b6829f..df59a13f4 100644
--- a/packages/schemas/src/v3/index.type.ts
+++ b/packages/schemas/src/v3/index.type.ts
@@ -41,6 +41,7 @@ export type IdentityProviderConfig =
| AuthentikIdentityProviderConfig
| BitbucketCloudIdentityProviderConfig
| JumpCloudIdentityProviderConfig
+ | IdiraIdentityProviderConfig
| BitbucketServerIdentityProviderConfig;
export interface SourcebotConfig {
@@ -1756,6 +1757,53 @@ export interface JumpCloudIdentityProviderConfig {
googleCloudSecret: string;
};
}
+export interface IdiraIdentityProviderConfig {
+ provider: "idira";
+ /**
+ * Optional human-readable label shown on the login screen. Defaults to 'Idira'.
+ */
+ displayName?: string;
+ purpose: "sso";
+ clientId:
+ | {
+ /**
+ * The name of the environment variable that contains the token.
+ */
+ env: string;
+ }
+ | {
+ /**
+ * The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets
+ */
+ googleCloudSecret: string;
+ };
+ clientSecret:
+ | {
+ /**
+ * The name of the environment variable that contains the token.
+ */
+ env: string;
+ }
+ | {
+ /**
+ * The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets
+ */
+ googleCloudSecret: string;
+ };
+ issuer:
+ | {
+ /**
+ * The name of the environment variable that contains the token.
+ */
+ env: string;
+ }
+ | {
+ /**
+ * The resource name of a Google Cloud secret. Must be in the format `projects//secrets//versions/`. See https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets
+ */
+ googleCloudSecret: string;
+ };
+}
export interface BitbucketServerIdentityProviderConfig {
provider: "bitbucket-server";
/**
diff --git a/packages/web/public/idira.svg b/packages/web/public/idira.svg
new file mode 100644
index 000000000..fb92b20d0
--- /dev/null
+++ b/packages/web/public/idira.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/web/src/app/login/components/loginForm.tsx b/packages/web/src/app/login/components/loginForm.tsx
index 9f9fb9662..6274ab34e 100644
--- a/packages/web/src/app/login/components/loginForm.tsx
+++ b/packages/web/src/app/login/components/loginForm.tsx
@@ -60,6 +60,8 @@ export const LoginForm = ({ callbackUrl, error, context, isAnonymousAccessEnable
return "wa_login_with_microsoft_entra_id" as const;
case "jumpcloud":
return "wa_login_with_jumpcloud" as const;
+ case "idira":
+ return "wa_login_with_idira" as const;
default:
return "wa_login_with_github" as const; // fallback
}
diff --git a/packages/web/src/ee/features/sso/sso.ts b/packages/web/src/ee/features/sso/sso.ts
index ca5b6b686..84e06a68a 100644
--- a/packages/web/src/ee/features/sso/sso.ts
+++ b/packages/web/src/ee/features/sso/sso.ts
@@ -162,6 +162,26 @@ export const getEEIdentityProviders = async (): Promise => {
});
}
+ if (idpConfig.provider === "idira") {
+ const clientId = await getTokenFromConfig(idpConfig.clientId);
+ const clientSecret = await getTokenFromConfig(idpConfig.clientSecret);
+ const issuer = (await getTokenFromConfig(idpConfig.issuer)).replace(/\/+$/, '');
+ providers.push({
+ __provider: createIdiraProvider({
+ id,
+ clientId,
+ clientSecret,
+ issuer,
+ allowDangerousEmailAccountLinking: env.AUTH_EE_ALLOW_EMAIL_ACCOUNT_LINKING === 'true',
+ }),
+ id,
+ type: idpConfig.provider,
+ displayName: idpConfig.displayName,
+ purpose: idpConfig.purpose,
+ issuerUrl: issuer,
+ });
+ }
+
if (idpConfig.provider === "bitbucket-server") {
const clientId = await getTokenFromConfig(idpConfig.clientId);
const clientSecret = await getTokenFromConfig(idpConfig.clientSecret);
@@ -403,6 +423,36 @@ const createJumpCloudProvider = (id: string, clientId: string, clientSecret: str
} as Provider;
}
+type CreateIdiraProviderOptions = {
+ id: string;
+ clientId: string;
+ clientSecret: string;
+ issuer: string;
+ allowDangerousEmailAccountLinking: boolean;
+};
+
+const createIdiraProvider = ({
+ id,
+ clientId,
+ clientSecret,
+ issuer,
+ allowDangerousEmailAccountLinking,
+}: CreateIdiraProviderOptions): Provider => ({
+ id,
+ name: "Idira",
+ type: "oidc",
+ clientId,
+ clientSecret,
+ issuer,
+ checks: ["pkce", "state"],
+ authorization: {
+ params: {
+ scope: "openid profile email",
+ },
+ },
+ allowDangerousEmailAccountLinking,
+} as Provider);
+
const createGCPIAPProvider = (id: string, audience: string): Provider => {
return Credentials({
id,
diff --git a/packages/web/src/lib/posthogEvents.ts b/packages/web/src/lib/posthogEvents.ts
index 15353cbd5..152a293e4 100644
--- a/packages/web/src/lib/posthogEvents.ts
+++ b/packages/web/src/lib/posthogEvents.ts
@@ -143,6 +143,7 @@ export type PosthogEventMap = {
wa_login_with_keycloak: {},
wa_login_with_microsoft_entra_id: {},
wa_login_with_jumpcloud: {},
+ wa_login_with_idira: {},
wa_login_with_magic_link: {},
wa_login_with_credentials: {},
//////////////////////////////////////////////////////////////////
diff --git a/packages/web/src/lib/utils.ts b/packages/web/src/lib/utils.ts
index bc7720416..b49050f2a 100644
--- a/packages/web/src/lib/utils.ts
+++ b/packages/web/src/lib/utils.ts
@@ -13,6 +13,7 @@ import keycloakLogo from "@/public/keycloak.svg";
import microsoftLogo from "@/public/microsoft_entra.svg";
import authentikLogo from "@/public/authentik.svg";
import jumpcloudLogo from "@/public/jumpcloud.svg";
+import idiraLogo from "@/public/idira.svg";
import { ServiceError } from "./serviceError";
import { ConnectionType } from "@sourcebot/db";
import { CodeHostType } from "@sourcebot/db";
@@ -155,6 +156,15 @@ export const getAuthProviderInfo = (providerType: string): AuthProviderInfo => {
src: jumpcloudLogo,
},
};
+ case "idira":
+ return {
+ id: "idira",
+ name: "Idira",
+ displayName: "Idira",
+ icon: {
+ src: idiraLogo,
+ },
+ };
case "credentials":
return {
id: "credentials",
@@ -654,4 +664,4 @@ export const fetchWithRetry = async (
}
// Unreachable, but TypeScript needs it
throw new Error('fetchWithRetry: exhausted retries');
-}
\ No newline at end of file
+}
diff --git a/schemas/v3/identityProvider.json b/schemas/v3/identityProvider.json
index fcc98d081..264fd8f7d 100644
--- a/schemas/v3/identityProvider.json
+++ b/schemas/v3/identityProvider.json
@@ -278,6 +278,32 @@
},
"required": ["provider", "purpose", "clientId", "clientSecret", "issuer"]
},
+ "IdiraIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "idira"
+ },
+ "displayName": {
+ "type": "string",
+ "description": "Optional human-readable label shown on the login screen. Defaults to 'Idira'."
+ },
+ "purpose": {
+ "const": "sso"
+ },
+ "clientId": {
+ "$ref": "./shared.json#/definitions/Token"
+ },
+ "clientSecret": {
+ "$ref": "./shared.json#/definitions/Token"
+ },
+ "issuer": {
+ "$ref": "./shared.json#/definitions/Token"
+ }
+ },
+ "required": ["provider", "purpose", "clientId", "clientSecret", "issuer"]
+ },
"BitbucketServerIdentityProviderConfig": {
"type": "object",
"additionalProperties": false,
@@ -343,6 +369,9 @@
{
"$ref": "#/definitions/JumpCloudIdentityProviderConfig"
},
+ {
+ "$ref": "#/definitions/IdiraIdentityProviderConfig"
+ },
{
"$ref": "#/definitions/BitbucketServerIdentityProviderConfig"
}