Authentication
LogTide supports multiple authentication methods including local email/password, OpenID Connect (OIDC) for SSO, and LDAP for enterprise directory integration.
Overview
- PKCE flow for OIDC (protection against authorization code interception)
- Secure password hashing with bcrypt for local accounts
- Rate limiting on authentication endpoints
- Automatic account linking when email matches
Admin Setup
Authentication providers are configured by administrators in the Admin Panel. Navigate to Admin > Auth Providers to manage providers.
Local Provider Enabled by Default
The local email/password provider is automatically available. Add OIDC or LDAP providers to enable SSO.
OpenID Connect (OIDC)
OIDC enables Single Sign-On (SSO) with identity providers like Authentik, Keycloak, Okta, Auth0, Google, and Azure AD.
Configuration Fields
| Field | Description | Example |
|---|---|---|
| Issuer URL | OIDC discovery endpoint (without /.well-known/openid-configuration) | https://auth.example.com/application/o/logtide/ |
| Client ID | Application client ID from your identity provider | logtide-client-id |
| Client Secret | Application client secret (for confidential clients) | your-secret-here |
| Redirect URI | Callback URL (optional, auto-generated if empty) | https://logtide.example.com/api/v1/auth/providers/my-oidc/callback |
| Scopes | OAuth scopes to request | openid, email, profile |
| Email Claim | JWT claim containing user email | |
| Name Claim | JWT claim containing user display name | name |
Example: Authentik Setup
Configure LogTide as an OAuth2/OIDC application in Authentik:
- In Authentik, go to Applications > Applications and create a new application
- Create an OAuth2/OIDC Provider with these settings:
- Client type: Confidential
- Client ID: (auto-generated or custom)
- Client Secret: (auto-generated)
- Redirect URIs:
https://your-logtide.com/api/v1/auth/providers/authentik/callback
- Note the OpenID Configuration Issuer URL from the provider overview
- In LogTide Admin, add a new OIDC provider with these values
{
"issuerUrl": "https://auth.example.com/application/o/logtide/",
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"redirectUri": "https://logtide.example.com/api/v1/auth/providers/authentik/callback",
"scopes": ["openid", "email", "profile"]
} Example: Keycloak Setup
- In Keycloak Admin Console, create a new client in your realm
- Set Client type: to "OpenID Connect"
- Set Client authentication to "On" (confidential client)
- Add Valid redirect URI:
https://your-logtide.com/api/v1/auth/providers/keycloak/callback - Copy Client ID and Client Secret from the Credentials tab
{
"issuerUrl": "https://keycloak.example.com/realms/your-realm",
"clientId": "logtide",
"clientSecret": "your-client-secret"
}
The redirect URI configured in your identity provider must exactly match what LogTide uses.
The format is: https://your-logtide-domain/api/v1/auth/providers/{slug}/callback
If you're using a reverse proxy, ensure the backend API is accessible at /api/.
LDAP / Active Directory
LDAP integration allows users to authenticate with their enterprise directory credentials (Active Directory, OpenLDAP, FreeIPA, etc.).
Configuration Fields
| Field | Description | Example |
|---|---|---|
| Server URL | LDAP server address (ldap:// or ldaps://) | ldap://ldap.example.com:389 |
| Bind DN | Service account DN for searching users | cn=admin,dc=example,dc=com |
| Bind Password | Service account password | your-bind-password |
| Search Base | Base DN for user searches | ou=users,dc=example,dc=com |
| Search Filter | LDAP filter to find users (use {{username}} placeholder) | (uid={{username}}) |
| Email Attribute | LDAP attribute containing user email | |
| Name Attribute | LDAP attribute containing user display name | cn |
Example: OpenLDAP Setup
{
"serverUrl": "ldap://ldap.example.com:389",
"bindDn": "cn=admin,dc=example,dc=com",
"bindPassword": "admin-password",
"searchBase": "ou=users,dc=example,dc=com",
"searchFilter": "(uid={{username}})",
"emailAttribute": "mail",
"nameAttribute": "cn"
} Example: Active Directory Setup
{
"serverUrl": "ldaps://ad.example.com:636",
"bindDn": "CN=Service Account,OU=Service Accounts,DC=example,DC=com",
"bindPassword": "service-account-password",
"searchBase": "OU=Users,DC=example,DC=com",
"searchFilter": "(sAMAccountName={{username}})",
"emailAttribute": "mail",
"nameAttribute": "displayName"
}
For Active Directory, use sAMAccountName for username-based login
or userPrincipalName for email-based login.
Always use ldaps:// (LDAP over SSL/TLS on port 636) in production
to encrypt credentials in transit. Plain ldap:// transmits passwords in cleartext.
User Authentication Flow
New Users
When a user authenticates via OIDC or LDAP for the first time:
- A new LogTide account is automatically created using their email and name from the identity provider
- The external identity is linked to the new account
- User is redirected to the onboarding flow to create or join an organization
Existing Users
When an existing user authenticates:
- Same email: If a local account exists with the same email, the external identity is automatically linked
- Already linked: If the identity is already linked, user is logged in directly
Multiple Providers
Users can have multiple identities linked to one account. For example, a user could:
- Sign up with email/password (local)
- Later link their Okta account for SSO convenience
- Also link their LDAP credentials for on-premise access
Environment Variables
| Variable | Description | Default |
|---|---|---|
| FRONTEND_URL | Frontend URL for OIDC redirects | http://localhost:3000 (dev) |
| AUTH_RATE_LIMIT_LOGIN | Max login attempts per window | 20 |
| AUTH_RATE_LIMIT_WINDOW | Rate limit window in milliseconds | 900000 (15 min) |
For production deployments with OIDC, set FRONTEND_URL to your actual frontend domain
(e.g., https://logtide.example.com). This ensures users are redirected correctly after SSO authentication.
Auth-Free Mode
For single-user deployments, LogTide supports an auth-free mode that bypasses authentication entirely. This is ideal for personal setups where you're the only user and don't need login protection.
Auth-free mode disables all authentication. Only use this for private, single-user deployments where the LogTide instance is not exposed to the internet. Anyone with network access to your LogTide instance will have full admin access.
How It Works
When auth-free mode is enabled:
- All API requests bypass token validation
- The frontend automatically uses the configured default user
- No login page is shown — users go directly to the dashboard
- The default user must be an admin with at least one organization
Setting Up Auth-Free Mode
- First, create a local admin account through normal signup
- Create at least one organization for the admin user
- Go to Admin > Settings
- Set Authentication Mode to "Auth-Free (No Login Required)"
- Select the admin user as the Default User
- Save changes
After saving, you'll be automatically logged in as the default user. On subsequent visits, no login will be required.
Requirements
Disabling Auth-Free Mode
To re-enable authentication, go to Admin > Settings and set Authentication Mode back to "Standard (Login Required)". Users will then need to log in with their credentials.
Initial Admin Setup
For automated deployments (Docker, Kubernetes, etc.), you can create an initial admin user using environment variables. This allows you to deploy LogTide without needing to manually create the first account.
Environment Variables
| Variable | Description | Required |
|---|---|---|
| INITIAL_ADMIN_EMAIL | Email address for the admin account | Yes |
| INITIAL_ADMIN_PASSWORD | Password (minimum 8 characters) | Yes |
| INITIAL_ADMIN_NAME | Display name (defaults to "Admin") | No |
Docker Compose Example
services:
backend:
image: logtide/backend:latest
environment:
# Initial admin (only creates user if no users exist)
INITIAL_ADMIN_EMAIL: [email protected]
INITIAL_ADMIN_PASSWORD: your-secure-password
INITIAL_ADMIN_NAME: Administrator
# ... other environment variables The initial admin is only created if no users with login credentials exist. After the first user is created, these environment variables are ignored. This is safe to leave in your deployment configuration.
Auto-Generated Credentials
If you don't configure INITIAL_ADMIN_* environment variables, LogTide will
automatically create a [email protected] admin account with a randomly
generated password. The credentials are printed to the console on first startup:
╔════════════════════════════════════════════════════════════════╗
║ INITIAL ADMIN CREDENTIALS (save these!) ║
╠════════════════════════════════════════════════════════════════╣
║ Email: [email protected] ║
║ Password: xY7k2mN9pQ4rS1tU... ║
╠════════════════════════════════════════════════════════════════╣
║ Change your password after first login! ║
║ Or set INITIAL_ADMIN_* env vars for future deployments. ║
╚════════════════════════════════════════════════════════════════╝
Check your Docker logs or terminal output for these credentials. We recommend changing the
password after first login or using the INITIAL_ADMIN_* environment variables
for production deployments.
Admin Settings
Administrators can configure authentication behavior from Admin > Settings.
| Setting | Description | Options |
|---|---|---|
| Authentication Mode | Controls whether users need to log in |
|
| Signups Enabled | Allow new user registration |
|
| Default User | User to use in auth-free mode | Select from admin users only |
Disabling Signups
To prevent new user registrations (useful for private instances):
- Go to Admin > Settings
- Toggle Signups Enabled to off
- Save changes
When signups are disabled, the signup link is hidden from the login page. Users can only be created by administrators or through external identity providers (OIDC/LDAP).
User Management
Administrators can manage users from Admin > Users.
Admin Role Management
From the user details page, administrators can promote or demote users:
- Promote to Admin: Gives the user full admin access including system settings, user management, and access to all organizations
- Remove Admin Role: Revokes admin privileges. The user retains their organization memberships and data access
You cannot remove the admin role from yourself. This prevents accidentally locking yourself out of admin access. Another admin must demote you if needed.
Other User Actions
Troubleshooting
OIDC Errors
- Verify Client ID and Client Secret are correct
- Check that the client is configured as "Confidential" in your IdP
- Some providers require POST-based client authentication (LogTide uses this by default)
- The redirect URI in LogTide must exactly match what's configured in your IdP
- Check for trailing slashes, http vs https, and port numbers
- Format:
https://{domain}/api/v1/auth/providers/{slug}/callback
- The Issuer URL must match exactly what the IdP returns in discovery
- Check for trailing slashes - some providers require them, others don't
- Visit
{issuerUrl}/.well-known/openid-configurationto see the expected issuer
Auth-Free Mode Issues
- Ensure the default user is configured in Admin Settings
- Verify the default user has at least one organization
- Clear browser cache and cookies, then refresh
- Go to Admin > Settings and select a default user
- The default user must be an admin with at least one organization
- If no users are available, switch back to standard mode and create an admin user first
- Verify auth-free mode is properly enabled in the database
- Restart the backend service to clear any cached settings
- Check that the Redis cache has been updated (settings use a 5-minute cache TTL)
LDAP Errors
- Verify the Bind DN and Bind Password are correct
- Test the bind credentials directly with
ldapsearch - Check if the service account has permission to search the user base
- Verify the Search Base DN is correct
- Check the Search Filter - use
(uid={{username}})for OpenLDAP or(sAMAccountName={{username}})for AD - Ensure the user exists in the specified search base
- Check firewall rules between LogTide and the LDAP server
- Verify the server URL and port (389 for LDAP, 636 for LDAPS)
- For LDAPS, ensure the server certificate is valid
Development Testing
For local development and testing, you can run identity providers using Docker.
Test with Authentik (OIDC)
Create a docker-compose.authentik.yml file:
# Authentik for testing OIDC integration
# Run: docker compose -f docker-compose.authentik.yml up -d
# Access: http://localhost:9000 (admin setup on first visit)
services:
postgresql-authentik:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- authentik-db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: authentik-password
POSTGRES_USER: authentik
POSTGRES_DB: authentik
redis-authentik:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- authentik-redis:/data
authentik-server:
image: ghcr.io/goauthentik/server:2024.2.2
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis-authentik
AUTHENTIK_POSTGRESQL__HOST: postgresql-authentik
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: authentik-password
AUTHENTIK_SECRET_KEY: test-secret-key-change-in-production
volumes:
- authentik-media:/media
- authentik-templates:/templates
ports:
- "9000:9000"
- "9443:9443"
depends_on:
- postgresql-authentik
- redis-authentik
authentik-worker:
image: ghcr.io/goauthentik/server:2024.2.2
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis-authentik
AUTHENTIK_POSTGRESQL__HOST: postgresql-authentik
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: authentik-password
AUTHENTIK_SECRET_KEY: test-secret-key-change-in-production
volumes:
- authentik-media:/media
- authentik-templates:/templates
depends_on:
- postgresql-authentik
- redis-authentik
volumes:
authentik-db:
authentik-redis:
authentik-media:
authentik-templates:
After starting, visit http://localhost:9000 to set up the admin account,
then create an OAuth2/OIDC application for LogTide.
Test with OpenLDAP
Create a docker-compose.ldap.yml file:
# OpenLDAP for testing LDAP integration
# Run: docker compose -f docker-compose.ldap.yml up -d
# Admin UI: http://localhost:8090
services:
openldap:
image: osixia/openldap:1.5.0
container_name: logtide-openldap
environment:
LDAP_ORGANISATION: "Example Inc"
LDAP_DOMAIN: "example.org"
LDAP_ADMIN_PASSWORD: "adminpassword"
LDAP_CONFIG_PASSWORD: "configpassword"
LDAP_READONLY_USER: "true"
LDAP_READONLY_USER_USERNAME: "readonly"
LDAP_READONLY_USER_PASSWORD: "readonlypassword"
ports:
- "389:389"
- "636:636"
volumes:
- ldap-data:/var/lib/ldap
- ldap-config:/etc/ldap/slapd.d
phpldapadmin:
image: osixia/phpldapadmin:0.9.0
container_name: logtide-phpldapadmin
environment:
PHPLDAPADMIN_LDAP_HOSTS: openldap
PHPLDAPADMIN_HTTPS: "false"
ports:
- "8090:80"
depends_on:
- openldap
volumes:
ldap-data:
ldap-config: Create LDAP Test User
Create a test-user.ldif file and apply it to create a test user:
# test-user.ldif
dn: ou=users,dc=example,dc=org
objectClass: organizationalUnit
ou: users
dn: cn=testuser,ou=users,dc=example,dc=org
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: testuser
sn: User
givenName: Test
uid: testuser
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/testuser
mail: [email protected]
userPassword: testpassword Apply with:
# Copy file to container
docker cp test-user.ldif logtide-openldap:/tmp/test-user.ldif
# Apply LDIF
docker exec logtide-openldap ldapadd -x -D "cn=admin,dc=example,dc=org" -w adminpassword -f /tmp/test-user.ldif
Test credentials: testuser / testpassword
For the OpenLDAP test setup, use these values in LogTide:
- Server URL:
ldap://localhost:389 - Bind DN:
cn=admin,dc=example,dc=org - Bind Password:
adminpassword - Search Base:
ou=users,dc=example,dc=org - Search Filter:
(uid={{username}})