Skip to content

Releases: ingres-si/ingressi

v1.13.3

Choose a tag to compare

@fuomag9 fuomag9 released this 29 Sep 19:37
Immutable release. Only release title and notes can be modified.
b9a903b

Fixes

  • L4 proxy hosts with load balancing enabled no longer make Caddy reject the whole config with unknown field "retries" (#301, #302). The unsupported Retries and Unhealthy Latency fields are removed from the L4 dialog, and legacy stored values are ignored.

Dependencies

  • better-auth 1.7.6, drizzle-orm 0.45.3, next 16.3.6, maplibre-gl 6.11.2, apexcharts 7.6.0, lucide-react 1.48.0, plus the dev-dependency group (#299, #300).
  • Docker golang and ubuntu base images bumped (#297, #298); Caddy compatibility pins refreshed (#294).

Upgrade notes

No upgrade actions needed: docker compose pull && docker compose up -d.

v1.13.2

Choose a tag to compare

@fuomag9 fuomag9 released this 27 Sep 01:10
Immutable release. Only release title and notes can be modified.
4e2c1bb

A security fix release for v1.13.1. It covers forward-auth identity headers, the WAF "Skip OWASP CRS for path" template, secrets left in the database file after encryption, instance sync, disabled users and WAF event redaction. Some changes need action from operators: check the X-CPM-User and WAF template items, and rotate CA keys and DNS credentials if database backups from before the upgrade exist. The README section Upgrade Notes → Upgrading from v1.13.1 covers every item.

Upgrade notes

Pull and recreate the containers with docker compose pull && docker compose up -d.

These changes also apply when upgrading from an earlier release.

  • X-CPM-User is now the sign-in username, or the email address for an account without one. It used to be the display name, which is not unique (users, OAuth providers and ADMIN_USERNAME choose it), so an upstream trusting it could take one user for another. An upstream that maps users by this header (e.g. Grafana's auth proxy) sees new values and may create new users for them; map the existing ones or key them on X-CPM-User-Id, the account's id. See Identity headers.
  • WAF template "Skip OWASP CRS for path". The v1.13.x template matched the raw request URI, so /api/../index.php or /api/%2e%2e/index.php turned the OWASP CRS off for a path outside /api/. Replace stored copies (SecRule REQUEST_URI "@beginsWith /api/" … ctl:ruleRemoveByTag=OWASP_CRS") with the new template: SecRule REQUEST_FILENAME "@rx \A/api/(?:[^.]|\.[^.])*\.?\z" "id:9001,phase:1,pass,nolog,ctl:ruleRemoveByTag=OWASP_CRS", which matches the decoded path and skips nothing when it contains ...
  • Deleted secrets are wiped from the database file. SQLite now overwrites deleted content (PRAGMA secure_delete), and the first start after the upgrade runs VACUUM once, as does any start whose migrations encrypt or replace stored secrets. Before this, the plaintext CA private keys and DNS provider credentials that earlier releases encrypted on startup, and the CA keys the first sync removed from slaves, could remain in the file's free pages. VACUUM needs free disk space about the size of the database; if it fails, the start logs Failed to VACUUM the database and continues. Backups or copies of the database made before the upgrade may still hold them: if any exist, rotate the CA keys and DNS provider credentials.
  • Forward auth: copy headers Authorization, Proxy-Authorization, Cookie. When one of them is listed in the copy headers of generic or Authentik forward auth and the auth server returns no value for it, the client's own value is now removed on protected routes, after the auth server has seen it, instead of reaching the upstream. On excluded paths and on API bypass routes the client's credentials still reach the upstream unchanged, since nothing authenticates those requests.
  • Stored WAF directives left out of the config are now listed on the WAF page. A left-out deny rule (e.g. one using @ipMatchFromFile) no longer blocks anything, and when a SecDefaultAction is left out, later rules using block follow Coraza's default action instead, which does not block.
  • Disabled users get no Better Auth session: signing in answers as a wrong password does, and disabling a user now also ends their dashboard sessions.
  • Self-registration refuses an email address that another account has or signs in with using Better Auth's "User already exists. Use another email.", whatever the reason. An OAuth sign-up whose email has no @, or ends in @localhost (the forward-auth portal's names), is refused.
  • Editing a user's email (dashboard or PUT /api/v1/users/{id}) stores it trimmed and lowercased, and refuses an address that lowercasing would turn into another one (such as one with the Kelvin sign), as creating a user does.
  • WAF events also redact credential query parameters in the request URI (token, api_key, password, code, …), form fields and query parameters with such names in rule messages (ARGS:password), and headers whose names contain such words (e.g. X-Access-Token).

v1.13.1

Choose a tag to compare

@fuomag9 fuomag9 released this 26 Sep 22:26
Immutable release. Only release title and notes can be modified.
cd31c64

A security hardening release covering authentication, forward auth, stored secrets, instance sync, mTLS and the WAF (#296), plus a fix that stops CPM from deriving sign-in usernames from email addresses. v1.13.0 has been withdrawn and is replaced by this release. Several changes need action from operators. If you run v1.12.0 or earlier, upgrade directly to v1.13.1 and read the upgrade notes below before pulling the new images. The README section Upgrade Notes → Upgrading from v1.12.0 or earlier covers every item in full.

Upgrade notes

Pull and recreate the containers with docker compose pull && docker compose up -d. docker compose restart does not re-read .env.

Check before upgrading

  • Example secrets are refused. In production the web container refuses to start when SESSION_SECRET is a shipped placeholder (including the old .env.example value your-secure-session-secret-here-min-32-chars) or ADMIN_PASSWORD is an example password from an earlier README or .env.example ("ADMIN_PASSWORD is an example value from the documentation; choose your own password"). Generate a new secret with openssl rand -base64 32. Stored secrets that were encrypted under the placeholder are re-encrypted with the new secret on the next start, so you don't have to re-enter anything. For any other rotation, put the old value in SESSION_SECRET_PREVIOUS (see Rotating SESSION_SECRET in the README). .env.example now leaves SESSION_SECRET, ADMIN_PASSWORD and CLICKHOUSE_PASSWORD empty.

  • Using your own compose file? Pass the new variables through. The stock docker-compose.yml passes SESSION_SECRET_PREVIOUS, FORWARD_AUTH_ALLOWED_PORTS, TRUSTED_CLIENT_IP_HEADER and INSTANCE_SYNC_TIMEOUT_MS to the web container. The web container only gets the variables listed in the web service's environment, so a value that exists only in .env has no effect. If you run a custom or modified compose file, add these variables there. This also applies to existing variables the stock file doesn't list (e.g. INSTANCE_MODE: ${INSTANCE_MODE:-}). Give numeric variables their documented default rather than an empty value, because an empty value is read as 0 (e.g. LOGIN_MAX_ATTEMPTS: ${LOGIN_MAX_ATTEMPTS:-5}).

  • Forward auth on a non-standard port. If browsers reach forward-auth protected sites on a port other than 80/443 (e.g. Caddy published as 8443:443, or NAT), set FORWARD_AUTH_ALLOWED_PORTS=8443 (comma-separated for several) and recreate the web container. Without it, existing forward-auth sessions stop validating, the portal shows "This site is served on port 8443, which is not allowed for forward authentication…" and the web container logs [forward-auth] Rejected host:8443 … FORWARD_AUTH_ALLOWED_PORTS.

  • Instance sync: upgrade slaves before the master, or at the same time. An upgraded master seals certificate private keys and DNS provider credentials to each slave's own key (see Instance sync under Highlights). A slave still on v1.12.0 or earlier gets the old payload and needs the master's SESSION_SECRET as its own. A master still on v1.12.0 or earlier sends DNS provider credentials encrypted with its own SESSION_SECRET, so every slave needs that secret as SESSION_SECRET or in SESSION_SECRET_PREVIOUS. Otherwise applying the synced config fails. Keep the shared secret until every instance runs v1.13.1. After that, each instance can have its own secret.

  • Instance sync no longer follows redirects. Point each slave URL (in the UI or in INSTANCE_SLAVES) at the final URL. A slave that redirects now fails with "Sync key request failed with HTTP 302" (or 301/308). Each sync request is limited to INSTANCE_SYNC_TIMEOUT_MS (default 60 s; reported as "Sync timed out"), so raise it for slaves that take longer to apply a config. Slave URLs with credentials, a query string or a fragment are rejected, and such INSTANCE_SLAVES entries are skipped with Skipping INSTANCE_SLAVES entry <index>: <reason>.

  • Proxies in front of a slave must pass GET as well as POST on /api/instances/sync, including the Authorization header and the query string, and must not cache the GET reply. Before every sync, the master fetches the slave's sync key with this request. A 405 makes an upgraded slave look like an older release. Any other refusal fails the sync with "Sync key request failed with HTTP ".

  • Sync key pinning starts on the first sync. After the upgrade, the master pins each slave's sync key the first time it sees one. From then on:

    • A slave that comes back with a different key (e.g. reinstalled with a new SESSION_SECRET) fails with "Slave sync key changed; verify the slave, then pin its new key or reset its key pin" until you pin its new key on the master.
    • When you rotate a slave's SESSION_SECRET, keep the old value in the slave's SESSION_SECRET_PREVIOUS until the master has synced to it once (click Sync now on the master). The master then re-pins the new key automatically. For slaves pinned with syncPublicKey/syncKeyId in INSTANCE_SLAVES, update the entry instead.
    • After downgrading a slave to v1.12.0 or earlier, reset its key pin. Otherwise its syncs fail with "Sync key request failed with HTTP 405".
    • To leave no trust-on-first-use window, pin each slave's key before the first sync (see New configuration).
  • CA private keys stay on the master. CA private keys are now encrypted at rest with SESSION_SECRET and are no longer synced. The first sync removes the copies that older versions stored on slaves. Slaves still validate client certificates, but a slave promoted to master cannot issue certificates from the existing CAs. Back up the master's database together with its SESSION_SECRET.

  • WAF custom directives. Some lines are no longer sent to Caddy. Stored rules are kept, but they are left out of the generated config, and the web container logs [waf] <source>: N custom directive line(s) are not sent to Caddy and have no effect: …. The dropped lines are:

    • rules using file-reading or exec operators (@pmFromFile/@pmf, @ipMatchFromFile/@ipMatchF, @inspectFile, @validateSchema). The data-file operators still work with the embedded @owasp_crs/*.data files when the CRS is loaded.
    • the setenv action, and ctl:ruleEngine in any spacing or quoting.
    • lines Coraza cannot parse, and directives continued over several lines with a trailing \.
    • the rest of a chain when one of its lines is dropped.
    • rules that reuse an earlier rule's id:.

    Check the log after upgrading and rewrite any affected rules.

  • Host placeholders are sent literally. {env.*}, {system.*} and {file.*} are no longer expanded in default responses, error pages, path-block bodies and redirect rule targets. Request placeholders such as {http.request.uri} and {http.request.host} still expand. For example, rewrite https://{env.PRIMARY_DOMAIN}{http.request.uri} with a literal host.

  • Database file permissions. On startup, the SQLite database and its -journal/-wal/-shm files lose their world permission bits. Owner and group bits are unchanged. A backup job that reads the files as an unrelated user needs to run as the owner or a member of the files' group.

Behaviour changes

  • Admin credentials from the environment are applied only when they change. ADMIN_USERNAME/ADMIN_PASSWORD are applied when the admin is created and whenever they change, instead of on every start. A password changed in the UI now survives restarts. On the first start after upgrading, a stored admin password that differs from ADMIN_PASSWORD (and is not admin or a documented example) is kept, and a warning is logged. To force the env password, change ADMIN_PASSWORD again and recreate the web container. A changed ADMIN_USERNAME is still applied on that first start, unless another account already signs in with it (see Sign-in usernames under Highlights). The same steps recover a lost admin password: they reset the primary admin's password and its username to ADMIN_USERNAME, restore its admin role, re-activate it, and sign out its sessions.
  • Password policy everywhere. Passwords must be 12–256 characters with upper- and lowercase letters, a digit and a special character. This now also applies to admin-created users (dashboard and POST /api/v1/users), password changes, and Better Auth self-registration (AUTH_ALLOW_SELF_REGISTRATION=true) and reset. Scripts that create users with weaker passwords get 400.
  • Password changes sign out other sessions. Changing or setting a password signs out the user's other dashboard sessions and all of their forward-auth sessions. API tokens are kept, and you can revoke them under Profile → API Tokens.
  • Unused Better Auth self-service endpoints are disabled: /api/auth/update-user, /change-password, /change-email, /delete-user, /unlink-account, /update-session, /verify-password and /is-username-available. Use the Profile page or /api/v1/ instead. With AUTH_ALLOW_OAUTH_REGISTRATION=false, an OAuth sign-in can no longer create an account, even if the client asks for sign-up.
  • Sign-in usernames. The login page signs in by username only and ignores case. CPM never generates a username from an email address. Startup, profile edits and email changes leave stored usernames as they are. The one exception is the primary admin: applying a changed ADMIN_USERNAME or ADMIN_PASSWORD resets its username to ADMIN_USERNAME and its email to <ADMIN_USERNAME>@localhost. An account without a username gets its own email address, lowercased, as its username only if that address is already a valid username (3–255 characters from A-Z a-z 0-9 _ . @ -) and no other account signs in with it or has it as its email address. Otherwise an administrator sets the username on the Users page (**...
Read more

v1.12.0

Choose a tag to compare

@fuomag9 fuomag9 released this 22 Sep 15:01
Immutable release. Only release title and notes can be modified.
e5e7f00

Highlights

Generic forward auth (#188)

Proxy hosts can now use a generic forward-auth provider (Authelia preset or fully custom) alongside the existing Authentik integration and the built-in CPM portal, with the split browser vs API pattern for mixed UI + API services:

  • Browser requests (Accept: text/html, no X-Requested-With) keep the auth server's portal-redirect flow — 302s pass through so users get the normal login experience.
  • API split mode: with api_split enabled, API clients and WebSocket handshakes get a bare 401 instead of an HTML login page mid-stream — a second route converts any 3xx from the auth server into a static 401.
  • Bypass headers (e.g. X-Api-Key) let requests skip forward auth entirely so the upstream can enforce its own API-key auth (the Moonraker/Spoolman case), replacing hand-written customPreHandlersJson subroutes.

Security hardening: identity headers the auth server returns (Remote-User, Remote-Groups, …) are stripped from inbound requests on every route of the host — protected or not — preventing identity spoofing to the upstream (same class of fix as the X-CPM-* stripping). Header names are validated against the RFC 7230 token grammar, placeholders are stripped from endpoints and paths, and enabled-but-invalid configs are rejected at write time so a host can never silently publish unprotected.

Surface: forwardAuth field on proxy hosts, Settings > Forward Auth Defaults (synced to slave instances), /api/v1/settings/forward-auth API group, and the OpenAPI ForwardAuthConfig schema. Tested with 14 functional e2e tests against real Caddy via a mock Authelia container (browser 302 / API 401 / WS 401 / bypass / forged-header stripping) plus real Authelia and real Moonraker integration tests.

L4 hosts can no longer bind reserved ports 80/443/2019 (#295)

An L4 host listening on :443 (or :80) while regular HTTPS proxy hosts exist made CPM generate two independent listeners on the same port. Caddy sets SO_REUSEPORT on every listener, so the second bind succeeded silently — and the kernel then split new connections between the two sockets, failing ~50% of TLS handshakes with tlsv1 alert internal error (reported and confirmed at kernel level in #295). Two independent HTTP and layer4 servers sharing port 443 is not supported by Caddy (the caddy-l4 docs require listener wrappers for that), so CPM now refuses the invalid configuration instead of generating it:

  • L4 listen addresses on ports 80, 443 and 2019 are rejected on create and update — in the UI, the REST API and server actions — with the reserved ports named in the error.
  • Instance sync rejects synced L4 hosts on reserved ports, so a replica can't inherit the broken config.
  • Config generation and the L4 port manager skip legacy rows already on a reserved port and log a warning, so an existing bad row can't poison :443 for every other host until it's fixed.
  • The create/edit dialog documents the reservation; the wiki no longer describes the TLS SNI example as "on port 443" and gained a troubleshooting entry.

If you have an existing L4 host on :443, move it to a different listen port (e.g. :8443) — SNI matching and passthrough behave the same, and "Apply Port Changes" publishes the new mapping.

Caddy monitor: config drift detected by content

The monitor's restart detection compared the live config ID against a literal "empty" marker — but Caddy always serves an ETag, so the marker was unreachable and no configuration re-push ever happened after the l4-port-manager recreated the caddy container, leaving it unconfigured until something else pushed config. Every successful applyCaddyConfig() now records the sha256 of the config Caddy is actually serving, and the monitor re-pushes whenever the live hash differs — catching empty configs, the image's default Caddyfile, and stale autosaves alike.

Maintenance

  • Caddy: bump otlptracegrpc/otlptracehttp to 1.46.0 and the otel/log 0.21.0 line so the tree compiles against otel core 1.46.0 (#284, #285–#288).
  • Bump TypeScript 5.9.3 → 7.0.2 (#293), 9 production (#292) and 4 development (#291) dependency updates.
  • e2e: real Authelia and real Moonraker integration tests for the generic forward-auth provider.
  • Repo cleanup: the forward-auth security analysis moved out of the repository (docs/ is now gitignored).

Changes

  • e5e7f00 fix(l4): reject reserved listen ports 80/443/2019 for L4 proxy hosts (#295)
  • 93b05fd deps(deps-dev): bump typescript from 5.9.3 to 7.0.2 (#293)
  • f0bd0f0 deps(deps): bump the production-dependencies group with 9 updates (#292)
  • 3b2a595 deps(deps-dev): bump the development-dependencies group with 4 updates (#291)
  • 286de86 caddy: bump otel exporters to match merged otel 1.46.0 core (#285-#288)
  • 9d75485 chore: remove security analysis from repo and ignore docs/
  • c8a360b test(e2e): add real Authelia and real Moonraker integration tests for generic forward auth
  • 7b6a1d1 feat(forward-auth): add generic forward-auth provider with split browser vs API auth (#188)
  • 255ab49 caddy: bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc (#284)
  • 3dbb3b8 fix(caddy-monitor): detect config drift by content, not an unreachable sentinel

Full Changelog: v1.11.3...v1.12.0

v1.11.3

Choose a tag to compare

@fuomag9 fuomag9 released this 17 Sep 17:46
Immutable release. Only release title and notes can be modified.
46c8481

Highlights

  • Fix all logins failing with SCHEMA_MISMATCH on accounts.issuer (#283). Better Auth ≥ 1.7.3 validates the database schema at startup and rejects the accounts table because its issuer column was NOT NULL without a default — every sign-in/sign-up request then died with BetterAuthError: SCHEMA_MISMATCH (unexpected-required-column). This release makes the schema conform again:
    • accounts.issuer now has a DEFAULT '' (migration 0025_accounts_issuer_default rebuilds the table on existing databases and backfills empty issuers the same way 0024 did).
    • A boot-time schema check repairs legacy database shapes automatically on startup (including upgrades from ≤ v1.11.2).
    • An account.create after-hook backfills the issuer (local:credential for password accounts, local:oauth:<provider> otherwise) because Better Auth 1.7.4 silently drops unknown fields in its adapter — without this, newly created accounts would have an empty issuer and CPM's issuer-keyed queries (password change, account linking, identity lookup) would miss them.
    • If the data directory is not writable (the docker cp ownership trap from the issue), startup now fails with an explicit message naming uid 10001 and the chown 10001:10001 fix instead of a raw SQLITE_READONLY error.

Scope note: the released tags v1.10.0 – v1.11.2 pinned Better Auth 1.7.2 and were never affected; the bug shipped in Docker images built after the Better Auth 1.7.4 upgrade — i.e. the latest tag since 2026-09-15. This release moves latest to a fixed build.

Maintenance

  • e2e: plant the stale L4 apply lock as root (mirrors how a crashed apply leaves the files owned by the sidecar user on the shared volume) and raise the tcpSend read timeout to 10 s so emulated linux/amd64 echo backends don't flake under full-suite load.

Changes

  • 46c8481 test(e2e): plant stale L4 lock as root and tolerate slow emulated echo backends
  • 4af1bf6 fix(auth): give accounts.issuer a DB default and repair legacy shapes (#283)

Full Changelog: v1.11.2...v1.11.3

v1.11.2

Choose a tag to compare

@fuomag9 fuomag9 released this 09 Sep 16:54
Immutable release. Only release title and notes can be modified.
7e57917

Highlights

  • Expose DNS propagation delay/timeout settings with netcup defaults (#258): DNS-01 issuance could fail on slow-propagation providers (notably netcup) because Caddy's defaults (no delay, 2m timeout) expire before the TXT record becomes visible, even though the provider API works. Every DNS provider now has optional Propagation Delay / Propagation Timeout fields (new duration field type, validated as Go/Caddy duration syntax), emitted as Caddy challenges.dns.propagation_delay / propagation_timeout. Netcup ships sensible defaults (600s delay, 900s timeout, -1 disables the propagation check), overridable per provider.

Note: the v1.11.1 tag was never published as a GitHub release; this release supersedes it and includes its change.

Maintenance

  • Refresh Caddy compatibility pins (#271), bump google.golang.org/grpc in the Caddy image (#272) and the Go builder image (#265)
  • Verify Caddy pin refreshes by building the Dockerfile directly in CI (#270)
  • Dependency updates: vitest 5.0.0, next 16.3.4, zod 4.5.4, lucide-react 1.40.0, apexcharts 7.1.0, maplibre-gl 6.7.0, react-map-gl 8.1.3, postcss 8.5.28, plus dev-dependency group bumps
  • Correct the log-rotation documentation to reflect the real root cause of the 2026-09 disk-fill incident (logs directory permissions silently disabling timberjack cleanup — not Caddy defaults) and warn against write-only bind-mounted /logs directories

Changes

  • 7e57917 docs: correct log-rotation comment — perms, not Caddy defaults, filled the disk
  • 9f2f128 caddy: bump google.golang.org/grpc in /docker/caddy (#272)
  • f125793 caddy: refresh compatibility pins (#271)
  • 64a0398 ci: verify Caddy pin refresh by building Dockerfile directly (#270)
  • eeb810e deps(deps-dev): bump vitest from 4.1.11 to 5.0.0 (#269)
  • 3c95f67 deps(deps-dev): bump @vitest/ui from 4.1.11 to 5.0.0 (#268)
  • df24d53 deps(deps): bump the production-dependencies group with 7 updates (#267)
  • aa41b26 deps(deps-dev): bump the development-dependencies group with 5 updates (#266)
  • 7a36fe0 docker: bump golang from 4013ae0 to 512690a in /docker/caddy (#265)
  • f6ff473 Expose DNS propagation delay/timeout settings with netcup defaults (#258)

Full Changelog: v1.11.0...v1.11.2

v1.11.0

Choose a tag to compare

@fuomag9 fuomag9 released this 04 Sep 10:01
Immutable release. Only release title and notes can be modified.
04a75e7

Highlights

  • Add ClouDNS DNS provider for ACME DNS-01 challenges (#260)
  • Show the application version in the web GUI (#259): release Docker builds bake the git tag into the app, displayed in the sidebar logo block (desktop + mobile drawer) and under the login card. The same constant now feeds the OpenAPI spec version instead of the previously hardcoded 1.0.0.
  • Fix OAuth link/unlink not synchronizing users.provider and users.subject (#261): the Profile page could show an account as not linked even though OAuth sign-in worked, and kept claiming it was linked after unlinking. The identity columns are now re-derived from the authoritative accounts table on link/sign-in and after unlinking, the Profile page derives its connection state from accounts directly, and a one-time repair migration fixes existing deployments.
  • Fix WAF timestamps flipping between dots and slashes after refresh (#233): locale- and timezone-dependent rendering made the server (UTC) and the browser disagree after a full page reload. Formatting is now pinned to en-GB/UTC across the WAF events page (table, drawer, mobile cards), the audit log and the analytics blocked-events table, and WAF custom-range filters use UTC to match the displayed timestamps — headers and inputs are labelled "(UTC)".
  • Clarify secret decryption errors with component context (#263): error messages now name the stored value that failed to decrypt (DNS provider credential, OAuth provider secret, instance API token, certificate private key), explain the likely cause (the SESSION_SECRET changed) and how to recover.

Changes

  • 04a75e7 Clarify secret decryption errors with component context (#263)
  • 54816f3 Fix OAuth link/unlink not synchronizing users.provider and users.subject (#261)
  • 15449c0 Show application version in the web GUI (#259)
  • a52e537 caddy: bump google.golang.org/grpc in /docker/caddy (#262)
  • 18a1073 Fix timezone-dependent epoch expectations in WAF period filter test
  • 1f99a7f Add ClouDNS DNS provider for DNS-01 challenges (#260)
  • cd74731 Fix WAF timestamps flipping between dots and slashes after refresh (#233)

Full Changelog: v1.10.0...v1.11.0

v1.10.0

Choose a tag to compare

@fuomag9 fuomag9 released this 02 Sep 22:20
Immutable release. Only release title and notes can be modified.
14e223a

Highlights

  • Add a configurable default response for requests that don't match any proxy host (#241). Unknown Host headers and direct IP access were previously answered by Caddy's built-in behaviour; the response status and body are now configurable under Settings → Default Response and via the /api/v1/settings REST endpoint.
  • Add WAF request body limit settings (#252): SecRequestBodyLimit, SecRequestBodyInMemoryLimit and SecRequestBodyLimitAction are now exposed as global and per-host WAF settings, entered in MiB. Out-of-range values are refused at save time instead of failing the whole Caddy config load, and Caddy config errors now name known Coraza rejection causes.
  • Fix OAuth account linking (#247): the per-provider auto-link switch and OAUTH_ALLOW_AUTO_LINKING never reached Better Auth, so every link attempt returned account_not_linked. Linking now works from the profile page, which also explains why a given provider cannot be linked. Better Auth 1.7 account issuer identity is adopted and the OAuth callback URL is exposed via the API.
  • Harden API security boundaries.
  • Add netcup DNS provider for ACME DNS-01 challenges (#258).
  • Fix WAF events being dropped unless the request was actually blocked (#233).
  • Fix stale UI after saves on the L4 proxy hosts page and in the GeoIP settings (#241): rapid successive L4 host creates and enable toggles only appeared after a manual browser refresh, and the GeoIP form appeared to revert to pre-save values until reload.
  • Fix the analytics world map rendering as empty ocean for locally built Docker images: the staged maplibre worker could go stale across maplibre-gl upgrades because versions 6.4.1 and 6.6.0 ship worker files of identical size. Worker staging now compares file content, and Docker builds stage the worker from the container's own node_modules so a stale host copy can no longer leak into the image.

Changes

  • 1b0b7c3 Fix WAF events dropped unless the request was blocked (#233)
  • 28aa9e3 deps(deps-dev): bump the development-dependencies group with 5 updates (#235)
  • 0139b7c deps(deps): bump the production-dependencies group with 7 updates (#236)
  • 8f7936b deps(deps-dev): bump the development-dependencies group with 5 updates (#238)
  • 56aeb62 deps(deps-dev): bump @types/better-sqlite3 from 7.6.13 to 9.6.0 (#240)
  • 43814f8 deps(deps): bump the production-dependencies group across 1 directory with 6 updates (#239)
  • 74552e4 docker: bump golang from 1.26 to 1.27 in /docker/caddy (#244)
  • 41af21e deps(deps-dev): bump the development-dependencies group with 3 updates (#245)
  • 15a78b5 deps(deps): bump the production-dependencies group with 5 updates (#246)
  • 2467246 Add configurable default Caddy response (#241)
  • 3f40c74 Harden API security boundaries
  • cf78d20 Fix API hardening regressions
  • 049b965 Adopt Better Auth 1.7 account issuer identity
  • 0730df4 Wire OAuth account linking into Better Auth (#247)
  • 5b5ff0c ci(deps): bump actions/setup-go from 6 to 7 (#248)
  • ba954f3 deps(deps-dev): bump the development-dependencies group with 4 updates (#249)
  • 94107a0 deps(deps): bump the production-dependencies group with 3 updates (#250)
  • e35568a Add WAF request body limit settings
  • 230ca11 docker: bump golang from 0ecdc2a to 4013ae0 in /docker/caddy (#253)
  • 27ac577 deps(deps-dev): bump the development-dependencies group with 4 updates (#254)
  • 3db2e94 caddy: bump github.com/corazawaf/coraza-caddy/v2 (#255)
  • 1051be3 deps(deps): bump the production-dependencies group with 4 updates (#256)
  • cd00c05 deps(deps): bump apexcharts from 6.10.0 to 7.0.0 (#257)
  • a8f5a5f Expose OAuth callback URL in API and drop stale next-auth helper
  • 5956e59 Fix flaky certificate delete assertion with toHaveCount(0)
  • 61b7da2 caddy: make manifest module a buildable Go package for CodeQL and tidy
  • deccd59 Add netcup DNS provider for DNS-01 challenges (#258)
  • 402789b Fix stale UI after saves on L4 hosts page and GeoIP settings (#241)
  • 14e223a Fix stale maplibre worker staged into Docker builds

Full Changelog: v1.9.1...v1.10.0

v1.9.1

Choose a tag to compare

@fuomag9 fuomag9 released this 04 Aug 16:49
Immutable release. Only release title and notes can be modified.
8cb09d0

Highlights

  • Fix Authentik defaults not applied when editing a proxy host (#232) — EditHostDialog never passed authentikDefaults down to AuthentikFields, so enabling Authentik Forward Auth on an existing host left Outpost Domain, Outpost Upstream and Auth Endpoint blank and the save failed on the required fields. New hosts were unaffected.
  • Fix the analytics world map rendering as empty ocean and the analytics page crashing on API errors — maplibre-gl v6 resolves its tile worker via import.meta.url, which Turbopack can't resolve, so the worker never started. The worker is now staged into public/maplibre/ at build time. The analytics client also now checks response.ok before parsing, instead of throwing and unmounting the page on a 5xx.
  • Add Infomaniak DNS provider for ACME DNS-01 challenges (#223).
  • Document the OAuth self-registration setting in the README and docker-compose.yml.

Changes

  • 8cb09d0 Fix Authentik defaults not applied when editing a proxy host (#232)
  • bad34ec Update .gitignore
  • e77cbc3 Fix analytics world map and analytics page error handling
  • 37e03e1 deps(deps): bump the production-dependencies group with 2 updates (#230)
  • 31bc80e deps(deps-dev): bump the development-dependencies group with 3 updates (#229)
  • 252f1ef ci(deps): bump actions/stale from 10 to 11 (#228)
  • 99613e9 docs: expose OAuth self-registration setting
  • d4680dc deps: bump dependencies, keep typescript on 5.9
  • b1f6c63 deps(deps): bump the production-dependencies group with 21 updates (#225)
  • dbb100e deps(deps-dev): bump the development-dependencies group with 5 updates (#224)
  • 5bbeefe Delete docs directory
  • 64eaaf1 Add Infomaniak DNS provider

Full Changelog: v1.9...v1.9.1

v1.9

Choose a tag to compare

@fuomag9 fuomag9 released this 24 Jul 14:41
Immutable release. Only release title and notes can be modified.
8f44a50

Highlights

  • Add a global Trusted Proxies setting that writes server-level trusted_proxies / client_ip_headers / trusted_proxies_strict to the Caddy HTTP server (#222). When CPM runs behind another proxy (Pangolin/Newt, Cloudflare Tunnel, nginx/HAProxy), Caddy now resolves the real client IP instead of the immediate peer — fixing client-IP attribution in access logs, analytics, the country map, and any downstream handler. Accepts CIDRs and the private_ranges shorthand, supports custom client IP headers (e.g. Cf-Connecting-Ip), and can optionally default the geoblock trusted-proxy list from the same value. Configurable via Settings → Networking, the /api/v1/settings/trusted-proxies REST endpoint, and master→slave instance sync. Empty by default, preserving current behaviour on upgrade.

Changes

  • 8f44a50 Add server-level trusted_proxies / client_ip_headers setting

Full Changelog: v1.8.1...v1.9