Goal of this guide

This guide shows step by step how to install, configure, test and harden grommunio-auth with Keycloak on a grommunio 2026.06.1 appliance. It gives you a reproducible practice path from package installation to validated web login with central sign-in.

  • You install `grommunio-auth` and `grommunio-keycloak` after the base installation.

  • You configure FQDN, database, grommunio user federation, realm and OIDC client.

  • You protect `/auth/admin`, `/auth/metrics` and `/auth/health` through explicit management networks.

  • You verify services, reverse proxy, OpenID discovery and grommunio Web login.

  • You recognise common pitfalls such as file permissions, theme assets and temporary admin users.

Start chronologically with the grommunio 2026.06.1 installation and then optionally continue with the current grommunio-antispam/Rspamd article.

Understand the architecture first

Before touching ports, files and commands, the login path must be clear. grommunio Web no longer handles the sign-in itself; it redirects to Keycloak through OpenID Connect. Keycloak authenticates the user in the `grommunio` realm and reads grommunio users through the grommunio user storage provider.

User
-> grommunio Web
-> OIDC redirect
-> Keycloak realm "grommunio"
-> grommunio user storage provider
-> grommunio user / mailbox
  • Realm: isolated Keycloak area for users, clients, flows and policies.

  • Client: application that uses Keycloak for sign-in; here grommunio Web.

  • Redirect URI: allowed return target after successful login.

  • User federation/user storage provider: connection from Keycloak to a user source.

  • Required action: action a user must complete during the next login, for example configuring OTP.

  • MFA: additional factor besides the password, usually a one-time code from an authenticator app.

What grommunio-auth does technically

grommunio-auth adds a central authentication layer to the collaboration platform. Keycloak provides the identity provider, grommunio integrates users through the grommunio user storage provider, and grommunio Web authenticates via OpenID Connect. This creates a clean path for SSO, MFA, external identity providers and controlled login policies.

  • Keycloak runs locally on port `9080` and is published through nginx under `/auth`.

  • The public web login uses the `grommunio` realm and the `grommunio` client.

  • The Keycloak admin console is under `/auth/admin` and should not be open to the internet.

  • grommunio Web reads `/etc/gromox/keycloak.json` and needs correct permissions for the web FPM process.

  • The grommunio user storage provider connects Keycloak to grommunio users.

Login flow without OAuth deep dive

  1. The user opens `https://mail.example.test/web/`.

  2. grommunio Web reads its Keycloak configuration from `/etc/gromox/keycloak.json`.

  3. grommunio Web redirects to the `grommunio` realm.

  4. Keycloak authenticates the user and runs required actions such as OTP if needed.

  5. Keycloak provides authorization code and tokens for the client through the standard flow.

  6. The browser returns to grommunio Web through the allowed redirect URI.

  7. grommunio Web creates its application session from that result.

Step 1: Check the starting point

Start only once the base appliance is healthy. Domain, users, webmail, admin interface, nginx, PHP-FPM and database must work. If you add auth to an unstable system, later troubleshooting starts in the wrong place.

bash
hostname -f
rpm -q grommunio-admin-api grommunio-web gromox grommunio-setup
systemctl is-active nginx php-fpm mariadb gromox-http gromox-zcore
curl -k -I https://mail.example.test/web/
curl -k -I https://mail.example.test:8443/

In the validated appliance, the hostname was `mail.example.test`, the base installation was grommunio 2026.06.1, and both web and admin interfaces were reachable before enabling auth.

Step 2: Install packages

Install `grommunio-auth` and `grommunio-keycloak` from the grommunio repositories. On the validated appliance, this added Keycloak, the grommunio provider and the Java runtime.

bash
zypper refresh
zypper install grommunio-auth grommunio-keycloak
rpm -q grommunio-auth grommunio-keycloak java-17-openjdk-headless
systemctl status grommunio-keycloak --no-pager

`grommunio-keycloak` is not fully configured immediately after package installation. That is expected: database, realm, client, provider and reverse proxy rules are created during setup.

Screenshot: The setup starts after package installation and announces the changes to Keycloak configuration and database.

