diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd71cf1e7..39e1ac87b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for streaming code search results. [#623](https://github.com/sourcebot-dev/sourcebot/pull/623)
- Added buttons to toggle case sensitivity and regex patterns. [#623](https://github.com/sourcebot-dev/sourcebot/pull/623)
- Added counts to members, requets, and invites tabs in the members settings. [#621](https://github.com/sourcebot-dev/sourcebot/pull/621)
+- [Sourcebot EE] Add support for Authentik as a identity provider. [#627](https://github.com/sourcebot-dev/sourcebot/pull/627)
### Changed
- Changed the default search behaviour to match patterns as substrings and **not** regular expressions. Regular expressions can be used by toggling the regex button in search bar. [#623](https://github.com/sourcebot-dev/sourcebot/pull/623)
diff --git a/docs/docs/configuration/idp.mdx b/docs/docs/configuration/idp.mdx
index 21ae756d4..6d2475b59 100644
--- a/docs/docs/configuration/idp.mdx
+++ b/docs/docs/configuration/idp.mdx
@@ -366,3 +366,53 @@ A Microsoft Entra ID connection can be used for [authentication](/docs/configura
+### Authentik
+
+[Auth.js Authentik Provider Docs](https://authjs.dev/getting-started/providers/authentik)
+
+An Authentik connection can be used for [authentication](/docs/configuration/auth).
+
+
+
+
+ To begin, you must create a OAuth2/OpenID Connect application in Authentik. For more information, see the [Authentik documentation](https://docs.goauthentik.io/add-secure-apps/applications/manage_apps/#create-an-application-and-provider-pair).
+
+ When configuring your application:
+ - Set the provider type to "OAuth2/OpenID Connect"
+ - Set the client type to "Confidential"
+ - Add `/api/auth/callback/authentik` to the redirect URIs (ex. https://sourcebot.coolcorp.com/api/auth/callback/authentik)
+
+ After creating the application, open the application details to obtain the client id, client secret, and issuer URL (typically in the format `https:///application/o//`).
+
+
+ The client id, secret, and issuer URL are provided to Sourcebot via environment variables. These can be named whatever you like
+ (ex. `AUTHENTIK_IDENTITY_PROVIDER_CLIENT_ID`, `AUTHENTIK_IDENTITY_PROVIDER_CLIENT_SECRET`, and `AUTHENTIK_IDENTITY_PROVIDER_ISSUER`)
+
+
+ Create a `identityProvider` object in the [config file](/docs/configuration/config-file) with the following fields:
+
+ ```json wrap icon="code"
+ {
+ "$schema": "https://raw.githubusercontent.com/sourcebot-dev/sourcebot/main/schemas/v3/index.json",
+ "identityProviders": [
+ {
+ "provider": "authentik",
+ "purpose": "sso",
+ "clientId": {
+ "env": "AUTHENTIK_IDENTITY_PROVIDER_CLIENT_ID"
+ },
+ "clientSecret": {
+ "env": "AUTHENTIK_IDENTITY_PROVIDER_CLIENT_SECRET"
+ },
+ "issuer": {
+ "env": "AUTHENTIK_IDENTITY_PROVIDER_ISSUER"
+ }
+ }
+ ]
+ }
+ ```
+
+
+
+
+
diff --git a/docs/snippets/schemas/v3/identityProvider.schema.mdx b/docs/snippets/schemas/v3/identityProvider.schema.mdx
index 30c172bed..da75427dd 100644
--- a/docs/snippets/schemas/v3/identityProvider.schema.mdx
+++ b/docs/snippets/schemas/v3/identityProvider.schema.mdx
@@ -647,6 +647,115 @@
"purpose",
"audience"
]
+ },
+ "AuthentikIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
},
"oneOf": [
@@ -1293,6 +1402,115 @@
"purpose",
"audience"
]
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
]
}
diff --git a/docs/snippets/schemas/v3/index.schema.mdx b/docs/snippets/schemas/v3/index.schema.mdx
index 413e51bd6..f3da7ed42 100644
--- a/docs/snippets/schemas/v3/index.schema.mdx
+++ b/docs/snippets/schemas/v3/index.schema.mdx
@@ -5163,6 +5163,115 @@
"purpose",
"audience"
]
+ },
+ "AuthentikIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
},
"oneOf": [
@@ -5809,6 +5918,115 @@
"purpose",
"audience"
]
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
]
}
diff --git a/packages/schemas/src/v3/identityProvider.schema.ts b/packages/schemas/src/v3/identityProvider.schema.ts
index 708c3b4cd..f3ff42580 100644
--- a/packages/schemas/src/v3/identityProvider.schema.ts
+++ b/packages/schemas/src/v3/identityProvider.schema.ts
@@ -646,6 +646,115 @@ const schema = {
"purpose",
"audience"
]
+ },
+ "AuthentikIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
},
"oneOf": [
@@ -1292,6 +1401,115 @@ const schema = {
"purpose",
"audience"
]
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
]
} as const;
diff --git a/packages/schemas/src/v3/identityProvider.type.ts b/packages/schemas/src/v3/identityProvider.type.ts
index 31d7a9a8c..12cdb0ba8 100644
--- a/packages/schemas/src/v3/identityProvider.type.ts
+++ b/packages/schemas/src/v3/identityProvider.type.ts
@@ -7,7 +7,8 @@ export type IdentityProviderConfig =
| OktaIdentityProviderConfig
| KeycloakIdentityProviderConfig
| MicrosoftEntraIDIdentityProviderConfig
- | GCPIAPIdentityProviderConfig;
+ | GCPIAPIdentityProviderConfig
+ | AuthentikIdentityProviderConfig;
export interface GitHubIdentityProviderConfig {
provider: "github";
@@ -255,3 +256,46 @@ export interface GCPIAPIdentityProviderConfig {
googleCloudSecret: string;
};
}
+export interface AuthentikIdentityProviderConfig {
+ provider: "authentik";
+ 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;
+ };
+}
diff --git a/packages/schemas/src/v3/index.schema.ts b/packages/schemas/src/v3/index.schema.ts
index c7bf374d4..f5676ac3f 100644
--- a/packages/schemas/src/v3/index.schema.ts
+++ b/packages/schemas/src/v3/index.schema.ts
@@ -5162,6 +5162,115 @@ const schema = {
"purpose",
"audience"
]
+ },
+ "AuthentikIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
},
"oneOf": [
@@ -5808,6 +5917,115 @@ const schema = {
"purpose",
"audience"
]
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"
+ ]
}
]
}
diff --git a/packages/schemas/src/v3/index.type.ts b/packages/schemas/src/v3/index.type.ts
index 669a9511b..f0e487c4d 100644
--- a/packages/schemas/src/v3/index.type.ts
+++ b/packages/schemas/src/v3/index.type.ts
@@ -33,7 +33,8 @@ export type IdentityProviderConfig =
| OktaIdentityProviderConfig
| KeycloakIdentityProviderConfig
| MicrosoftEntraIDIdentityProviderConfig
- | GCPIAPIdentityProviderConfig;
+ | GCPIAPIdentityProviderConfig
+ | AuthentikIdentityProviderConfig;
export interface SourcebotConfig {
$schema?: string;
@@ -1401,3 +1402,46 @@ export interface GCPIAPIdentityProviderConfig {
googleCloudSecret: string;
};
}
+export interface AuthentikIdentityProviderConfig {
+ provider: "authentik";
+ 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;
+ };
+}
diff --git a/packages/web/public/authentik.svg b/packages/web/public/authentik.svg
new file mode 100644
index 000000000..9933084de
--- /dev/null
+++ b/packages/web/public/authentik.svg
@@ -0,0 +1 @@
+
diff --git a/packages/web/src/ee/features/sso/sso.ts b/packages/web/src/ee/features/sso/sso.ts
index a0fe415c9..c43b32621 100644
--- a/packages/web/src/ee/features/sso/sso.ts
+++ b/packages/web/src/ee/features/sso/sso.ts
@@ -1,11 +1,12 @@
import type { IdentityProvider } from "@/auth";
import { onCreateUser } from "@/lib/authUtils";
import { prisma } from "@/prisma";
-import { GCPIAPIdentityProviderConfig, GitHubIdentityProviderConfig, GitLabIdentityProviderConfig, GoogleIdentityProviderConfig, KeycloakIdentityProviderConfig, MicrosoftEntraIDIdentityProviderConfig, OktaIdentityProviderConfig } from "@sourcebot/schemas/v3/index.type";
+import { AuthentikIdentityProviderConfig, GCPIAPIdentityProviderConfig, GitHubIdentityProviderConfig, GitLabIdentityProviderConfig, GoogleIdentityProviderConfig, KeycloakIdentityProviderConfig, MicrosoftEntraIDIdentityProviderConfig, OktaIdentityProviderConfig } from "@sourcebot/schemas/v3/index.type";
import { createLogger, env, getTokenFromConfig, hasEntitlement, loadConfig } from "@sourcebot/shared";
import { OAuth2Client } from "google-auth-library";
import type { User as AuthJsUser } from "next-auth";
import type { Provider } from "next-auth/providers";
+import Authentik from "next-auth/providers/authentik";
import Credentials from "next-auth/providers/credentials";
import GitHub from "next-auth/providers/github";
import Gitlab from "next-auth/providers/gitlab";
@@ -71,6 +72,13 @@ export const getEEIdentityProviders = async (): Promise => {
const audience = await getTokenFromConfig(providerConfig.audience);
providers.push({ provider: createGCPIAPProvider(audience), purpose: providerConfig.purpose });
}
+ if (identityProvider.provider === "authentik") {
+ const providerConfig = identityProvider as AuthentikIdentityProviderConfig;
+ const clientId = await getTokenFromConfig(providerConfig.clientId);
+ const clientSecret = await getTokenFromConfig(providerConfig.clientSecret);
+ const issuer = await getTokenFromConfig(providerConfig.issuer);
+ providers.push({ provider: createAuthentikProvider(clientId, clientSecret, issuer), purpose: providerConfig.purpose });
+ }
}
// @deprecate in favor of defining identity providers throught the identityProvider object in the config file. This was done to allow for more control over
@@ -268,4 +276,12 @@ const createGCPIAPProvider = (audience: string): Provider => {
}
},
});
+}
+
+export const createAuthentikProvider = (clientId: string, clientSecret: string, issuer: string): Provider => {
+ return Authentik({
+ clientId: clientId,
+ clientSecret: clientSecret,
+ issuer: issuer,
+ });
}
\ No newline at end of file
diff --git a/packages/web/src/lib/utils.ts b/packages/web/src/lib/utils.ts
index ea229977f..d0030524e 100644
--- a/packages/web/src/lib/utils.ts
+++ b/packages/web/src/lib/utils.ts
@@ -11,6 +11,7 @@ import googleLogo from "@/public/google.svg";
import oktaLogo from "@/public/okta.svg";
import keycloakLogo from "@/public/keycloak.svg";
import microsoftLogo from "@/public/microsoft_entra.svg";
+import authentikLogo from "@/public/authentik.svg";
import { ServiceError } from "./serviceError";
import { StatusCodes } from "http-status-codes";
import { ErrorCode } from "./errorCodes";
@@ -65,16 +66,6 @@ export const createPathWithQueryParams = (path: string, ...queryParams: [string,
return `${path}?${queryString}`;
}
-export type AuthProviderType =
- "github" |
- "gitlab" |
- "google" |
- "okta" |
- "keycloak" |
- "microsoft-entra-id" |
- "credentials" |
- "nodemailer";
-
type AuthProviderInfo = {
id: string;
name: string;
@@ -140,6 +131,15 @@ export const getAuthProviderInfo = (providerId: string): AuthProviderInfo => {
src: microsoftLogo,
},
};
+ case "authentik":
+ return {
+ id: "authentik",
+ name: "Authentik",
+ displayName: "Authentik",
+ icon: {
+ src: authentikLogo,
+ },
+ }
case "credentials":
return {
id: "credentials",
diff --git a/schemas/v3/identityProvider.json b/schemas/v3/identityProvider.json
index de2e0d113..201c6ca2d 100644
--- a/schemas/v3/identityProvider.json
+++ b/schemas/v3/identityProvider.json
@@ -170,6 +170,28 @@
}
},
"required": ["provider", "purpose", "audience"]
+ },
+ "AuthentikIdentityProviderConfig": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "provider": {
+ "const": "authentik"
+ },
+ "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"]
}
},
"oneOf": [
@@ -193,6 +215,9 @@
},
{
"$ref": "#/definitions/GCPIAPIdentityProviderConfig"
+ },
+ {
+ "$ref": "#/definitions/AuthentikIdentityProviderConfig"
}
]
}