feat: Betrieb hinter einem Anmelde-Proxy, Schlüssel für die App-Liste

Marc stellt Pangolin davor und will keinen zweiten Anmeldeschirm.

- HONEYOS_PROXY_AUTH=true: HoneyOS prüft nicht mehr selbst, der Start sagt
  deutlich, dass der Container dann nur über den Proxy erreichbar sein darf.
  Mit HONEYOS_USER_HEADER bekommt jeder Name seine eigenen Einstellungen.
- HONEYOS_APPS_KEY schützt /api/apps. Nötig, weil HoneyOS auf einer anderen
  Site liegt als die Apps (duckdns.org steht auf der Public-Suffix-Liste) –
  der Browser schickt die Sitzung dort nicht mit, und der Pfad muss im Proxy
  von der Anmeldung befreit sein.

Beim Durchspielen mit zwei echten Hostnamen fiel ein Loch auf: Ohne eigene
Anmeldung gilt jede Anfrage als angemeldet, also gab der Rückfall auf diese
Prüfung die Liste an jeden heraus – auch ohne oder mit falschem Schlüssel.
Der Rückfall greift jetzt nur noch, wo es wirklich eine Sitzung geben kann.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-08-24 22:09:37 +02:00
1 parent 905b136516
commit 1c3218939b
8 files changed
+382 -45

No files matched your search

+58 -18
View File
@@ -29,33 +29,73 @@ und die Einstellungen je Nutzer. Sichere sie zusammen mit der `.env` — ohne
außer dass `X-Forwarded-Proto: https` durchkommt — sonst setzt HoneyOS das Sitzungscookie
ohne `Secure`.
## Anmeldung
## Anmeldung — zwei Wege, einer davon reicht
In PocketID einen Client anlegen und dort als Rückrufadresse **exakt** eintragen:
```
https://os.honeyy.duckdns.org/api/auth/callback
```
HoneyOS schickt PKCE mit, braucht aber trotzdem ein Client-Geheimnis — also **keinen
„public client"** anlegen. Danach in die `.env`:
**A · Ein Proxy davor macht die Tür** (Pangolin, Authelia, …). Dann in der `.env`:
```dotenv
HONEYOS_PUBLIC_URL=https://os.honeyy.duckdns.org
HONEYOS_SESSION_SECRET=… # openssl rand -hex 32
HONEYOS_OIDC_ISSUER=https://id.honeyy.duckdns.org
HONEYOS_PROXY_AUTH=true
# HONEYOS_USER_HEADER=Remote-User # optional, trennt die Einstellungen je Nutzer
```
HoneyOS fragt dann nicht noch einmal — kein zweiter Anmeldeschirm. **Der
Container darf in diesem Betrieb nur über den Proxy erreichbar sein**, denn er
prüft selbst nichts mehr.
**B · HoneyOS meldet selbst an**, mit eigenem Anmeldeschirm über deinen
OIDC-Anbieter. In PocketID einen Client anlegen und als Rückrufadresse **exakt**
`<PUBLIC_URL>/api/auth/callback` eintragen. HoneyOS schickt PKCE mit, braucht
aber trotzdem ein Client-Geheimnis — also **keinen „public client"**.
```dotenv
HONEYOS_SESSION_SECRET=… # openssl rand -hex 32
HONEYOS_OIDC_ISSUER=https://id.example.com
HONEYOS_OIDC_CLIENT_ID=honeyos
HONEYOS_OIDC_CLIENT_SECRET=…
HONEYOS_BUTTON_LABEL=Anmelden mit PocketID
# HONEYOS_ALLOWED_USERS=marc # zweiter Riegel neben den PocketID-Gruppen
```
Wer nicht angemeldet ist, sieht **nur** den Anmeldeschirm — keine App-Liste, keine Namen.
Die Sitzung ist ein signiertes Cookie ohne Gegenstück auf dem Server: ein Neustart wirft
niemanden hinaus, und es gibt nichts aufzuräumen. Sie hält 30 Tage.
Wer nicht angemeldet ist, sieht nur den Anmeldeschirm — keine App-Liste, keine
Namen. Die Sitzung ist ein signiertes Cookie ohne Gegenstück im Server: ein
Neustart wirft niemanden hinaus. Sie hält 30 Tage.
**Ohne `HONEYOS_OIDC_ISSUER` läuft HoneyOS ganz ohne Anmeldung.** Das ist zum Entwickeln
gedacht und sagt beim Start deutlich, dass es so nicht ins offene Netz gehört.
**Weder A noch B** heißt: offen für jeden. Sagt beim Start deutlich, dass das
nur zum Entwickeln taugt.
## Wenn HoneyOS auf einer anderen Site liegt als die Apps
Der Browser behandelt `honeyos.duckdns.org` und `cloud.honeyy.duckdns.org` als
**fremde Sites** — `duckdns.org` steht auf der Public-Suffix-Liste, die
gemeinsame Endung zählt also nicht. Folge: Bei der Anfrage aus einer App heraus
schickt der Browser die HoneyOS-Sitzung **nicht** mit.
Damit die Leiste trotzdem eine App-Liste bekommt:
```dotenv
HONEYOS_APPS_KEY=… # openssl rand -hex 16
```
und derselbe Wert im Skript-Tag der App:
```html
<script defer src="https://honeyos.duckdns.org/honeybar/honeybar.js"
data-app="aether" data-key="…"></script>
```
Der Schlüssel steht damit in der App, die ohnehin nur Berechtigte sehen. Ohne
ihn antwortet `/api/apps` mit 401 — auch im Proxy-Betrieb, gerade weil dieser
Pfad im Proxy von der Anmeldung befreit sein muss.
Zweite Schranke, unabhängig davon: HoneyOS gibt die Liste nur an Ursprünge
heraus, die **selbst als App eingetragen** sind. Eine fremde Seite scheitert
also an CORS, selbst mit richtigem Schlüssel.
**Was auf zwei Sites nicht geht:** der Anmeldestand auf den Kacheln des
Schreibtischs (fragt über die Domaingrenze). Der Name *in der Leiste* geht
weiterhin — den holt sie bei der App selbst, gleicher Ursprung.
Liegen alle Adressen unter derselben Domain (`os.honeyy…`, `cloud.honeyy…`),
entfällt der Schlüssel und alles funktioniert ohne Einschränkung.
## Apps anlegen