Step 3: Start setup and make the key decisions

The appliance provides the wizard `/usr/share/grommunio-auth/setup-grommunio-auth.sh`. It asks for the essential values. In production, define and document these answers before you start.

bash
/usr/share/grommunio-auth/setup-grommunio-auth.sh
  1. Set the FQDN, for example `mail.example.test`.

  2. Create a local Keycloak database or connect an existing database.

  3. Configure grommunio database access for the user storage provider.

  4. Set and securely store the Keycloak admin password.

  5. Set allowed networks for protected auth paths, for example a management or VPN network.

  6. Finish setup and let services start.

Screenshot: In the wizard, you define FQDN and Keycloak database path; local database creation is the appliance default path.

Screenshot: The wizard connects Keycloak to grommunio users and limits administrative auth paths to allowed management networks.

For the validated appliance, `/auth/admin` was not opened globally; it was limited to the isolated VM management network and localhost. This is the important principle: expose user login paths as needed, but protect admin, metrics and health explicitly.

Path Purpose Exposure
/auth/realms/grommunio user login public if webmail is public
/auth/admin Keycloak admin management network, VPN, bastion or allowlist only
/auth/metrics operational metrics not public
/auth/health health checks not public

Step 4: Verify files and reverse proxy

After setup, three things must match: Keycloak configuration, the grommunio Web adapter and the nginx proxy. Verify them directly before opening the browser.

bash
sed -E 's/(db-password=).*/\1[REDACTED]/' /etc/grommunio-keycloak/keycloak.conf
sed -E 's/(password=).*/\1[REDACTED]/' /etc/grommunio-keycloak/grommunio.properties
jq '{realm, resource, "auth-server-url": ."auth-server-url"}' /etc/gromox/keycloak.json
cat /etc/grommunio-common/nginx/auth_allow.conf
nginx -T | grep -n -A8 'location /auth'

The validated installation used internal `http-port=9080`, `http-relative-path=/auth`, the `grommunio` realm, the `grommunio` client and reverse proxying through the web vhost. `/etc/grommunio-common/nginx/auth_allow.conf` contained only explicitly allowed networks.

Step 5: Check file permissions for grommunio Web

grommunio Web needs `/etc/gromox/keycloak.json` because it contains realm, auth server, client and secret. A common error is a valid file that the web process cannot read. grommunio Web then falls back to defaults and creates broken redirects such as `nullrealms/...`. On the validated appliance, the web FPM pool runs as `groweb`; that user must be able to read the file.

bash
grep -R '^user\|^group' -n /etc/php8/fpm/php-fpm.d/pool-grommunio-web.conf
namei -l /etc/gromox/keycloak.json
runuser -u groweb -- php -r 'define("GROMOX_CONFIG_PATH","/etc/gromox/"); $f=GROMOX_CONFIG_PATH."keycloak.json"; var_dump(file_exists($f), is_readable($f));'
chown root:groweb /etc/gromox/keycloak.json
chmod 640 /etc/gromox/keycloak.json
systemctl restart php-fpm nginx

Do not make the file world-readable unnecessarily because it contains an OIDC client secret. `root:groweb 0640` was the clean approach for the validated appliance.

Step 6: Validate services and OpenID discovery

If Keycloak starts during manual bootstrap but fails later under systemd, check `journalctl` first. In the validated appliance, a root-owned `/tmp/vertx-cache` blocked service startup as `groauth`; removing the temporary cache fixed it.

bash
systemctl is-active grommunio-keycloak nginx php-fpm mariadb
systemctl is-enabled grommunio-keycloak nginx mariadb
ss -ltnp | grep -E '(:9080|:443|:8443)\b'
curl -fsS http://localhost:9080/auth/realms/grommunio/.well-known/openid-configuration | jq -r '.issuer,.authorization_endpoint,.token_endpoint'
journalctl -u grommunio-keycloak --since '30 minutes ago' --no-pager

Screenshot: After setup completion, verify services and OpenID discovery before testing web login.

https://mail.example.test:8443/

Screenshot: grommunio Admin dashboard with active and enabled `grommunio-keycloak` service.

