Skip to main content
Homarr includes a comprehensive authentication system supporting multiple providers, role-based permissions, and group management. Control access to boards, integrations, and administrative features with fine-grained permissions.

Authentication Providers

Homarr supports multiple authentication methods to integrate with your existing infrastructure:

Credentials

Local username and password authentication with secure password hashing.

LDAP

Integrate with LDAP/Active Directory for centralized user management.

OIDC

OpenID Connect for single sign-on with providers like Keycloak, Authelia, and Auth0.

Guest Access

Optional anonymous access for public boards (configurable).

Provider Configuration

Homarr uses NextAuth.js with custom providers:
// From packages/auth/configuration.ts:50
providers: filterProviders([
  Credentials(createCredentialsConfiguration(db)),
  Credentials(createLdapConfiguration(db)),
  EmptyNextAuthProvider(), // Guest access
  OidcProvider(headers)
])

Credentials Provider

Local authentication with username and password:

Features

  • Secure password hashing with bcrypt
  • Password strength requirements
  • Account lockout after failed attempts
  • Password reset functionality
  • Remember me option

Configuration

Credentials provider is enabled by default. Configure in environment variables:
# Session configuration
AUTH_SESSION_EXPIRY_TIME=604800 # 7 days in seconds

# Secure cookies (enable for HTTPS)
AUTH_SECURE_COOKIES=true

Session Management

// From packages/auth/configuration.ts:72
const expires = expireDateAfter(env.AUTH_SESSION_EXPIRY_TIME);
const sessionToken = generateSessionToken();

await adapter.createSession({
  sessionToken,
  expires,
  userId: user.id
});

// Set secure cookie
cookies().set(sessionTokenCookieName, sessionToken, {
  path: "/",
  expires: expires,
  httpOnly: true,
  sameSite: "lax",
  secure: useSecureCookies
});

LDAP Authentication

Connect to LDAP or Active Directory servers:

Setup

  1. Configure LDAP connection in environment:
# LDAP server configuration
AUTH_LDAP_URI=ldap://ldap.example.com:389
AUTH_LDAP_BIND_DN=cn=admin,dc=example,dc=com
AUTH_LDAP_BIND_PASSWORD=password
AUTH_LDAP_BASE=dc=example,dc=com

# User search configuration
AUTH_LDAP_USER_SEARCH_BASE=ou=users,dc=example,dc=com
AUTH_LDAP_USER_SEARCH_FILTER=(uid={{username}})

# Group membership (optional)
AUTH_LDAP_GROUP_SEARCH_BASE=ou=groups,dc=example,dc=com
AUTH_LDAP_GROUP_SEARCH_FILTER=(member={{dn}})
  1. Enable LDAP in Homarr settings
  2. Test connection with a known user
  3. Map LDAP groups to Homarr groups (optional)

LDAP Implementation

// From packages/auth/providers/credentials/ldap-client.ts
class LdapClient {
  async authenticate(username: string, password: string) {
    // Bind to LDAP server
    const client = await this.connectAsync();
    
    // Search for user
    const user = await this.searchUserAsync(client, username);
    if (!user) return null;
    
    // Authenticate user
    await this.bindUserAsync(client, user.dn, password);
    
    // Get user groups
    const groups = await this.getUserGroupsAsync(client, user.dn);
    
    return { user, groups };
  }
}

LDAP Group Sync

Automatically sync LDAP groups to Homarr:
  • Map LDAP groups to Homarr groups
  • Inherit board permissions from groups
  • Sync on each login
  • Manual sync available in admin panel
LDAP users are created in Homarr on first login. Subsequent logins update user information and group membership.

OIDC Provider

Single sign-on with OpenID Connect:

Supported Providers

  • Keycloak: Open-source identity and access management
  • Authelia: Authentication and authorization server
  • Auth0: Cloud-based identity platform
  • Authentik: Open-source identity provider
  • Okta: Enterprise identity management
  • Azure AD: Microsoft identity platform
  • Google: Google OAuth 2.0
  • Any OIDC-compliant provider

Configuration

Configure OIDC in environment variables:
# OIDC provider configuration
AUTH_OIDC_CLIENT_ID=your-client-id
AUTH_OIDC_CLIENT_SECRET=your-client-secret
AUTH_OIDC_ISSUER=https://auth.example.com/realms/homarr

# Optional: Custom scopes
AUTH_OIDC_SCOPES=openid profile email groups

