Skip to content

Authentication

Describes Hibernator chart 0.12.44

Users sign in to Hibernator with a one-time code that Hibernator sends by email. There are no passwords and no local account, so without a working mail server nobody can sign in. Passkeys are an option on top of the code (Passkeys).

  1. A user types an address on the login page.
  2. Hibernator compares the address with config.auth.allowedEmailDomains. It refuses an address outside those domains and sends no email.
  3. Hibernator sends an email with a code. When the request comes from the login page, the email also holds a link to config.externalUrl that signs the user in.
  4. The user types the code, or clicks the link.

The code has 6 characters: capital letters and digits, without I, O, 0 and 1. It is valid for 10 minutes. The third wrong code for an address cancels that code and its link, and the user must request a new code.

The API limits the requests:

  • 3 code requests for one address in 10 minutes.
  • 10 code requests from one client address in one minute.
  • 20 code checks from one client address in one minute.

The API sees the real client address only behind a proxy that frontend.trustedProxies names (Trusted proxies). The codes and the limits are in the memory of one API pod. With replicaCount.app above 1, a code works only on the pod that sent it (Passkeys).

Hibernator sends the codes, and the notification emails, through one mail server:

config:
smtp:
enabled: true
host: "smtp.example.com"
port: 587
from: "hibernator@example.com"
secrets:
smtp:
user: "hibernator"
password: "<your password>"

The chart puts secrets.smtp into the Secret hibernator-secrets, not into the ConfigMap. If secrets.existingSecret names your own Secret, Hibernator reads the user and the password from its keys smtp-user and smtp-password (install.md). The host, the port and the sender address always come from config.smtp.

Hibernator signs in to the mail server only when both user and password are set. The port decides the TLS:

Port TLS
465 TLS from the start of the connection
587 or 25 STARTTLS, which the server must offer
any other port, with user and password STARTTLS when the server offers it
any other port, without user and password no TLS

With config.smtp.enabled: false, the API refuses every code request with SMTP is disabled, and no notification email goes out. Troubleshooting tells what to check when no code arrives.

config.auth.allowedEmailDomains is the list of domains whose addresses can sign in. An empty list lets every address sign in.

  • Write each domain with or without @: example.com and @example.com are the same entry. Upper and lower case and spaces around a domain do not matter.
  • A domain matches only itself. example.com does not let mail.example.com in.
  • Hibernator compares the address with the list at each sign-in and each time it issues an access token. When you remove a domain, its users lose access within config.auth.tokenExpiry (Troubleshooting).

config.auth.adminUsers lists the addresses that get the admin role. Upper and lower case and spaces around an address do not matter. An admin must also pass allowedEmailDomains.

Admin-only screens and actions, such as Manual Control and the settings, need the admin role. With an empty list, nobody can administer the install, and the notes that helm install prints say so.

The admin role is part of the access token. A change to the list takes effect for a user when Hibernator next issues that user an access token.

A sign-in gives the user two tokens:

  • The access token is valid for config.auth.tokenExpiry (default 24h).
  • The refresh token is valid for config.auth.refreshExpiry (default 168h). The UI uses it to get a new access token. Hibernator does not renew it, so a user signs in again at least once in each refreshExpiry.

Both values are durations such as 30m or 12h. A value that Hibernator cannot read becomes the default, without an error.

secrets.jwtSecret signs both tokens, and it is required. Keep the value. A new value signs out every user. Hibernator keeps no session on the server.

config.auth.privacy replaces the addresses of chosen domains in logs, audit entries, events and the actor names on cards:

config:
auth:
privacy:
anonymizeLogsEnabled: true
domains:
- domain: "example.com"
exemptionPattern: "^ops-bot@example\\.com$"
replacement: "anonymized@example.com"
  • domains lists the domains to replace. With an empty list, Hibernator logs and stores every address unchanged, so list at least your own domain.
  • exemptionPattern is optional. It is a regular expression for the address in lower case, and an address that matches stays unchanged. If the expression is not valid, the API logs an error and leaves the addresses of that domain unchanged.
  • replacement is optional. Without it, the address becomes anonymized@<domain>.
  • anonymizeLogsEnabled: false turns the replacement off for all domains.

The passkey data keeps the address unchanged, because the address ties a passkey to a person (Passkeys).

The API reads the values on this page when it starts. When a helm upgrade changes one of them, the chart restarts the API pod, and the new pod reads the new values.

Apply your values file with helm upgrade.

Value Default What it does
config.smtp.enabled true Sends codes and notification emails. false refuses every code request
config.smtp.host "" The mail server
config.smtp.port 1025 The port of the mail server. It also decides the TLS
config.smtp.from "noreply@hibernator.local" The sender address of every email
secrets.smtp.user "" The user name for the mail server
secrets.smtp.password "" The password for the mail server
secrets.existingSecret "" Your own Secret. It replaces every secrets value: see install.md
config.auth.allowedEmailDomains [] The domains whose addresses can sign in, with or without @. Empty means every address
config.auth.adminUsers [] The addresses with the admin role
config.auth.tokenExpiry "24h" How long an access token is valid
config.auth.refreshExpiry "168h" How long a refresh token is valid
secrets.jwtSecret Signs the tokens. Required. A new value signs out every user
config.auth.webauthn.enabled, rpId, displayName false, "", "" Passkeys: see Passkeys
config.auth.privacy.anonymizeLogsEnabled true Turns the replacement of addresses on
config.auth.privacy.domains[] [] The domains whose addresses are replaced, each with domain, exemptionPattern and replacement