Step 7: Open the Keycloak admin console

Open the admin console only from the allowed management network. After the first login, Keycloak shows a warning about the temporary admin user. For production, create a permanent admin, verify roles and remove the temporary bootstrap user.

bash
# Management-Client oder VPN:
https://mail.example.test/auth/admin/
# Nach dem Login:
# permanenten Admin anlegen
# temporären Bootstrap-Admin entfernen
# MFA/Recovery-Prozess für Admins festlegen
https://mail.example.test/auth/admin/

Screenshot: Keycloak login under `/auth/admin` through the web vhost.

https://mail.example.test/auth/admin/master/console/

Screenshot: Keycloak console after login with a warning about the temporary admin user.

Step 8: Verify the grommunio realm

The `grommunio` realm is the functional SSO layer for grommunio sign-in. Verify realm, login theme, session behaviour, token lifetimes and later the connected identity providers.

bash
/opt/grommunio-keycloak/bin/kcadm.sh get realms/grommunio --fields realm,enabled,rememberMe,loginTheme | jq .
https://mail.example.test/auth/admin/master/console/#/grommunio

Screenshot: The configured grommunio realm in the Keycloak console.

Step 9: Verify the OIDC client

The `grommunio` client connects grommunio Web to Keycloak. Redirect URIs, web origins, client secret, standard flow, direct access grants and service accounts are especially important. Change these values only deliberately and retest login afterwards.

  • Redirect URIs must be limited tightly to the real grommunio Web return paths.

  • Web origins should also be restrictive; wildcards are convenient but risky.

  • Confidential clients use a secret; this secret is stored in the web configuration and must not be world-readable.

  • Standard flow is relevant for browser sign-in.

  • Direct access grants are needed only when a validated use case truly requires password grant.

  • Enable service accounts only for technical client-to-client scenarios, not pre-emptively.

bash
/opt/grommunio-keycloak/bin/kcadm.sh get clients -r grommunio -q clientId=grommunio \
| jq '.[0] | {clientId, redirectUris, webOrigins, publicClient, standardFlowEnabled, directAccessGrantsEnabled, serviceAccountsEnabled}'
https://mail.example.test/auth/admin/master/console/#/grommunio/clients

Screenshot: The OpenID Connect client `grommunio` with redirect and origin context.

Step 10: Verify user federation

The grommunio user storage provider lets Keycloak use grommunio users. Verify that the provider is enabled and that users appear in the realm. If profile fields are missing during first login, Keycloak completes them through a required action.

The distinction matters: in this article, the grommunio internal user source remains authoritative. User federation here means the grommunio user storage provider. An external user source such as LDAP, Active Directory or FreeIPA and an external identity provider through OIDC or SAML are separate architecture decisions and should be planned and tested separately.

bash
/opt/grommunio-keycloak/bin/kcadm.sh get components -r grommunio \
| jq '.[] | select(.providerId=="grommunio") | {name, providerId, providerType, config}'
https://mail.example.test/auth/admin/master/console/#/grommunio/user-federation

Screenshot: User federation with the grommunio provider as the connection to grommunio users.

Step 11: Plan authentication flows and MFA

Keycloak flows are where login policies, MFA and later identity provider integrations live. Do not enable MFA blindly for all users without a rollout plan. Define admin MFA, recovery process, helpdesk workflow, exceptions and a pilot group first.

  • Harden admin accounts first.

  • Define a pilot group for user MFA.

  • Document recovery codes or fallback procedures.

  • Plan monitoring for failed logins and lockouts.

  • Connect external IdPs such as upstream Keycloak, Entra ID, Okta or LDAP/AD only after the target architecture is clear.

https://mail.example.test/auth/admin/master/console/#/grommunio/authentication

Screenshot: Authentication flows are the basis for MFA and controlled login policies.

Step 12: Enable MFA for users

For users without an existing second factor, use the Keycloak required action `Configure OTP`. This makes the user set up an authenticator during the next login. Roll MFA out for admins and a pilot group first before enabling it as a default action for all users.

  • Pilot: set the required action only for selected users.

  • Broad rollout: enable `Configure OTP` as a default action so users without OTP are guided during their next login.

  • Recovery: define the process for lost devices, helpdesk verification and OTP reset before rollout.

  • Monitoring: review failed logins, lockouts and unusual MFA errors regularly.

