* web: Tidy form explainer, formatting.
* web/admin/stages: use ak-text-input for stage name field
Replace the hand-rolled ak-form-element-horizontal + input name field
with the shared ak-text-input component across the stage forms, and give
the label and placeholder shared message IDs (stage.name.*).
Co-Authored-By: Playpen Agent <279763771+playpen-agent@users.noreply.github.com>
---------
Co-authored-by: Playpen Agent <279763771+playpen-agent@users.noreply.github.com>
* website/docs: document ak_call_policy error handling and context mutation
* chore: remove the context override warning since it is fixed in a separate PR
---------
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
* website/docs: show how to handle an object-shaped `groups` claim
#25208 made an unusable group identifier a skip rather than an HTTP 500,
and documented that entries which are not simple values are dropped. It
did not say what an affected operator should do instead, so the docs
stop at describing the loss.
@rissson's point on #25396 is the right one: there is no standard for
what a `groups` claim contains, so authentik should not guess at it, and
the extension point for this is property mappings. That works today — a
user property mapping runs before the identifiers are read, so it can
reduce object entries itself.
Documents both halves of the recipe: reducing entries to identifiers in a
user property mapping, and recovering the provider's own group names in a
group property mapping, which receives `group_id` alongside the claim.
Both snippets were run against a source with an object-shaped claim
before being written down:
input: [{"id": "g1", "name": "Admins"},
{"value": "g2", "display": "Devs"},
"plain"]
result: {"g1": {"name": "Admins"}, "g2": {"name": "Devs"},
"plain": {"name": "plain"}}
covering the `id`/`name` and SCIM `value`/`display` shapes and leaving a
plain string entry untouched.
* Update index.md
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
* Update website/docs/users-sources/sources/property-mappings/index.md
Co-authored-by: Dominic Roy <dominic@goauthentik.io>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
---------
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dominic Roy <dominic@goauthentik.io>
web: let the error-reporting setting govern Sentry in production
`init({ enabled: process.env.NODE_ENV !== "production" })` disabled the
SDK in exactly the builds that ship: the container's web stage sets
`NODE_ENV=production` (lifecycle/container/Dockerfile), and the bundler
inlines it. An administrator who turned error reporting on in their
config therefore received nothing, while `browserTracingIntegration` was
registered only in production — the opposite polarity — so development
had the SDK on with no tracing integration behind it.
Consolidates the decision into `sentryEnabled(cfg, debug)`:
- The administrator's `errorReporting.enabled` decides, in every
environment; `CanDebug` still forces it on.
- Development additionally honors `?disable-sentry`, so a noisy local
session can opt out for one load without a rebuild.
- The tracing integration is registered whenever the SDK runs. It has
always been configured with the automatic instrumentation off, since
the router opens the spans itself.
`enabled: true` stays on the `init` call so the decision is readable off
the client, which is how the router outlets gate their spans.
Tidy.
* website/integrations: add vcf9
* cleanup
* Update website/integrations/hypervisors-orchestrators/vmware-cloud-foundation/index.mdx
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
---------
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
* stages/authenticator_duo: return a descriptive error when the Duo API is unreachable
`_duo_import_devices` caught only `RuntimeError`, but `duo_client` surfaces
transport failures as the underlying socket/TLS error. `SSLCertVerificationError`
is an `OSError`, not a `RuntimeError`, so a Duo endpoint behind an untrusted
certificate escaped the handler entirely and the request finished as a bare 405
with no actionable error.
`OSError` is also in `authentik.lib.sentry.ignored_classes`, so the exception was
dropped from error reporting too, leaving nothing to diagnose from.
Catch the transport failures explicitly and map them to the documented 400 with a
descriptive message, ordered narrowest-first since
SSLCertVerificationError < SSLError < OSError:
- certificate verification failure -> "TLS certificate verification failed."
- any other TLS failure -> "TLS error."
- any other connection failure -> "Failed to connect to Duo."
The messages stay categorical and do not echo exception text, keeping the
existing behaviour of not leaking internals to the API caller.
closes#22896
* translate
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
* packages/theme: add the @goauthentik/theme design-system package (#23341)
* packages/fonts: add @goauthentik/fonts package
Extract the bundled web fonts out of web/ into a dedicated
@goauthentik/fonts workspace package: the RedHat variable faces, the
PatternFly pficon icon face, and the FontAwesome Free solid face, each
with its upstream license recorded under licenses/.
web/ now pulls the faces and icons from the package's
@goauthentik/fonts/faces.css and @goauthentik/fonts/icons.css entry
points instead of the old #fonts/* import and the inlined pficon.scss
vendor sheet.
Anchor esbuild's [dir] at the monorepo root via outbase so assets pulled
from the out-of-web package no longer resolve to a "_.._" segment, which
Go's //go:embed silently drops from the embedded outpost build.
Co-Authored-By: Ken Sternberg <ken@goauthentik.io>
* packages/theme: add @goauthentik/theme design-system package
Add @goauthentik/theme, which defines authentik's design tokens (color,
typography, fonts, spacing, shape, shadow, motion, z-index) in TypeScript
and builds them into CSS via styleframe.
Token names carry a distinct separator per category so the token type is
recoverable from the name alone. That is worth the verbosity: it keeps
the DX legible and leaves room for automatic theme management and future
tooling built on top of the token set.
Co-Authored-By: Ken Sternberg <ken@goauthentik.io>
* web/theme: add a demo page for the theme tokens
Add a self-contained demo page, built by build-demo.mjs, that renders
every theme token — colors, typography, spacing, shape, shadow, motion —
so the design system can be eyeballed in isolation while it evolves.
Co-Authored-By: Ken Sternberg <ken@goauthentik.io>
* Heal lockfile.
* Fix spelling.
* Fix grouping.
---------
Co-authored-by: Ken Sternberg <ken@goauthentik.io>
* web/elements/ak-mdx: drop React + runtime MDX eval, use unified pipeline
Replace `@mdx-js/mdx`'s `evaluate`/`run` (which depends on `'unsafe-eval'`
in the page CSP) with a pure `unified`/remark/rehype pipeline. URL-mode
content now arrives from the build-time `mdx-plugin` as pre-rendered HTML
and is stamped through a Trusted Types passthrough policy
(`CompiledMarkdownTrustPolicy`) so admin-side custom elements like
`<ak-alert>` and `<ak-md-a>` survive. Content-mode (admin-supplied
markdown) is compiled in-browser via `compileRuntimeMarkdown` and routed
through the existing `BrandedHTMLPolicy` (DOMPurify).
`<ak-md-a>` replaces the React `MDXAnchor`/`MDXWrapper` pair: a tiny Lit
custom element with `display: contents` that intercepts in-doc fragment
clicks for shadow-root scrolling. The remark plugins gain `caution` and
`tip` admonition types and promote `:::name[Title]` directive labels to
`<strong>`. `one-dark.css` learns `:host` so syntax-highlighted code
blocks inherit the palette inside `<ak-mdx>`'s shadow tree.
Removes `@mdx-js/mdx`, `react`, `react-dom`, `rehype-mermaid`, and
`remark-mdx-frontmatter`. Adds `unified`, `remark-parse`, `remark-rehype`,
and `mdast-util-to-string`.
Co-Authored-By: Agent <279763771+playpen-agent@users.noreply.github.com>
* web/bundler/mdx-plugin: pre-render markdown to HTML at build time
Compile each `.md` / `.mdx` file through a build-time `unified` pipeline
(remark-parse, GFM, frontmatter, directives, custom admonition/headings/
lists transforms; rehype-rehype, anchor wrapping, syntax highlighting,
mermaid extraction) and emit a JSON envelope of
`{ content: HTML, frontmatter, publicPath, publicDirectory }`. The
on-load result still ships via the `file` loader so the runtime side
keeps its existing fetch path. The compiled HTML uses `<ak-md-a>` and
`<ak-alert>` custom elements so `<ak-mdx>` can stamp it directly into
shadow DOM with no client-side JavaScript evaluation.
Plugin is split across four sibling files (`node.js`, `compile.js`,
`remark.js`, `rehype.js`) so each concern lives in its own module. The
title/wrapper HTML is built as a hast tree and serialized through
`hast-util-to-html` rather than string-concatenated, dropping the
hand-rolled `escapeHTML` helper and unifying escape semantics with the
rest of the document.
Co-Authored-By: Agent <279763771+playpen-agent@users.noreply.github.com>
* web/test: e2e ak-mdx pipeline via OAuth2 provider docs
The OAuth2 provider docs page exercises the full pipeline in one place:
frontmatter title, multiple H2 slugs, `:::caution`/`:::info` admonitions
(with and without titles), relative-doc links, external links, and an
embedded mermaid sequence diagram. Tests boot the admin UI, provision a
fresh OAuth2 provider, navigate to its view page, and assert against the
compiled DOM inside `<ak-mdx>`'s shadow root.
Co-Authored-By: Agent <279763771+playpen-agent@users.noreply.github.com>
* web/elements/ak-mdx: sanitize replacer output, note pipeline drift
Address PR review feedback on the URL-mode trust boundary. `<ak-mdx>`'s
`replacers` hook runs over pre-rendered build-time HTML before it is
stamped into the DOM, and consumers (e.g. `ProxyProviderViewPage`) splice
admin-controlled values such as `provider.externalHost` into it. The old
React pipeline ran replacers on raw markdown that was then compiled, so
those values were HTML-escaped on serialization; the new URL mode passed
the post-replacer HTML straight through, dropping that guarantee.
Replace the passthrough `CompiledMarkdownTrustPolicy` with
`CompiledMarkdownSanitizePolicy`: a DOMPurify policy that whitelists the
custom elements (`<ak-alert>`, `<ak-md-a>`, `<ak-diagram>`) and the
`part`/`level` attributes our pipeline emits, and strips anything else a
replacer could inject.
Also add a reciprocal drift note to the runtime `markdown.ts` pointing at
`bundler/mdx-plugin/`, mirroring the existing note on the bundler side.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix anchor slugification.
* Spellcheck.
---------
Co-authored-by: Ken Sternberg <ken@goauthentik.io>
Co-authored-by: Agent <279763771+playpen-agent@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>