# Optional: Custom claim mapping
AUTH_OIDC_NAME_CLAIM=preferred_username
AUTH_OIDC_EMAIL_CLAIM=email
AUTH_OIDC_GROUPS_CLAIM=groups

OIDC Implementation

// From packages/auth/providers/oidc/oidc-provider.ts
export const OidcProvider = (headers) => ({
  id: "oidc",
  name: "OpenID Connect",
  type: "oidc",
  clientId: env.AUTH_OIDC_CLIENT_ID,
  clientSecret: env.AUTH_OIDC_CLIENT_SECRET,
  issuer: env.AUTH_OIDC_ISSUER,
  authorization: {
    params: {
      scope: env.AUTH_OIDC_SCOPES
    }
  },
  profile(profile) {
    return {
      id: profile.sub,
      name: profile[env.AUTH_OIDC_NAME_CLAIM],
      email: profile[env.AUTH_OIDC_EMAIL_CLAIM],
      groups: profile[env.AUTH_OIDC_GROUPS_CLAIM]
    };
  }
});

User Management

Creating Users

Create users through the web interface:
  1. Navigate to SettingsUsers
  2. Click Add User
  3. Enter user details:
    • Username
    • Email
    • Password (for credentials provider)
    • Groups (optional)
  4. Click Create
The user can now log in with their credentials.

User Properties

  • Username: Unique identifier for login
  • Email: For notifications and password reset
  • Display Name: Shown in UI
  • Avatar: Profile picture URL
  • Groups: Group membership for permissions
  • Permissions: Direct user permissions
  • Status: Active/Inactive

Groups and Permissions

Group Management

Organize users into groups for easier permission management:
  1. Navigate to SettingsGroups
  2. Click Add Group
  3. Enter group name and description
  4. Add users to the group
  5. Configure group permissions

Permission Levels

Homarr uses a hierarchical permission system:
Direct permissions assigned to individual users. Override group permissions when higher.Common user permissions:
  • admin: Full system access
  • board-create: Create new boards
  • board-view-all: View all boards
  • board-modify-all: Edit all boards
  • board-full-all: Full access to all boards
  • integration-create: Create integrations
  • integration-use-all: Use all integrations in widgets
  • integration-full-all: Manage all integrations
Permissions inherited by all group members. Useful for team-based access control.Example groups:
  • Admins: Full system access
  • Editors: Can create and modify boards
  • Viewers: Read-only access to public boards
  • Media Team: Access to media-related boards and integrations
  • Infrastructure Team: Access to monitoring boards
Specific to individual boards. See Board Permissions for details.Permission types:
  • View: Read-only access
  • Modify: Edit layout and widgets
  • Full: Complete control including permissions
Control which users can use specific integrations in widgets.Permission model:
  • Creator has full access
  • Users can be granted view or full access
  • Groups can inherit integration permissions
  • Widgets respect integration permissions when displaying data

Permission Implementation

// From packages/auth/permissions/board-permissions.ts:24
const constructBoardPermissions = (board, session) => {
  const isCreator = session?.user.id === board.creatorId;
  
  return {
    // Full access: creator OR explicit permission OR admin
    hasFullAccess:
      isCreator ||
      board.userPermissions.some(p => p.permission === "full") ||
      board.groupPermissions.some(p => p.permission === "full") ||
      session?.user.permissions.includes("board-full-all"),
      
    // Modify access: creator OR modify/full permission
    hasChangeAccess:
      isCreator ||
      board.userPermissions.some(p => 
        p.permission === "modify" || p.permission === "full"
      ) ||
      board.groupPermissions.some(p => 
        p.permission === "modify" || p.permission === "full"
      ) ||
      session?.user.permissions.includes("board-modify-all") ||
      session?.user.permissions.includes("board-full-all"),
      
    // View access: any permission OR public board
    hasViewAccess:
      isCreator ||
      board.userPermissions.length >= 1 ||
      board.groupPermissions.length >= 1 ||
      board.isPublic ||
      session?.user.permissions.includes("board-view-all")
  };
};

Session Management

Session Configuration

Sessions are stored in the database with configurable expiry:
// From packages/auth/configuration.ts:95
session: {
  strategy: "database",
  maxAge: env.AUTH_SESSION_EXPIRY_TIME, // Default: 7 days
  generateSessionToken
}