In the browser, open the Keycloak admin console at `https://mail.example.test/auth/admin/`, switch to the `grommunio` realm and go to Authentication -> Required actions. Enable `Configure OTP` there and set it as default action if required. For repeatable changes, the CLI below is better because it is exact and auditable.

bash
/opt/grommunio-keycloak/bin/kcadm.sh config credentials \
--server http://localhost:9080/auth \
--realm master \
--user admin \
--password '[REDACTED]'
# Pilot: enforce MFA for one user during the next login.
USER_ID=$(/opt/grommunio-keycloak/bin/kcadm.sh get users -r grommunio \
-q username=alex@example.test --fields id --format csv --noquotes | head -1)
/opt/grommunio-keycloak/bin/kcadm.sh update users/$USER_ID -r grommunio \
-s 'requiredActions=["CONFIGURE_TOTP"]'
# Rollout: enable Configure OTP as a default action for users without OTP.
/opt/grommunio-keycloak/bin/kcadm.sh update authentication/required-actions/CONFIGURE_TOTP -r grommunio \
-s enabled=true \
-s defaultAction=true

On the next visit to `https://mail.example.test/web/`, the user first enters the password. Keycloak then shows OTP setup: open the authenticator app, add the QR code or setup key, enter the one-time code and confirm. On later logins, Keycloak asks for password and one-time code.

Important in practice: the QR code is not an admin configuration screen; it appears in the user login after the required action has been set. Test exactly this flow with a pilot user before rollout: open webmail, enter the password, scan the QR code, confirm OTP, sign out, sign in again and verify the one-time code prompt.

https://mail.example.test/web/

Screenshot: During the next login, Keycloak shows MFA setup with a scannable QR code.

If a user loses the device, remove the OTP credential and then set `CONFIGURE_TOTP` again. Check the credential ID deliberately first; do not blindly delete other sign-in methods.

bash
USER_ID=$(/opt/grommunio-keycloak/bin/kcadm.sh get users -r grommunio \
-q username=alex@example.test --fields id --format csv --noquotes | head -1)
/opt/grommunio-keycloak/bin/kcadm.sh get users/$USER_ID/credentials -r grommunio
# Delete only the affected user's real OTP credential.
/opt/grommunio-keycloak/bin/kcadm.sh delete users/$USER_ID/credentials/$CREDENTIAL_ID -r grommunio
/opt/grommunio-keycloak/bin/kcadm.sh update users/$USER_ID -r grommunio \
-s 'requiredActions=["CONFIGURE_TOTP"]'

Step 13: Test grommunio Web login

Open grommunio Web without the admin console. With the Keycloak adapter enabled, you should be redirected to the Keycloak login for the `grommunio` realm. Sign in with an existing grommunio user and verify that the session returns to grommunio Web.

bash
https://mail.example.test/web/
# Bei Fehlern:
journalctl -u php-fpm --since '30 minutes ago' --no-pager
journalctl -u grommunio-keycloak --since '30 minutes ago' --no-pager
tail -200 /var/log/nginx/error.log
https://mail.example.test/web/

Screenshot: grommunio Web redirects the user to Keycloak in the `grommunio` realm.

https://mail.example.test/web/

Screenshot: During first login, Keycloak can request missing profile fields through a required action.

Troubleshooting from the validated appliance

Three failure modes matter most because they are easy to misread in practice.

  • `/web/nullrealms/...`: grommunio Web could not read `/etc/gromox/keycloak.json` or the file is invalid.

  • `Unable to create folder at path /tmp/vertx-cache/...`: remove the temporary cache and then start Keycloak through systemd.

  • 404 on theme CSS: check login theme and theme resources; on the validated appliance, the stable Keycloak default theme fallback was clean.

