Skip to content

feat(seerr): Web/Container: Inject custom Seerr headers via nginx proxy#971

Open
v3DJG6GL wants to merge 34 commits intoDonutWare:developfrom
v3DJG6GL:feat/seerr-custom-headers
Open

feat(seerr): Web/Container: Inject custom Seerr headers via nginx proxy#971
v3DJG6GL wants to merge 34 commits intoDonutWare:developfrom
v3DJG6GL:feat/seerr-custom-headers

Conversation

@v3DJG6GL
Copy link
Copy Markdown
Contributor

@v3DJG6GL v3DJG6GL commented Apr 22, 2026

Pull Request Description

Currently, for the web/container version you can't configure global custom headers for Seerr.

There were already some attempts: PR #817 introduced SEERR_HEADER functionality, but it got removed again with #833.
This implementation had the flaw that the custom header was exposed to anyone with access to Fladder WebUI:
The SEERR_HEADER ENV value was written to /assets/config/config.json, which anyone with access to the Fladder WebUI can fetch.

With my new attempt, the custom headers are now routed to Seerr through the nginx proxy that already serves the web build, so the headers get injected server-side and should never reach the browser.

How it should work

  • You set SEERR_HEADER via the docker ENV, e.g:
    {"Remote-User":"you","CF-Access-Client-Id":"abc"}.

  • On startup, docker-entrypoint.sh runs it through jq and turns each entry into a proxy_set_header directive inside a location /seerr-proxy/ block in the generated nginx config.

  • The entrypoint also writes a new seerrProxyPath field into assets/config/config.json. On web, SeerrRequest in lib/providers/seerr_api_provider.dart picks that up and resolves requests against the proxy path instead of the raw Seerr URL.

  • Mobile/Desktop builds don't touch seerrProxyPath at all (guarded by kIsWeb) - they keep using the per-credential customHeaders like before.

Example configuration (docker-compose)

environment:
  SEERR_BASE_URL: https://SEERR.DOMAIN.TLD
  SEERR_HEADER: '{"Remote-User":"you","CF-Access-Client-Id":"abc"}'

Security model / intended use

  • SEERR_HEADER is intended for headers that authenticate the Fladder container to an outer auth layer in front of Seerr (e.g. Authelia, Authentik, forward-auth, Cloudflare Access, basic auth on a reverse proxy, etc.). Those headers let Fladder get past this out wall to reach Seerr.

  • What SEERR_HEADER is not for: Seerr's own X-Api-Key. The /seerr-proxy/ endpoint is not authenticated by Fladder - Fladder has no HTTP-layer auth at all. So a Seerr X-Api-Key placed here would let any HTTP caller on Fladder act as a Seerr admin (list users, create/modify/delete requests, change settings) - sth we don't really want ;)

  • Untrusted inputs are validated and escaped: Both in the docker entrypoint (before generating the nginx config) and in the Flutter client (before resolving URLs). Malformed input fails with a clear error instead of silently producing a broken config.

Clean-Up (leftover from #833)

I found some dead configuration in config.json which was introduced with #817 but was not removed by #833:

Issue Being Fixed

N/A

Screenshots / Recordings

N/A

Notes

AI Disclosure

Developed with assistance from Claude Code (Opus 4.7). The LLM helped me identify the related files, code parts and proposed possible code modifications and fixes.
I've manually reviewed, cleaned, refactored and hardened the code the best I could, but my Dart capabilities are not that good.
A Proper code review is required in any case - also especially since this PR is also focused on authentication...

Tested On

  • Android
  • Android TV
  • iOS
  • Linux
  • Windows
  • macOS
  • Web

Checklist

  • If a new package was added, did you ensure it works for all supported platforms?
    jq is alpine-only and only added for docker/web builds, not for other desktop/mobile builds.
  • Check that any changes are related to the issue at hand.

v3DJG6GL added 30 commits March 16, 2026 00:30
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