Session Security

  • HTTP-only cookies: Prevents XSS attacks
  • SameSite=Lax: CSRF protection
  • Secure flag: HTTPS only (in production)
  • Token rotation: New token on sign-in
  • Automatic cleanup: Expired sessions removed

Session Endpoints

  • /api/auth/signin: Sign in page
  • /api/auth/signout: Sign out endpoint
  • /api/auth/session: Get current session
  • /api/auth/callback/*: OAuth callbacks

API Key Authentication

For programmatic access to Homarr:

Creating API Keys

  1. Navigate to SettingsAPI Keys
  2. Click Create API Key
  3. Enter description and expiry date
  4. Select permissions
  5. Copy the generated key (shown only once)

Using API Keys

Include in requests as bearer token:
curl -H "Authorization: Bearer your-api-key" \
  https://homarr.example.com/api/boards

API Key Sessions

// From packages/auth/api-key/get-api-key-session.ts
export async function getApiKeySession(request: Request) {
  const authHeader = request.headers.get("Authorization");
  if (!authHeader?.startsWith("Bearer ")) return null;
  
  const apiKey = authHeader.substring(7);
  const hashedKey = hashApiKey(apiKey);
  
  // Look up API key in database
  const keyRecord = await db.apiKey.findUnique({
    where: { hashedKey },
    include: { user: true }
  });
  
  if (!keyRecord || keyRecord.expiresAt < new Date()) {
    return null;
  }
  
  return createSessionFromApiKey(keyRecord);
}
API keys have full access to the user’s permissions. Store them securely and rotate regularly.

Security Best Practices

Password Security

  • Enforce strong password requirements
  • Enable account lockout after failed attempts
  • Use password managers for users
  • Rotate passwords regularly
  • Never share credentials

Session Security

  • Use HTTPS in production
  • Enable secure cookies
  • Set appropriate session expiry
  • Sign out on shared devices
  • Monitor active sessions

Permission Management

  • Follow principle of least privilege
  • Use groups for team permissions
  • Review permissions regularly
  • Audit permission changes
  • Remove inactive users

Integration Security

  • Use separate service accounts
  • Limit integration permissions
  • Rotate integration secrets
  • Monitor integration usage
  • Remove unused integrations

Authentication Flow

Login Process

Authorization Flow

  1. Request: User accesses protected resource
  2. Session Check: Verify valid session exists
  3. Permission Check: Verify required permissions
  4. Resource Access: Grant or deny based on permissions
  5. Audit Log: Record access attempt

Event Logging

Authentication events are logged for audit purposes:
// From packages/auth/events.ts
export const createSignInEventHandler = (db) => async ({ user }) => {
  await db.auditLog.create({
    data: {
      userId: user.id,
      action: "sign_in",
      timestamp: new Date(),
      ipAddress: request.headers.get("x-forwarded-for"),
      userAgent: request.headers.get("user-agent")
    }
  });
};
Logged events:
  • Sign in/out
  • Failed login attempts
  • Password changes
  • Permission changes
  • API key usage
  • Session creation/expiry

Troubleshooting

Check:
  • Credentials are correct
  • Account is not locked
  • Provider is properly configured
  • Session cookies are enabled
  • HTTPS is used if secure cookies enabled
Solution:
  • Reset password if forgotten
  • Check server logs for errors
  • Verify provider configuration
  • Clear browser cookies and retry
Check:
  • LDAP URI is correct
  • Bind credentials are valid
  • Network connectivity to LDAP server
  • Firewall rules allow connection
  • Search base and filter are correct
Solution:
  • Test LDAP connection with ldapsearch
  • Verify bind DN has search permissions
  • Check LDAP server logs
  • Ensure TLS/SSL certificates are valid
Check:
  • Client ID and secret are correct
  • Redirect URI is registered with provider
  • Issuer URL is accessible
  • Scopes are supported by provider
  • System time is synchronized
Solution:
  • Verify provider configuration
  • Check provider logs
  • Test token endpoint manually
  • Ensure HTTPS is used
Check:
  • User has required permission
  • Group permissions are configured
  • Board/integration permissions are set
  • User is member of correct groups
  • Session is valid and not expired
Solution:
  • Review permission settings
  • Check group membership
  • Verify resource permissions
  • Sign out and back in to refresh permissions

Next Steps

Board Permissions

Learn about board-specific permissions

Integration Setup

Configure integrations with proper permissions

User Management

Manage users, groups, and permissions

Configuration

Configure authentication providers

Build docs developers (and LLMs) love