bash
jq . /etc/gromox/keycloak.json >/dev/null
runuser -u groweb -- php -r 'define("GROMOX_CONFIG_PATH","/etc/gromox/"); $f=GROMOX_CONFIG_PATH."keycloak.json"; var_dump(is_readable($f));'
rm -rf /tmp/vertx-cache
systemctl restart grommunio-keycloak php-fpm nginx
curl -k https://mail.example.test/auth/realms/grommunio/.well-known/openid-configuration | jq -r '.issuer'

If Keycloak fails

If Keycloak fails, new SSO logins fail. Existing sessions may continue for a while or fail at the next token/session step depending on state, session lifetime and application context. Do not rely on assumptions; test failure and recovery in your own operating model.

  • Monitor `grommunio-keycloak`, nginx, php-fpm, MariaDB, OpenID discovery, health/metrics, login failures, token errors, lockouts, certificates and database availability.

  • Plan database and configuration backup, recovery procedures and restore tests.

  • Define a strongly protected break-glass path for recovery and test it regularly.

  • For larger environments, Keycloak HA should be planned as a separate architecture topic; this article does not claim an untested HA variant.

Backup, restore and lifecycle

Before changing authentication, back up more than packages. The important parts are database, realm/client configuration, secrets, reverse proxy rules and the files grommunio Web needs for OIDC.

  • Back up or deliberately review: Keycloak database, `/etc/grommunio-keycloak/`, `/etc/gromox/keycloak.json`, nginx auth allow configuration, relevant secrets and custom themes or configuration.

  • Run restore tests: service start, OpenID discovery, admin login, web login, MFA pilot, redirects and logs.

  • Apply updates only within the grommunio lifecycle: read release notes, create backup/snapshot, document realm/client/redirects, then retest services, discovery, web login, admin login and MFA.

Production hardening

  1. Expose `/auth/admin`, `/auth/metrics` and `/auth/health` only through management network, VPN, bastion or explicit IP allowlist.

  2. Replace the temporary admin user with permanent admin accounts protected by MFA.

  3. Include OIDC client secret, database passwords and Keycloak configuration files in backup and secret management.

  4. Verify TLS, FQDN, reverse proxy and HSTS before production login.

  5. Roll out MFA first for admins and a pilot group.

  6. Connect external identity providers only after defining attributes, groups and roles.

  7. Monitor Keycloak, grommunio-keycloak, grommunio-auth, nginx and PHP-FPM.

  8. Review login failures, lockouts, token errors and unusual session patterns.

  9. Test backup and restore of the Keycloak database and grommunio configuration.

  10. Version changes to flows, clients and redirect URIs and apply them with a rollback plan.

Order in the grommunio series

Chronologically, the series stays clear: first install grommunio 2026.06.1, then Day-2 topics such as grommunio-antispam and grommunio-auth. Product context is also available on the grommunio-auth product page.

Outlook

External identity providers, Keycloak HA, backup/DR architecture, monitoring expansion and modern authentication methods such as WebAuthn, passkeys or conditional flows belong in the next planning step. Implement them only when support, target architecture and operating path have been validated for the concrete grommunio environment.

Sources and validated basis

  • grommunio 2026.06.1 release notes: new appliance base, new admin interface and Keycloak component.

  • grommunio Technology: identity, access, OIDC, SAML, LDAP/AD, MFA and RBAC as platform functions.

  • grommunio Keycloak provider: user storage provider for grommunio users and Keycloak integration.

  • Keycloak documentation: OpenID Connect, realms, clients, authentication flows and server administration.

  • Validated appliance: grommunio 2026.06.1, `grommunio-auth 0.2.25`, `grommunio-keycloak 26.7.2`, web vhost under `/auth`, Keycloak internally on `9080`.

Licensing and evaluation

If you want to evaluate grommunio or need licences for a production environment, you can also contact ForgeOne. As a grommunio Gold Partner, we support you in selecting the right licensing model and can clarify test or evaluation options for planned environments together.

Introduce grommunio-auth in production

ForgeOne plans and operates grommunio as a sovereign collaboration platform including licensing, SSO, Keycloak, MFA, mail flow, migration, monitoring, backup and support. If you want to use grommunio as a native Exchange replacement with central sign-in, we can review architecture, identity integration and rollout with you.