Skip to main content

Dynamic User Management

Dynamic Elasticsearch User Management automatically creates and manages ES users for ALL authenticated users (OIDC, Basic Auth, etc.). This provides accountability, auditing, and proper role-based access control without requiring pre-configured ES users.

Overview

Keyline's dynamic user management is the core innovation inherited from elastauth, significantly enhanced with additional security and flexibility.

Key Benefits

BenefitDescription
AccountabilityEach user has their own ES account
AuditingES audit logs show actual usernames
SecurityRandom, short-lived passwords
Role-based AccessUser groups map to ES roles
ScalabilityRedis cache enables multi-instance deployments

How It Works

Architecture

Component Overview

Components

ComponentPurpose
User ManagerOrchestrates user creation, role mapping, credential caching
Role MapperMaps user groups to Elasticsearch roles
Password GeneratorGenerates cryptographically secure random passwords
Credential EncryptorEncrypts passwords before caching (AES-256-GCM)
Cache BackendStores encrypted credentials with TTL

Configuration

Enable Dynamic User Management

user_management:
enabled: true
password_length: 32
credential_ttl: 1h

Required Configuration

OptionRequiredDefaultDescription
enabledYesfalseEnable dynamic user management
password_lengthNo32Generated password length (min 32)
credential_ttlNo1hPassword cache TTL (5m to 24h)

Elasticsearch Admin Credentials

elasticsearch:
admin_user: ${ES_ADMIN_USER}
admin_password: ${ES_ADMIN_PASSWORD}
url: https://elasticsearch:9200
timeout: 30s

Requirements for Admin User:

  • Must have manage_security privilege
  • Used exclusively for Security API calls
  • Validated on Keyline startup

Cache Configuration

cache:
backend: redis # or 'memory'
redis_url: redis://localhost:6379
credential_ttl: 1h
encryption_key: ${CACHE_ENCRYPTION_KEY} # 32 bytes required

Encryption Key Requirements:

  • Must be exactly 32 bytes (256 bits) for AES-256-GCM
  • Generate with: openssl rand -base64 32
  • Store in environment variable (not in config file)
  • All Keyline instances must use same key (for Redis)

User Upsert Flow

Step-by-Step Process

User Metadata Extraction

FieldSourceRequired
UsernameOIDC claim or local user configYes
GroupsOIDC groups claim or local user groupsNo
EmailOIDC email claim or local user emailNo
Full NameOIDC name claim or local user full_nameNo

ES User Creation

Keyline creates ES users with the following structure:

PUT /_security/user/{username}
{
"password": "random-32-char-password",
"roles": ["developer", "kibana_user"],
"full_name": "User Name",
"email": "user@example.com",
"metadata": {
"source": "oidc:google",
"last_auth": "2024-01-01T00:00:00Z",
"groups": ["developers", "users"]
}
}

Role Mapping

Configuration

role_mappings:
- claim: groups
pattern: "admin"
es_roles:
- superuser

- claim: groups
pattern: "*-developers"
es_roles:
- developer
- kibana_user

default_es_roles:
- viewer
- kibana_user

Evaluation Logic

Examples

User GroupsMappings MatchedES Roles Assigned
["admin"]adminsuperuser["superuser"]
["backend-developers", "users"]*-developersdeveloper, kibana_user["developer", "kibana_user"]
["unknown-group"]No matches, has defaults["viewer", "kibana_user"]
[] (no groups)No matches, has defaults["viewer", "kibana_user"]
[] (no groups, no defaults)No matches, no defaultsAccess Denied

Credential Caching

Cache Key Format

keyline:user:{username}:password

Cache Operations

OperationDescription
SetEncrypt password, store with TTL
GetRetrieve, decrypt, return
DeleteRemove from cache (on user update)

Cache Backends

BackendUse CaseProsCons
RedisProduction, multi-nodePersistent, scalable, sharedRequires Redis infrastructure
MemoryDevelopment, single-nodeSimple, no dependenciesLost on restart, no scaling

Performance Targets

MetricTarget
User upsert (cache miss)< 500ms (p95)
User upsert (cache hit)< 10ms (p95)
Cache hit rate> 95% for active users

Security Features

Password Security

FeatureImplementation
Generationcrypto/rand (cryptographically secure)
LengthMinimum 32 characters
ComplexityUppercase, lowercase, digits, special characters
LoggingNever logged or exposed

Encryption

FeatureImplementation
AlgorithmAES-256-GCM (authenticated encryption)
Key Size256 bits (32 bytes)
NonceRandom for each encryption
EncodingBase64 for cache storage

Admin Credentials

FeatureImplementation
StorageEnvironment variables only
UsageSecurity API calls only
ValidationChecked on startup
LoggingNever logged or exposed

Monitoring

Metrics

# User upserts
keyline_user_upserts_total{status="success|failure"}

# User upsert duration
keyline_user_upsert_duration_seconds{cache_status="hit|miss"}

# Cache operations
keyline_cred_cache_hits_total
keyline_cred_cache_misses_total

# Role mapping
keyline_role_mapping_matches_total{pattern="admin"}

# ES API calls
keyline_es_api_calls_total{operation="create_user", status="200"}

Logging

{
"level": "info",
"message": "ES user created",
"username": "user@example.com",
"roles": ["developer", "kibana_user"],
"source": "oidc:google",
"duration": "125ms",
"cache_status": "miss"
}

Next Steps