All articles

Gatekeeper: a sign-in gate for websites behind nginx or Traefik

Published

Previews of new versions, reports, internal tools: many pages should not be public, yet they need no user management of their own. A shared password (HTTP Basic Auth) gets passed on and is never changed; a full identity platform is too much for a few pages.

For this we built Gatekeeper: a small service behind the reverse proxy that decides who may see which page.

How it works

On every request the reverse proxy asks the gatekeeper – nginx with auth_request, Traefik with forwardAuth. Without a session, the visitor sees the sign-in page right at the address they opened; after signing in, they land back there.

There are two ways in, chosen per host:

  • A one-time code by email: eight digits, valid for 15 minutes and only in the browser that asked for it.
  • Any OpenID Connect provider: Zitadel, Google, Microsoft, GitLab or another one.

Either way, one list of groups decides who may enter which host – it can hold single addresses or a whole domain.

Secure by design

  • Fail closed: an unknown host, a broken cookie or a provider error ends on the sign-in page, never in access.
  • No hints about addresses: an address without access gets the same answer in the same time as one with access – only the latter receives a mail.
  • Sessions are encrypted cookies bound to the host; codes are stored only as a hash.
  • Before the address field, an optional proof of work through our ALTCHA service keeps bots out.
  • If a code mail bounces, that address gets no further mail for 48 hours.
  • The sign-in pages need no scripts and carry a strict Content Security Policy; only the optional ALTCHA step loads its widget.

Lean in operation

Gatekeeper is a single static Go program: a 15 MB image that needs about 5 MiB of memory at rest. There is no database and no volume – sessions live in the cookie, pending codes in memory, users and groups in one JSON file. gatekeeper check tests a configuration before a restart. Sign-in pages and mails come in English, German, Russian and Georgian, with your own name, logo and colours or in a neutral look.

In nginx, a protected area needs three lines; the complete example is in the README:

location / {
    auth_request /_gatekeeper/auth;
    error_page 401 = /_gatekeeper/sign_in;
    error_page 403 = /_gatekeeper/denied;
}

In use

Gatekeeper protects the Lighthouse and SEO reports of our websites and the previews of new versions.

The source code is on GitLab and GitHub, the image on Docker Hub, under the MIT licence.

We will gladly set it up for your pages, too.

Ready for the next step?

There has never been a better time to start. Tell us about your project.

Get in touch