Skip to content

created a plugin for authentik / auth request#200

Open
daemon-byte wants to merge 4 commits into
bunkerity:mainfrom
daemon-byte:main
Open

created a plugin for authentik / auth request#200
daemon-byte wants to merge 4 commits into
bunkerity:mainfrom
daemon-byte:main

Conversation

@daemon-byte

Copy link
Copy Markdown

I originally managed this through config files, but as the number grew, it became messy and hard to maintain. To streamline the process, I developed a plugin to organize everything more cleanly. Since others might find it useful, I decided to share it here.

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2a6f9b77-2deb-4256-b14a-e1ace9b5c651

📥 Commits

Reviewing files that changed from the base of the PR and between 16ed8f0 and 1b33b02.

📒 Files selected for processing (2)
  • authentik/confs/server-http/authentik.conf
  • authentik/plugin.json
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
**/plugin.json

⚙️ CodeRabbit configuration file

**/plugin.json: plugin.json files define the settings schema that BunkerWeb reads to register settings and render the UI:

  • The top-level fields id, name, version, and stream (yes/no/partial) must stay consistent with the plugin directory name and its Lua module.
  • Ensure setting IDs remain stable unless there is an intentional breaking change documented in the PR.
  • Each setting must declare context (global or multisite), default, help, id, label, regex, and type. Regex validators must be anchored where appropriate, compile cleanly, and avoid catastrophic backtracking. Default values must satisfy their own validators.
  • USE_<PLUGIN> toggles are the standard gate for init_worker short-circuiting; keep them in sync with the Lua implementation.
  • Bump the per-plugin version field through ./misc/update_version.sh <new_version> so every plugin.json and the README badge move together. Do not edit the version in a single plugin.json by hand.
  • If a PR changes a setting ID, type, context, accepted value shape, or compatibility behaviour, require migration notes and confirm that the README settings table is regenerated via .tests/misc/json2md.py.

Files:

  • authentik/plugin.json
🔇 Additional comments (2)
authentik/plugin.json (1)

86-86: LGTM!

authentik/confs/server-http/authentik.conf (1)

1-1: LGTM!


Authentik Plugin (New)

Summary

  • Adds a new plugin at authentik/ implementing Authentik forward-auth (auth_request) for BunkerWeb.
  • Files added/modified: authentik/plugin.json, authentik/authentik.lua, authentik/confs/server-http/authentik.conf, authentik/README.md. Minor repo updates: README.md (catalogue entry), .gitignore (.idea).

Functional behaviour

  • Lua access handler (authentik/authentik.lua): performs a GET subrequest to {AUTHENTIK_URL}/outpost.goauthentik.io/auth/nginx with forwarded context (Host, X-Original-URL/URI, client IP/proto, selected client headers).
  • Bypasses auth for the local outpost path (AUTHENTIK_OUTPOST_PATH) to avoid subrequest loops.
  • On 200: optionally strips client-supplied identity headers and injects Authentik's X-authentik-* response headers into the upstream; propagates Set-Cookie to client.
  • On 401/403: returns HTTP 302 redirect to outpost start with rd param (original URL).
  • On upstream/configuration failures or unexpected statuses: returns internal server error.

User-visible changes

  • When enabled (USE_AUTHENTIK=yes), protected sites will redirect unauthenticated clients to Authentik and, on success, may receive identity headers and session cookies from Authentik.
  • Admins must configure AUTHENTIK_URL and may need to adjust AUTHENTIK_OUTPOST_PATH, proxy buffer settings and timeout.

Configuration / plugin.json schema

  • New plugin.json (version 1.10) exposes settings: USE_AUTHENTIK, AUTHENTIK_URL, AUTHENTIK_OUTPOST_PATH, AUTHENTIK_SSL_VERIFY, AUTHENTIK_TIMEOUT, AUTHENTIK_PROXY_BUFFER_SIZE, AUTHENTIK_PROXY_BUFFERS, AUTHENTIK_PASS_IDENTITY_HEADERS, AUTHENTIK_IDENTITY_HEADERS (defaults, regex validation and help text included).
  • Identity header handling: toggle to forward Authentik identity headers (disabled by default) plus configurable header list (space/comma-separated).

