fix(web-app-semaphore): serve the onion sibling relative assets

With SEMAPHORE_WEB_ROOT set, Semaphore rewrites index.html's
<base href="/"> to the full clearnet web root, so the onion page loaded
its JS and CSS from https://semaphore.<domain>/ and the onion CSP
blocked them (hlth-csp failed, semaphore#1). Unsetting the web root is
not an option: it also decides the session cookie's Secure flag.

Every served vhost other than the web root's host now gets a sub_filter
that turns that tag back into <base href="/">, passed to sys-stk-full as
webserver_location_extra_configuration. SEMAPHORE_WEB_ROOT is defined
once and read by the env file, the OIDC redirect_url and the rewrite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-10-25 19:45:25 +01:00
1 parent 00d8b4a50b
commit bcb6c9f105
3 files changed
+6 -2

No files matched your search

@@ -6,6 +6,7 @@
name: sys-stk-full
vars:
compose_handlers_flush: true
webserver_location_extra_configuration: "{{ '' if domain == (SEMAPHORE_WEB_ROOT | urlsplit('hostname')) else SEMAPHORE_SIBLING_BASE_REWRITE }}"
- name: "🧑‍💼 Run the Semaphore account operations on the stack host"
when: IS_STACK_HOST | bool
+1 -1
View File
@@ -1,7 +1,7 @@
{% include 'roles/sys-svc-container/templates/env.j2' %}
SEMAPHORE_PORT=:{{ container_port }}
SEMAPHORE_WEB_ROOT={{ lookup('tls', application_id, 'url.base') | regex_replace('/+$', '') }}
SEMAPHORE_WEB_ROOT={{ SEMAPHORE_WEB_ROOT }}
SEMAPHORE_DB_DIALECT=postgres
SEMAPHORE_DB_HOST={{ lookup('database', application_id, 'host') }}
+4 -1
View File
@@ -3,6 +3,9 @@ application_id: "web-app-semaphore"
container_port: "{{ lookup('config', application_id, 'services.semaphore.ports.internal.http') }}"
SEMAPHORE_NAME: "{{ lookup('config', application_id, 'services.semaphore.name') }}"
SEMAPHORE_WEB_ROOT: "{{ lookup('tls', application_id, 'url.base') | regex_replace('/+$', '') }}"
SEMAPHORE_SIBLING_BASE_REWRITE: >-
sub_filter '<base href="{{ SEMAPHORE_WEB_ROOT }}/">' '<base href="/">';
SEMAPHORE_OIDC_ENABLED: "{{ lookup('config', application_id, 'services.sso.enabled') }}"
SEMAPHORE_LDAP_ENABLED: "{{ lookup('config', application_id, 'services.ldap.enabled') }}"
@@ -27,7 +30,7 @@ SEMAPHORE_OIDC_PROVIDERS_JSON: >-
"provider_url": OIDC.CLIENT.ISSUER_URL,
"client_id": OIDC.CLIENT.ID,
"client_secret": OIDC.CLIENT.SECRET,
"redirect_url": (lookup('tls', application_id, 'url.base') | regex_replace('/+$', '')) ~ "/api/auth/oidc/keycloak/redirect",
"redirect_url": SEMAPHORE_WEB_ROOT ~ "/api/auth/oidc/keycloak/redirect",
"username_claim": OIDC.ATTRIBUTES.USERNAME,
"email_claim": "email",
"name_claim": "name",