configs.hermes-proxy: log in to assist.lassul.us via id.lassul.us
assist.lassul.us now sits behind oauth2-proxy on neoprism (provider
oidc, issuer https://id.lassul.us), wired in with nginx auth_request on
that vhost only. The nixpkgs nginx helper (oauth2-proxy.nginx) is not
used because it turns on services.nginx.recommendedProxySettings for
every vhost on the host; the same few locations are written out here.
Unauthenticated requests are redirected (307) to /oauth2/start with a
relative rd, which oauth2-proxy accepts without a whitelist-domain;
the provider button is skipped so it goes straight to Zitadel.
Access: the Zitadel project "assist" is declarative with a grant for
lass@lassul.us only, and its projectRoleCheck blocks everyone else at
the IdP. oauth2-proxy additionally allows only that address
(authenticated-emails-file, no email domains); its OIDC provider rejects
emails whose email_verified is false. The session user is the `sub`
claim. The client id/secret come from zitadel-reconcile's env file
(/var/lib/zitadel-apps/assist-web.env, OAUTH2_PROXY_CLIENT_ID/SECRET),
used as the unit's EnvironmentFile; the cookie secret from a new
neoprism vars generator (oauth2-proxy/cookie-secret, via LoadCredential).
Public without login, as Chrome fetches them without cookies to install
the page and verify the TWA: /.well-known/assetlinks.json,
/manifest.webmanifest, /icon-192.png, /icon-512.png.
After the login, nginx sets Authorization: Bearer <access token> towards
hermes-voice, from an include in /run written at boot by a root oneshot
(hermes-voice-auth-header, owned by nginx, mode 0600), so the token
never enters the store. For that the hermes-voice generator is now a
shared var (configs/hermes-voice-vars.nix, imported by coaxmetal and
neoprism); a shared generator gets a new value, so the token is rotated.
hermes-voice keeps checking the token, which still guards its retiolum
port; the gateway plugin keeps calling /approve on localhost with
API_SERVER_KEY.
The page no longer asks for or stores the token. Its fetches use
redirect: "manual", so an expired login (redirect to id.lassul.us,
which fetch cannot follow cross-origin) shows up as an opaqueredirect
and the page reloads into the login.
configs.hermes-proxy: log in to assist.lassul.us via id.lassul.us
assist.lassul.us now sits behind oauth2-proxy on neoprism (provider
oidc, issuer https://id.lassul.us), wired in with nginx auth_request on
that vhost only. The nixpkgs nginx helper (oauth2-proxy.nginx) is not
used because it turns on services.nginx.recommendedProxySettings for
every vhost on the host; the same few locations are written out here.
Unauthenticated requests are redirected (307) to /oauth2/start with a
relative rd, which oauth2-proxy accepts without a whitelist-domain;
the provider button is skipped so it goes straight to Zitadel.
Access: the Zitadel project "assist" is declarative with a grant for
lass@lassul.us only, and its projectRoleCheck blocks everyone else at
the IdP. oauth2-proxy additionally allows only that address
(authenticated-emails-file, no email domains); its OIDC provider rejects
emails whose email_verified is false. The session user is the `sub`
claim. The client id/secret come from zitadel-reconcile's env file
(/var/lib/zitadel-apps/assist-web.env, OAUTH2_PROXY_CLIENT_ID/SECRET),
used as the unit's EnvironmentFile; the cookie secret from a new
neoprism vars generator (oauth2-proxy/cookie-secret, via LoadCredential).
Public without login, as Chrome fetches them without cookies to install
the page and verify the TWA: /.well-known/assetlinks.json,
/manifest.webmanifest, /icon-192.png, /icon-512.png.
After the login, nginx sets Authorization: Bearer <access token> towards
hermes-voice, from an include in /run written at boot by a root oneshot
(hermes-voice-auth-header, owned by nginx, mode 0600), so the token
never enters the store. For that the hermes-voice generator is now a
shared var (configs/hermes-voice-vars.nix, imported by coaxmetal and
neoprism); a shared generator gets a new value, so the token is rotated.
hermes-voice keeps checking the token, which still guards its retiolum
port; the gateway plugin keeps calling /approve on localhost with
API_SERVER_KEY.
The page no longer asks for or stores the token. Its fetches use
redirect: "manual", so an expired login (redirect to id.lassul.us,
which fetch cannot follow cross-origin) shows up as an opaqueredirect
and the page reloads into the login.
configs.hermes-proxy: log in to assist.lassul.us via id.lassul.us
assist.lassul.us now sits behind oauth2-proxy on neoprism (provider
oidc, issuer https://id.lassul.us), wired in with nginx auth_request on
that vhost only. The nixpkgs nginx helper (oauth2-proxy.nginx) is not
used because it turns on services.nginx.recommendedProxySettings for
every vhost on the host; the same few locations are written out here.
Unauthenticated requests are redirected (307) to /oauth2/start with a
relative rd, which oauth2-proxy accepts without a whitelist-domain;
the provider button is skipped so it goes straight to Zitadel.
Access: the Zitadel project "assist" is declarative with a grant for
lass@lassul.us only, and its projectRoleCheck blocks everyone else at
the IdP. oauth2-proxy additionally allows only that address
(authenticated-emails-file, no email domains); its OIDC provider rejects
emails whose email_verified is false. The session user is the `sub`
claim. The client id/secret come from zitadel-reconcile's env file
(/var/lib/zitadel-apps/assist-web.env, OAUTH2_PROXY_CLIENT_ID/SECRET),
used as the unit's EnvironmentFile; the cookie secret from a new
neoprism vars generator (oauth2-proxy/cookie-secret, via LoadCredential).
Public without login, as Chrome fetches them without cookies to install
the page and verify the TWA: /.well-known/assetlinks.json,
/manifest.webmanifest, /icon-192.png, /icon-512.png.
After the login, nginx sets Authorization: Bearer <access token> towards
hermes-voice, from an include in /run written at boot by a root oneshot
(hermes-voice-auth-header, owned by nginx, mode 0600), so the token
never enters the store. For that the hermes-voice generator is now a
shared var (configs/hermes-voice-vars.nix, imported by coaxmetal and
neoprism); a shared generator gets a new value, so the token is rotated.
hermes-voice keeps checking the token, which still guards its retiolum
port; the gateway plugin keeps calling /approve on localhost with
API_SERVER_KEY.
The page no longer asks for or stores the token. Its fetches use
redirect: "manual", so an expired login (redirect to id.lassul.us,
which fetch cannot follow cross-origin) shows up as an opaqueredirect
and the page reloads into the login.