Documentation

  • Comprehensive README at authentik/README.md documenting request flow, installation (Docker/Swarm examples), Authentik admin setup, configuration reference, troubleshooting, and identity-header security guidance.
  • README catalogue updated to list Authentik plugin.

Security impact & notes

  • Positive: explicit stripping of client-supplied X-authentik-* headers before forwarding mitigates header spoofing when AUTHENTIK_PASS_IDENTITY_HEADERS=yes.
  • Sensitive behaviour: optional disabling of TLS verification (AUTHENTIK_SSL_VERIFY=no) is supported — this reduces TLS protection and should be avoided in production.
  • Propagation of Set-Cookie from Authentik: intentional to bind session cookies to the protected domain; operators must ensure cookie semantics are correct for their deployment.
  • Timeouts and proxy buffer tuning added to accommodate large Authentik response headers (groups / tokens); misconfiguration could expose resource/DoS considerations.

Compatibility / packaging / deployment

  • Adds a server-level snippet template (authentik/confs/server-http/authentik.conf) that must be included in server configuration when USE_AUTHENTIK=yes and AUTHENTIK_URL is set. It adjusts proxy_buffers/proxy_buffer_size and proxy_pass behaviour (path selection and optional proxy_ssl_verify off).
  • No changes to COMPATIBILITY.json detected; COMPATIBILITY.json maps core BunkerWeb versions, not per-plugin versions.
  • Plugin version is 1.10 (matches other plugins' plugin.json versions). The repository README displays a collection badge "bunkerweb_plugins-1.6" (collection label differs from plugin.json versions) — flag for maintainers: collection badge/versioning model differs from per-plugin "version" field; no automatic update to COMPATIBILITY.json observed.

Tests

  • No new integration or unit tests added (.tests contains tests for other plugins but none for authentik). CI/workflow files unchanged.

Impact summary for reviewers

  • Code review effort: low–medium (Lua auth flow is straightforward; server template needs review for proxy/pass semantics).
  • Operational impact: requires site-level configuration (AUTHENTIK_URL, optional proxy buffer/timeout tuning); enabling identity header forwarding changes upstream authentication assumptions and must be enabled only for trusted backends.

Walkthrough

Adds a new Authentik forward-auth plugin: plugin schema, Lua access-phase handler performing Authentik outpost subrequests, Nginx outpost proxy template, full plugin documentation, and repository housekeeping (.gitignore and README link).

Changes

Authentik Plugin Implementation

Layer / File(s) Summary
Plugin configuration schema and metadata
authentik/plugin.json
Defines plugin metadata and settings schema for activation, AUTHENTIK_URL/AUTHENTIK_OUTPOST_PATH, AUTHENTIK_SSL_VERIFY, AUTHENTIK_TIMEOUT, proxy buffer sizing, and identity-header forwarding (boolean + header list). (lines 1-90)
Lua authentication handler and request flow
authentik/authentik.lua
Implements access-phase authentik module: is_needed activation check, outpost-path bypass, outpost subrequest forwarding Host/X-Original-URL/IP/proto/selected headers, forwards Set-Cookie to client, optional identity-header passing on 200, 302 redirect to sign-in on 401/403, and 500 on configuration/subrequest errors. (lines 1-174)
Nginx outpost proxy configuration
authentik/confs/server-http/authentik.conf
Adds conditional server block (USE_AUTHENTIK == "yes") with proxy_buffers/proxy_buffer_size, port_in_redirect off;, and location {{ AUTHENTIK_OUTPOST_PATH }} proxying to Authentik or its outpost path; optional TLS verify skip, forwards Host and X-Original-URL, and strips request body. (lines 1-26)
Plugin documentation and repository integration
authentik/README.md, README.md, .gitignore
Comprehensive plugin README (request flow, install, admin setup, settings, troubleshooting, identity-header security). Root README updated to list Authentik in plugins; .gitignore now excludes .idea. (authentik README lines 1-194; README.md line 24; .gitignore line 7)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🔐 A sentinel stands at the gateway, Authentik-bound,
Lua whispers subrequests through the Nginx ground,
Sessions flutter forward on Set-Cookie winds,
Identity headers sail where the outpost begins,
New plugin, new guard — the site stands sound. 🌐

🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title lacks Conventional Commits format or component-description structure; it is overly casual ('created a plugin') and vague about the actual change. Reformat using 'feat: add Authentik forward authentication plugin' or 'feat: create Authentik plugin for auth request handling' to follow project conventions.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description is related to the changeset, explaining the motivations for introducing the Authentik plugin rather than managing via config files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@authentik/authentik.lua`:
- Around line 151-156: The loop that forwards identity headers uses exact key
lookup on res.headers (for _, h in
ipairs(split_headers(self.variables["AUTHENTIK_IDENTITY_HEADERS"])) ... local
value = res.headers[h]) which fails when header casing differs; update the
forwarding in the block that calls ngx_req.clear_header and ngx_req.set_header
to perform a case-insensitive lookup on res.headers (for example, check
res.headers[h] first, then res.headers[string.lower(h)] or build a lowercased
copy of res.headers once and read from that) so split_headers, the loop that
references res.headers, and the set_header/clear_header calls forward the header
values regardless of case.

In `@authentik/confs/server-http/authentik.conf`:
- Line 1: The template currently only checks USE_AUTHENTIK in authentik.conf and
can render an empty proxy_pass when AUTHENTIK_URL is unset; update the template
guard (the if that references USE_AUTHENTIK) to also verify AUTHENTIK_URL is
non-empty before emitting the authentik block, and apply the same non-empty
check around the proxy_pass lines (the proxy_pass entries on lines that
currently reference AUTHENTIK_URL) so Nginx never gets an empty target; refer to
the USE_AUTHENTIK and AUTHENTIK_URL variables and the proxy_pass entries in
authentik.conf when making this change.

In `@authentik/plugin.json`:
- Line 86: The current "regex" allows any header token; update it to only permit
header names that start with "X-authentik-" (case-insensitive) so the
identity-header allowlist can't include unrelated headers. Replace the existing
value for the "regex" property with a pattern enforcing case-insensitive
"X-authentik-" prefix followed by token chars and allowing multiple entries
separated by commas/spaces (e.g. use an inline case-insensitive regex such as
(?i)^X-authentik-[A-Za-z0-9-]+([ ,]+X-authentik-[A-Za-z0-9-]+)*$) so the schema
and the Lua flow only accept X-authentik-* headers.

In `@authentik/README.md`:
- Around line 136-149: The settings table in authentik/README.md is manually
maintained and must be regenerated from plugin.json; run the generation script
.tests/misc/json2md.py against this plugin's plugin.json and replace the current
hardcoded Settings table with the output so docs stay in sync. Locate
README.md's Settings section and plugin.json in the same module, run
.tests/misc/json2md.py to produce the markdown table, and commit the updated
README.md ensuring the generated table replaces the existing table (do not
hand-edit the rows).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 85d93dd3-d9c8-4791-ad0d-282147e90e3f

📥 Commits

Reviewing files that changed from the base of the PR and between 1aa4dc5 and 16ed8f0.

📒 Files selected for processing (6)
  • .gitignore
  • README.md
  • authentik/README.md
  • authentik/authentik.lua
  • authentik/confs/server-http/authentik.conf
  • authentik/plugin.json
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: Documentation should be concise, accurate, and written in British English:

  • Keep the structure clear with a sensible heading hierarchy.
  • Each plugin README contains a settings table generated from plugin.json via .tests/misc/json2md.py; regenerate it whenever settings change rather than hand-editing the table.
  • The repository README shows a compatibility badge tied to the plugins-collection version in COMPATIBILITY.json — keep it in sync with any version bump.
  • Prefer concrete instructions, accurate examples, and explicit prerequisites (Docker, sudo, required env vars like VIRUSTOTAL_API_KEY).
  • When a PR changes behaviour, defaults, packaging, or security posture, ask for the corresponding documentation update.

Files:

  • README.md
  • authentik/README.md
**/*.lua

⚙️ CodeRabbit configuration file

**/*.lua: Lua code runs on OpenResty inside the BunkerWeb nginx container and sits on the request hot path:

  • Every plugin subclasses bunkerweb.plugin via middleclass: local <name> = class("<name>", plugin) and plugin.initialize(self, "<id>", ctx) in initialize. Hook methods (init_worker, access, log, preread, ...) must return self:ret(ok_bool, msg, [http_status]). To deny a request, return self:ret(true, "reason", utils.get_deny_status()).
  • Gate expensive work at init_worker with utils.has_variable("USE_<PLUGIN>", "yes") and skip when self.is_loading is true, matching the pattern used across clamav.lua, coraza.lua, and virustotal.lua.
  • Use local variables and local module tables; avoid globals. Cache ngx.var.* and ngx.req.* values in locals instead of re-reading them repeatedly.
  • Precompile regular expressions in module-level locals; never compile inside request loops. For ngx.re.match/find/gmatch/sub, pass the option string "jo" (j enables PCRE JIT, o compiles the pattern once and caches it), anchor patterns with ^...$ when a full match is intended, and cap input length before matching to prevent ReDoS.
  • Validate and sanitise all request-derived input. Never evaluate request-derived code via load, loadstring, or similar mechanisms.
  • Use ngx.socket for raw TCP (see the ClamAV INSTREAM pattern in clamav.lua) and resty.http for HTTP upstreams (see virustotal.lua and coraza.lua). Prefer resty.upload for streaming request bodies — clamav.lua is the reference.
  • Cache upstream scan results by a strong digest of the body (SHA-512 in virustotal.lua) rather than by filename or weaker hashes; mind cache key length.
  • Shared-dictionary read-modify-write sequences are race-prone; prefer atomic operations such as incr or explicit locking where correctness matters.
  • Never log request bodies, cookies, bearer tokens, webhook secrets, or API keys.
  • Use pcall or explicit error...

Files:

  • authentik/authentik.lua
**/plugin.json

⚙️ CodeRabbit configuration file

**/plugin.json: plugin.json files define the settings schema that BunkerWeb reads to register settings and render the UI:

  • The top-level fields id, name, version, and stream (yes/no/partial) must stay consistent with the plugin directory name and its Lua module.
  • Ensure setting IDs remain stable unless there is an intentional breaking change documented in the PR.
  • Each setting must declare context (global or multisite), default, help, id, label, regex, and type. Regex validators must be anchored where appropriate, compile cleanly, and avoid catastrophic backtracking. Default values must satisfy their own validators.
  • USE_<PLUGIN> toggles are the standard gate for init_worker short-circuiting; keep them in sync with the Lua implementation.
  • Bump the per-plugin version field through ./misc/update_version.sh <new_version> so every plugin.json and the README badge move together. Do not edit the version in a single plugin.json by hand.
  • If a PR changes a setting ID, type, context, accepted value shape, or compatibility behaviour, require migration notes and confirm that the README settings table is regenerated via .tests/misc/json2md.py.

Files:

  • authentik/plugin.json
🪛 LanguageTool
authentik/README.md

[uncategorized] ~35-~35: A comma may be missing after the conjunctive/linking adverb ‘Otherwise’.
Context: ... flow itself, served by the outpost. 3. Otherwise the handler does an HTTP GET against ...

(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)


[uncategorized] ~40-~40: Use a comma before ‘so’ if it connects two independent clauses (unless they are closely connected and short).
Context: ... Authentik is relayed to the client so the session refreshes correctly. - *...

(COMMA_COMPOUND_SENTENCE_2)


[uncategorized] ~63-~63: Possible missing comma found.
Context: ...ed to be able to reach that public URL; otherwise login redirects from `/outpost.../start...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~131-~131: Possible missing comma found.
Context: ...'s response. 4. In the Authentik server logs you should see one `/outpost.goauthenti...

(AI_HYDRA_LEO_MISSING_COMMA)


[formatting] ~152-~152: Insert a comma before quoting reported speech: “says, "”…
Context: ...0 on every protected URL, scheduler log says "AUTHENTIK_URL not configured".** `USE_...

(SAID_COMMA_SPEECH)


[uncategorized] ~172-~172: Possible missing comma found.
Context: ...ntity headers downstream (opt-in).** By default this plugin only gates access and for...

(AI_HYDRA_LEO_MISSING_COMMA)

Comment thread authentik/authentik.lua
Comment thread authentik/confs/server-http/authentik.conf Outdated
Comment thread authentik/plugin.json Outdated
Comment thread authentik/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant