Forwarded Headers#

You may have a middleware that does authentication and then passes identity on to web applications in a header. If you do, then Grist can be configured to respect that header.

The redirection logic for authentication using forwarded headers currently assumes a single team site configuration, and may misbehave for multi-site configurations.

To make this work, here is what you’ll need to do:

  • Set GRIST_FORWARD_AUTH_HEADER to a header that will contain authorized user emails, say x-forwarded-user. This needs to match what your middleware will set.
  • Make sure the /auth/login path is handled by your middleware before reaching Grist.
  • Set GRIST_FORWARD_AUTH_LOGOUT_PATH to a path that will trigger a logout for your middleware (for example, /_oauth/logout). Make sure that the logout path is handled by your middleware!
  • If you want to allow anonymous access in some cases, make sure all other Grist paths are free of your middleware. Grist will trigger the middleware (by redirecting to /auth/login) as needed.
  • Your middleware may allow you to specify where to forward the user to after logging out. That should be /signed-out on the Grist site.

Example: traefik-forward-auth#

traefik-forward-auth is “A minimal forward authentication service that provides OAuth/SSO login and authentication for the traefik reverse proxy/load balancer.”

  • The GRIST_FORWARD_AUTH_HEADER should be X-Forwarded-User, and this should be set in the authResponseHeaders settings for traefik.

  • The GRIST_FORWARD_AUTH_LOGOUT_PATH should be /_oauth/logout, unless you have changed the default url-path setting for traefik-forward-auth.

  • LOGOUT_REDIRECT for traefik-forward-auth should be https://<grist-site>/signed-out.

There are worked examples at A template for self-hosting Grist with traefik and docker compose and Grist Omnibus.

Troubleshooting#

For many, this method of authentication works great. A user with multiple web apps served by the same middleware had difficulty coordinating logouts. That could be resolved by applying the middleware to all Grist paths and setting GRIST_IGNORE_SESSION=true so Grist has no separate notion of who is signed in. But then sharing some documents with everyone publically (without signing in) became a problem.

If on the contrary you want to be sure the user must be logged in before using Grist in any way, you can set GRIST_FORCE_LOGIN=true.