Compare commits

...

13 Commits

Author SHA1 Message Date
Dewi Roberts
a26cd079ea Add wording 2026-05-13 15:46:30 +03:00
Dewi Roberts
9853224275 Merge branch 'main' into website/integrations--add-absorb-LMS 2026-05-13 13:28:32 +01:00
Dewi Roberts
409f9ec429 Mdx and comments change 2026-05-13 15:21:29 +03:00
Teffen Ellis
2c3d11a4c3 core: harden npm install against supply-chain attacks (#22245)
* core: add .npmrc baseline to block dependency lifecycle scripts

Set ignore-scripts=true at the repo root, plus engine-strict, save-exact,
audit, and prefer-offline. This neutralizes the dominant npm supply-chain
attack vector — postinstall scripts in transitive dependencies — at the
cost of requiring an explicit rebuild for the handful of packages that
legitimately need install scripts (esbuild, chromedriver, tree-sitter,
tree-sitter-json). The next commit wires that rebuild into the Makefile.

Co-Authored-By: Playpen Agent <279763771+playpen-agent@users.noreply.github.com>

* core: route node installs through make to retire website preinstall hook

Make docs-install depend on a new root-node-install so the root deps
are guaranteed before the website install runs, removing the need for
the website/preinstall lifecycle script. Rebuild the small audited list
of trusted packages (esbuild, chromedriver, tree-sitter, tree-sitter-json)
after the web install so ignore-scripts=true remains the only path that
needs maintenance. web/README documents the new workflow.

Co-Authored-By: Playpen Agent <279763771+playpen-agent@users.noreply.github.com>

* Clean up install scripts.

* Track .npmrc in CODEOWNERS

---------

Co-authored-by: Playpen Agent <279763771+playpen-agent@users.noreply.github.com>
2026-05-13 12:20:36 +00:00
Dewi Roberts
f9b7d4c6ac Merge branch 'main' into website/integrations--add-absorb-LMS 2026-05-13 13:01:31 +01:00
Dewi Roberts
acbf176d50 Spellcheck 2026-05-13 15:01:04 +03:00
Dewi Roberts
85d2ac7735 Document 2026-05-13 14:54:58 +03:00
dependabot[bot]
a3c50ae92a core: bump django-stubs[compatible-mypy] from 6.0.3 to 6.0.4 (#22319)
Bumps [django-stubs[compatible-mypy]](https://github.com/typeddjango/django-stubs) from 6.0.3 to 6.0.4.
- [Release notes](https://github.com/typeddjango/django-stubs/releases)
- [Commits](https://github.com/typeddjango/django-stubs/compare/6.0.3...6.0.4)

---
updated-dependencies:
- dependency-name: django-stubs[compatible-mypy]
  dependency-version: 6.0.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-13 13:49:57 +02:00
dependabot[bot]
3ef36b9e9e ci: bump taiki-e/install-action from 2.77.3 to 2.77.4 in /.github/actions/setup (#22321)
ci: bump taiki-e/install-action in /.github/actions/setup

Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.77.3 to 2.77.4.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](e3134ec54b...ec28e28791)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.77.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-13 13:49:53 +02:00
Simonyi Gergő
691e173cad endpoints: remove print line (#22325) 2026-05-13 13:45:28 +02:00
Dewi Roberts
06d72b8386 Tabs 2026-05-08 18:59:18 +03:00
Dewi Roberts
c6771b2277 Headers 2026-05-08 18:33:58 +03:00
Dewi Roberts
ac3fc88bc9 Create doc 2026-05-08 18:24:15 +03:00
12 changed files with 325 additions and 13 deletions

View File

@@ -64,7 +64,7 @@ runs:
rustflags: ""
- name: Setup rust dependencies
if: ${{ contains(inputs.dependencies, 'rust') }}
uses: taiki-e/install-action@e3134ec54b36203e18f2d1e80652058bd078dd91 # v2
uses: taiki-e/install-action@ec28e287910af896fd98e04056d31fa68607e7ad # v2
with:
tool: cargo-deny cargo-machete cargo-llvm-cov nextest
- name: Setup node (web)

20
.npmrc Normal file
View File

@@ -0,0 +1,20 @@
# Block lifecycle scripts (preinstall/install/postinstall/prepare) from dependencies.
# This neutralizes the dominant npm supply-chain attack vector.
#
# Packages that legitimately need a build step (e.g. esbuild, chromedriver, tree-sitter)
# must be rebuilt explicitly:
#
# npm rebuild --foreground-scripts esbuild chromedriver tree-sitter tree-sitter-json
ignore-scripts=true
# Fail fast if the active Node/npm doesn't match the "engines" field.
engine-strict=true
# Pin exact versions so `npm install <pkg>` writes "1.2.3" not "^1.2.3".
save-exact=true
# Surface CVE warnings during install; doesn't block.
audit=true
# Suppress funding banners.
fund=false

View File

@@ -34,6 +34,7 @@ packages/django-channels-postgres @goauthentik/backend
packages/django-postgres-cache @goauthentik/backend
packages/django-dramatiq-postgres @goauthentik/backend
# Web packages
.npmrc @goauthentik/frontend
tsconfig.json @goauthentik/frontend
package.json @goauthentik/frontend
package-lock.json @goauthentik/frontend

View File

@@ -125,7 +125,7 @@ core-i18n-extract:
--ignore website \
-l en
install: node-install docs-install core-install ## Install all requires dependencies for `node`, `docs` and `core`
install: node-install web-install core-install ## Install all requires dependencies for `node`, `web` and `core`
dev-drop-db:
$(eval pg_user := $(shell $(UV) run python -m authentik.lib.config postgresql.user 2>/dev/null))
@@ -228,14 +228,26 @@ gen-dev-config: ## Generate a local development config file
## Node.js
#########################
# Packages whose install/postinstall scripts are required for correct
# operation (binary downloads, native bindings). The root .npmrc sets
# `ignore-scripts=true` to block dependency lifecycle scripts by default;
# this list is rebuilt explicitly with scripts re-enabled. Audit any
# additions: each entry runs arbitrary code at install time.
TRUSTED_INSTALL_SCRIPTS := esbuild chromedriver tree-sitter tree-sitter-json
node-install: ## Install the necessary libraries to build Node.js packages
npm ci
npm ci --prefix web
#########################
## Web
#########################
web-install: ## Install the necessary libraries to build the Authentik UI
npm ci --prefix web
web-postinstall: ## Trigger postinstall scripts for packages with native bindings or binary downloads, which are blocked by default for security reasons.
npm rebuild --prefix web --ignore-scripts=false --foreground-scripts $(TRUSTED_INSTALL_SCRIPTS)
web-build: node-install ## Build the Authentik UI
npm run --prefix web build
@@ -268,7 +280,7 @@ web-i18n-extract:
docs: docs-lint-fix docs-build ## Automatically fix formatting issues in the Authentik docs source code, lint the code, and compile it
docs-install:
docs-install: node-install
npm ci --prefix website
docs-lint-fix: lint-spellcheck

View File

@@ -31,7 +31,6 @@ class DeviceUser(VirtualUser):
username = "authentik:endpoints:device"
def has_perm(self, perm: str, obj: Model | None = None) -> bool:
print(perm)
if perm in [
"authentik_core.view_user",
"authentik_core.view_group",

View File

@@ -34,6 +34,7 @@ Komodo
Kubeconfig
Mautic
Mobilizon
myabsorb
Observium
Ofair
Ollama

View File

@@ -85,7 +85,7 @@ dev = [
"coverage[toml]==7.13.5",
"daphne==4.2.1",
"debugpy==1.8.20",
"django-stubs[compatible-mypy]==6.0.3",
"django-stubs[compatible-mypy]==6.0.4",
"djangorestframework-stubs[compatible-mypy]==3.16.9",
"drf-jsonschema-serializer==3.0.0",
"freezegun==1.5.5",

8
uv.lock generated
View File

@@ -394,7 +394,7 @@ dev = [
{ name = "coverage", extras = ["toml"], specifier = "==7.13.5" },
{ name = "daphne", specifier = "==4.2.1" },
{ name = "debugpy", specifier = "==1.8.20" },
{ name = "django-stubs", extras = ["compatible-mypy"], specifier = "==6.0.3" },
{ name = "django-stubs", extras = ["compatible-mypy"], specifier = "==6.0.4" },
{ name = "djangorestframework-stubs", extras = ["compatible-mypy"], specifier = "==3.16.9" },
{ name = "drf-jsonschema-serializer", specifier = "==3.0.0" },
{ name = "freezegun", specifier = "==1.5.5" },
@@ -1269,7 +1269,7 @@ s3 = [
[[package]]
name = "django-stubs"
version = "6.0.3"
version = "6.0.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django" },
@@ -1277,9 +1277,9 @@ dependencies = [
{ name = "types-pyyaml" },
{ name = "typing-extensions" },
]
sdist = { url = "https://files.pythonhosted.org/packages/86/0c/8d0d875af79bf774c1c3997c84aa118dba3a77be12086b9c14e130e8ec72/django_stubs-6.0.3.tar.gz", hash = "sha256:ee895f403c373608eeb50822f0733f9d9ec5ab12731d4ab58956053bb95fdd9e", size = 278214, upload-time = "2026-04-18T15:11:22.327Z" }
sdist = { url = "https://files.pythonhosted.org/packages/f9/82/ccf2a2dc9cdb4bd9cbe91f11e887589bf2da7609506db00ccbc73bd8a6da/django_stubs-6.0.4.tar.gz", hash = "sha256:7aee77e8de9c14c0d9cf84988befe826d93cbc15a87e0ade2943f14d553451cf", size = 280019, upload-time = "2026-05-09T21:24:30.436Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/80/a3/6751b7684d20fc4f228bdd3dd8341d382ab3faaf65d3d050c0d59ab0a1b0/django_stubs-6.0.3-py3-none-any.whl", hash = "sha256:5fee22bcbbad59a78c727a820b6f4e68ff442ca76a922b7002e57c25dd7cb390", size = 541570, upload-time = "2026-04-18T15:11:20.711Z" },
{ url = "https://files.pythonhosted.org/packages/ba/e7/5128914ada94dd6277626ef5a4a5680a4def7d2f9366214d26c1cd86723b/django_stubs-6.0.4-py3-none-any.whl", hash = "sha256:e991c68f77239663577a5f4fc75e99c84f867f378cafc97cbf4acc5aff378279", size = 543791, upload-time = "2026-05-09T21:24:28.218Z" },
]
[package.optional-dependencies]

View File

@@ -3,6 +3,27 @@
This is the default UI for the authentik server. The documentation is going to be a little sparse
for awhile, but at least let's get started.
# Setup
Install dependencies from the repo root with `make node-install` (or `make install` for the full
Python + web + docs bootstrap). This wraps `npm ci` and explicitly rebuilds the small set of
packages whose install scripts are required for the toolchain to function — currently `esbuild`,
`chromedriver`, `tree-sitter`, and `tree-sitter-json`.
The repo-root `.npmrc` sets `ignore-scripts=true` to neutralize the dominant npm supply-chain
attack vector. As a side effect, running `npm ci` directly in this directory will install
dependencies but skip those rebuilds, leaving `esbuild` and `chromedriver` in a non-functional
state. If you bypass `make`, run the rebuild step yourself:
```bash
npm rebuild --ignore-scripts=false --foreground-scripts \
esbuild chromedriver tree-sitter tree-sitter-json
```
New dependencies that ship install scripts must be audited and added to `TRUSTED_INSTALL_SCRIPTS`
in the repo-root `Makefile`. Each entry is arbitrary code that runs at install time, so the list
is intentionally small.
# The Theory of the authentik UI
In Peter Naur's 1985 essay [Programming as Theory

View File

@@ -0,0 +1,259 @@
---
title: Integrate with Absorb LMS
sidebar_label: Absorb LMS
support_level: community
authentik_version: 2026.5
---
import TabItem from "@theme/TabItem";
import Tabs from "@theme/Tabs";
## What is Absorb LMS?
> Absorb LMS is a cloud-based learning management system used by organizations to deliver, track, and manage employee, partner, and customer training. It lets you create or import courses, assign them to different audiences, and report on learner progress and compliance from a centralized portal.
>
> -- https://www.absorblms.com/
## Preparation
The following placeholders are used in this guide:
- `company.myabsorb.com` is the FQDN of the Absorb LMS deployment.
- `authentik.company` is the FQDN of the authentik installation.
:::info
This documentation lists only the settings that you need to change from their default values. Be aware that any changes other than those explicitly mentioned in this guide could cause issues accessing your application.
:::
authentik can be integrated with Absorb LMS to provider authentication through OIDC or SAML. You can optionally configure authentik to provision users to Absorb LMS via SCIM. Select your preferred option below:
<Tabs
defaultValue="oidc"
values={[
{ label: "OIDC", value: "oidc" },
{ label: "SAML", value: "saml" },
{ label: "SCIM", value: "scim" },
]}>
<TabItem value="oidc">
## authentik configuration
To integrate authentik with Absorb LMS via OIDC, you will need to create an application and provider pair in authentik.
### Create an application and provider in authentik
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Applications** > **Applications** and click **New Application** to open the application wizard.
- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings.
- **Choose a Provider type**: select **OAuth2/OIDC Provider** as the provider type.
- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations.
- Take note of the **Client ID** and **Client Secret** values as these will be required in the next section.
- Set a `Strict` Redirect URI to `https://company.myabsorb.com/account/openidconnect`
- Select any available **Signing key**.
- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/bindings-overview/) (policy, group, or user) to manage the listing and access to applications in a user's **Application Dashboard**.
3. Click **Create Application**.
## Absorb LMS configuration
1. Log in to the Absorb LMS Admin Dashboard (`company.myabsorb.com/admin/dashboard`) as an administrator.
2. Click the account icon in the top right, and then click **Portal Settings**.
3. In the right-hand sidebar, click **Manage SSO Settings**.
4. Under **SSO Configurations**, click **Manage**, click **Add SSO Configuration**, and set the following values:
- **Name**: `authentik`.
- **Method**: `Open ID Connect`.
5. Click **Next** and set the following values:
- **Client Identifier**: Client ID from authentik
- **Client Secret**: Client Secret from authentik
- **Issuer URL**: `https://authentik.company/application/o/<application_slug>/`
- **Authorization Endpoint URL**: `https://authentik.company/application/o/authorize/`
- **Token Endpoint URL**: `https://authentik.company/application/o/token/`
- **Logout URL** _(optional)_: `https://authentik.company/application/o/<application_slug>/end-session/`
6. Click **Next**, toggle **Automatically Redirect** to enabled, and select an **Assigned Route** from the dropdown.
7. Click **Save**.
## Configuration verification
To confirm that authentik is properly configured with Absorb LMS, log out and then log back in via the Absorb LMS user portal. You will be redirected to authentik, and once authenticated you will be logged in to the portal.
</TabItem>
<TabItem value="saml">
## authentik configuration
To integrate authentik with Absorb LMS via SAML, you will need to create an application and provider pair in authentik.
### Create an application and provider in authentik
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Applications** > **Applications** and click **New Application** to open the application wizard.
- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings.
- **Choose a Provider type**: select **SAML Provider** as the provider type.
- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations.
- Set **ACS URL** to `https://company.myabsorb.com/api/rest/v2/authentication/saml`
- Set **Audience** to `https://company.myabsorb.com`
- Under **Advanced Protocol Settings**:
- Select any available **Signing Certificate**.
- Set **NameID Property Mapping** to `authentik default SAML Mapping: Username`
- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/bindings-overview/) (policy, group, or user) to manage the listing and access to applications in a user's **Application Dashboard**.
3. Click **Create Application**.
## Absorb LMS configuration
1. Log in to the Absorb LMS Admin Dashboard (`company.myabsorb.com/admin/dashboard`) as an administrator.
2. Click the account icon in the top right, and then click **Portal Settings**.
3. In the right-hand sidebar, click **Manage SSO Settings**.
4. Under **SSO Configurations**, click **Manage**, click **Add SSO Configuration**, and set the following values:
- Set **Name** to `authentik`.
- Set **Method** to `SAML`.
- Set **Mode** to one of the three following values:
- `Identity Provider Initiated` - Users log in to Absorb LMS from authentik.
- `Service Provider Initiated` - Users attempting to log in to Absorb LMS are directed to authentik for authentication.
5. Click **Next** and set the following values:
- **Key**: paste the contents of your certificate from authentik
- **ID Property**: `Username`
- **Signature Type**: `SHA256`
- **Login URL**: `https://authentik.company/application/saml/<application_slug>/sso/binding/post/`
6. Click **Next** and then select an **Assigned Route** from the dropdown.
If you selected `Identity Provider Initiated`, enable the **Automatically Redirect** option.
7. Click **Save**.
## Configuration verification
To confirm that authentik is properly configured with Absorb LMS, log out and then log back in via the Absorb LMS user portal. You will be redirected to authentik, and once authenticated you will be logged in to the portal.
</TabItem>
<TabItem value="scim">
## SCIM provisioning _(optional)_
authentik can also optionally be integrated with Absorb LMS via SCIM for user provisioning. This can be done in conjunction with the OIDC or SAML integration, or configured on its own.
### Absorb LMS SCIM configuration
1. Log in to the Absorb LMS Admin Dashboard (`company.myabsorb.com/admin/dashboard`) as an administrator.
2. Click the account icon in the top right, and then click **Portal Settings**.
3. In the right-hand sidebar, click **Manage SSO Settings**.
4. Under **SCIM Settings** click **Manage**.
5. Take note of the **SCIM OAuth Client ID** and **SCIM OAuth Client Secret**. These values will be required later.
6. Select a **Default Department**. This is the department that users will be provisioned to in Absorb LMS.
7. Click **Save**.
### authentik SCIM configuration
To configure authentik as a SCIM provider for Absorb LMS, you will need to create an OAuth Source, a SCIM Provider Property Mapping, and a SCIM Provider in authentik.
#### Create an OAuth Source
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Directory** > **Federation and Social login** and click **New Source**.
3. Select **OpenID OAuth Source** as the Source type and click **Next**.
4. Set the following required values:
- **Source Name**: provide a name for the OAuth source
- **Slug**: provide a slug for the OAuth source or use the auto-generated slug
- **Consumer key**: the `SCIM OAuth Client ID` from Absorb LMS
- **Consumer secret**: the `SCIM OAuth Client Secret` from Absorb LMS
- **Scopes**: `offline_access`
- Under **URL Settings**:
- **Authorization URL**: `https://company.myabsorb.com/scim/v2/oauth/authorize`
- **Access Token URL**: `https://company.myabsorb.com/scim/v2/oauth/token`
- Set **Authorization code authentication method** to `Include the client ID and secret as request parameters`.
5. Click **Create**.
#### Create SCIM Provider Property Mapping
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Customization** > **Property Mappings** and click **New Property Mapping**.
3. Select **SCIM Provider Property Mapping** as the Property Mapping type and click **Next**.
4. Set the following required values:
- **Mapping Name**: `Absorb LMS SCIM Mapping`
- **Expression**:
```python showLineNumbers
givenName, familyName = request.user.name, " "
formatted = request.user.name + " "
# This default sets givenName to the name before the first space
# and the remainder as family name
# if the user's name has no space the givenName is the entire name
# (this might cause issues with some SCIM implementations)
if " " in request.user.name:
givenName, _, familyName = request.user.name.partition(" ")
formatted = request.user.name
locale = request.user.locale()
if locale == "":
locale = None
emails = []
if request.user.email != "":
emails = [{
"value": request.user.email,
"type": "work",
"primary": True,
}]
return {
"userName": request.user.username,
"name": {
"givenName": givenName,
"familyName": familyName,
},
"active": request.user.is_active,
"emails": emails,
"phoneNumbers": [
{
"primary": True,
# Enter the name of the attribute that you've stored
# the user's phone number under e.g. "phone"
"value": request.user.attributes.get("phone"),
"type": "work",
}
],
}
```
:::note Phone attribute
Ensure that you update the phone attribute to match the attribute name used in your users attributes.
:::
5. Click **Create**.
#### Create a SCIM Provider
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Applications** > **Providers** and click **New Provider** to open the provider wizard.
- **Choose a Provider type**: select **SCIM Provider** as the provider type.
- **Configure the Provider**: provide a name for the provider, and the following required configurations.
- **URL**: `https://company.myabsorb.com/scim/v2`
- **Authentication Mode**: `OAuth (Interactive)`
- **OAuth Source**: select the OAuth Source you created in the previous section
- **Group Filter**: select the group that contains users that should be provisioned to Absorb LMS
- Under **Attribute mapping**, remove the selected **User Property Mapping**, and replace it with `Absorb LMS SCIM Mapping`.
3. Click **Create**.
4. On the **Overview** tab of the SCIM provider, click the **(Re-)authenticate** button at the top right.
5. You should be redirected to Absorb LMS for authentication. Log in as an Absorb LMS administrator and approve the connection.
6. On the **Overview** tab of the SCIM provider, the **OAuth Status** should now show as `Authenticated`.
This step is only required when initially configuring the SCIM provider.
#### Set SCIM Provider as backchannel provider
1. Log in to authentik as an administrator and open the authentik Admin interface.
2. Navigate to **Applications** > **Applications** and click the name of your Absorb LMS application.
3. Click the plus (+) icon next to **Backchannel Providers** and select the SCIM provider that you created in the previous section.
4. Click **Save Changes**.
## Configuration verification
To confirm that authentik SCIM is properly configured with Absorb LMS, verify that users within the selected group are being provisioned in Absorb LMS.
If not, check the logs of SCIM provisioning tasks on the **Overview** tab of your SCIM provider.
</TabItem>
</Tabs>
## Resources
- [Absorb LMS Help Center](https://support.absorblms.com/hc/en-us)

View File

@@ -7,7 +7,6 @@
"": {
"name": "@goauthentik/docs",
"version": "0.0.0",
"hasInstallScript": true,
"license": "MIT",
"workspaces": [
"vendored/*",

View File

@@ -9,12 +9,12 @@
"build:integrations": "npm run build -w integrations",
"check-types": "tsc -b",
"docusaurus": "docusaurus",
"preinstall": "npm ci --prefix ..",
"lint": "eslint --fix .",
"lint:lockfile": "echo 'Skipping lockfile linting'",
"lint-check": "eslint --max-warnings 0 .",
"prettier": "prettier --write .",
"prettier-check": "prettier --check .",
"prettier-check": "npm run prettier-prepare && prettier --check .",
"prettier-prepare": "npm ci --prefix ../packages/prettier-config",
"start": "npm start -w docs",
"test": "node --test"
},