Skip to main content
This document describes the global key-value store system with group-based organization for managing application-wide configuration and credentials in DeployStack.

Overview

The global settings system provides secure storage for application-wide configuration values organized into logical groups for better management and frontend display:
  • SMTP Mail Settings: Host, port, username, password for email functionality
  • GitHub OAuth Configuration: GitHub OAuth client ID and secret for authentication
  • API Keys: External service credentials (OpenAI, AWS, etc.)
  • System Configuration: Application-wide settings and feature flags
  • Integration Credentials: Third-party service authentication tokens
  • Environment Variables: Dynamic configuration that can be changed without code deployment

Group-Based Organization

The system now uses groups to organize settings into logical categories that can be displayed as tabs in the frontend:
  • Group ID: Technical identifier used for API queries (e.g., smtp)
  • Group Name: Human-readable display name (e.g., SMTP Mail Settings)
  • Group Metadata: Description, icon, and sort order for frontend display

Auto-Initialization System

The system includes an auto-initialization feature that automatically creates missing groups and global settings when the server starts. Settings are defined in modular files within the src/global-settings/ directory, and the system will:
  • Scan for setting definition files on startup
  • Create missing groups with metadata
  • Check which settings exist in the database
  • Create missing settings with default values (non-destructive)
  • Link settings to their appropriate groups
  • Preserve existing settings and their values
  • Log initialization results for transparency

Key Features

  • Group-Based Organization: Settings organized into logical groups for frontend tabs
  • Hierarchical Keys: Dot notation organization (e.g., smtp.host, api.openai.key)
  • Encryption Support: Automatic encryption for sensitive values using AES-256-GCM
  • Group Metadata: Display names, descriptions, icons, and sort order for groups
  • Admin-Only Access: Only global_admin users can manage settings
  • Audit Trail: Track setting changes with timestamps
  • Search Functionality: Find settings by key patterns
  • Bulk Operations: Create/update multiple settings at once
  • Health Monitoring: Built-in encryption system health checks

Security

Encryption

Sensitive values are encrypted using industry-standard AES-256-GCM encryption:
  • Algorithm: AES-256-GCM (Galois/Counter Mode)
  • Key Derivation: Scrypt with fixed salt from DEPLOYSTACK_ENCRYPTION_SECRET environment variable
  • Authenticated Encryption: Prevents tampering with encrypted data
  • Unique IVs: Each encryption operation uses a unique initialization vector
  • Additional Authenticated Data: Extra security layer to prevent manipulation

Access Control

  • Role-Based Access: Only users with global_admin role can access settings
  • Permission-Based: Granular permissions for view, edit, and delete operations
  • Session Validation: All requests require valid authentication

Environment Variables

The system requires the DEPLOYSTACK_ENCRYPTION_SECRET environment variable:
Important: Use a strong, unique secret in production. This key is used to derive the encryption key for all sensitive settings.

Security Guidelines

Follow these guidelines when working with sensitive settings:
  • Always encrypt sensitive data: Passwords, API keys, tokens, and secrets must be encrypted
  • Use descriptive descriptions: Help administrators understand what each setting does and why it’s sensitive
  • Group sensitive settings: Keep all sensitive settings for a service in the same group for easier management
  • Regular audits: Review settings periodically for unused or outdated values
  • Environment separation: Use different encryption secrets for different environments (development, staging, production)

Database Schema

Naming Conventions

When creating global settings, follow these conventions for consistency:
  • Dot notation for hierarchy: Use category.subcategory.setting structure (e.g., smtp.host, api.openai.key)
  • Lowercase with underscores: Use lowercase letters with underscores for readability (e.g., smtp.max_retry_count)
  • Be descriptive but concise: Use clear names without redundancy (e.g., api.openai.key not api.openai.api_key)
  • Group related settings: Keep related configuration together (e.g., database.host, database.port, database.name)
  • Hierarchical keys within groups: Use dot notation for subcategories (e.g., group.subcategory.setting)
  • Keep all related settings in the same group: Maintain group consistency for better organization
  • Provide clear descriptions: Help administrators understand the purpose of each setting

API Endpoints

Authentication

All endpoints require authentication and appropriate permissions:
  • View Settings: Requires settings.view permission
  • Create/Update Settings: Requires settings.edit permission
  • Delete Settings: Requires settings.delete permission

Group Management

Get All Groups with Settings

Response:

Get Specific Group

Create Group

Update Group

Settings Management

List All Settings

Get Settings by Group

Example:

Get Specific Setting

Create New Setting

Update Existing Setting

Delete Setting

Search Settings

Bulk Create/Update Settings

Health Check

The GlobalSettings helper class provides simple, type-safe methods for retrieving setting values. These helpers are designed for common use cases where you just need the value of a setting, similar to the Email service helper methods.

Import the Helper Class

Basic Usage

Get Setting Values

Type-Safe Getters

Advanced Data Types

Batch Operations

Get Multiple Settings

Utility Methods

Check Setting Status

Error Handling

Real-World Examples

SMTP Configuration

Feature Flags

API Configuration

System Configuration

Usage Examples (GlobalSettingsService)

For more complex operations like creating, updating, or searching settings, use the GlobalSettingsService directly:

SMTP Configuration

API Keys Management

Error Handling

When working with global settings, implement proper error handling:

Auto-Initialization System

Overview

The auto-initialization system automatically creates missing groups and global settings when the server starts. This ensures that all required groups and settings are available without manual configuration, while preserving existing values.

File-Based Setting Definitions

Settings are defined in TypeScript files within the src/global-settings/ directory:

Setting Definition Format

Each setting file exports a GlobalSettingsModule with group metadata:

Setting Properties

Each setting in the settings array requires these properties:

Startup Behavior

When the server starts:
  1. Discovery: Scans src/global-settings/ for .ts files
  2. Loading: Dynamically imports each settings module
  3. Validation: Ensures each module has the correct structure
  4. Group Creation: Creates missing groups with metadata
  5. Database Check: Checks which settings exist in the database
  6. Creation: Creates missing settings with default values and group links
  7. Preservation: Skips existing settings (non-destructive)
  8. Logging: Reports initialization results

Example Startup Output

Built-in Setting Groups

SMTP Settings (Group ID: smtp)

Source: services/backend/src/global-settings/smtp.ts Email server configuration for sending notifications and system emails. Includes SMTP host, port, authentication credentials (encrypted password), SSL/TLS settings, and default sender information.

GitHub OAuth Settings (Group ID: github-oauth)

Source: services/backend/src/global-settings/github-oauth.ts GitHub OAuth application credentials for user authentication. Includes client ID, client secret (encrypted), enabled flag, callback URL, and requested OAuth scopes.

Global Settings (Group ID: global)

Source: services/backend/src/global-settings/global.ts Application-wide configuration settings. Controls frontend URL, email functionality toggle, login/registration enablement, and API documentation visibility.

User Display Settings (Group ID: user-display)

Source: services/backend/src/global-settings/user-display.ts Controls UI element visibility for users across the application. Manages header buttons like Discord community link and feedback form. Special behavior: These settings are automatically included in the /api/users/me endpoint response, making them immediately available to the frontend without additional API calls.

Helper Methods

The system provides helper methods for retrieving complete configurations:

Adding New Setting Groups (Core)

To add a new core setting group (managed directly by the application):
  1. Create Setting File: Add a new .ts file in src/global-settings/
  1. Restart Server: The new group and settings will be automatically discovered and initialized
  2. Add Helper Method (optional): Add a helper method to GlobalSettingsInitService

Frontend Integration

The group-based system is designed for easy frontend integration:

Dynamic Tab Creation

Group Management

System Configuration

Group Design Guidelines

When designing setting groups for your application, follow these guidelines:
  • Logical grouping: Group related settings together (e.g., all SMTP settings in one group)
  • Clear names: Use descriptive group names that are clear for frontend display
  • Consistent icons: Use consistent iconography across groups for better UX
  • Proper ordering: Set sort_order values to control tab display sequence in the frontend

Performance Considerations

In-Memory Cache

The global settings system uses an in-memory cache to eliminate database queries for read operations. This is critical for high-frequency endpoints like health checks (/) and Swagger documentation (/documentation).

How It Works

Cache Lifecycle

  1. Startup: After global settings initialization, all settings are loaded into memory
  2. Reads: All GlobalSettings.get*() calls read from memory (no database query)
  3. Writes: When settings are modified via GlobalSettingsService, the cache is automatically invalidated and reloaded
  4. Fallback: If cache is not initialized, reads fall back to database queries

When Cache Is Invalidated

The cache automatically reloads from the database after:
  • GlobalSettingsService.set() - Create or update a setting
  • GlobalSettingsService.setTyped() - Create or update with type
  • GlobalSettingsService.update() - Update an existing setting
  • GlobalSettingsService.delete() - Delete a setting

Manual Cache Refresh

If you modify settings outside of GlobalSettingsService (not recommended), refresh the cache manually:

Single-Instance Limitation

The current cache implementation is designed for single-instance deployments. Multi-instance support (horizontal scaling) with shared cache synchronization is planned for a future release.

Monitoring Cache Status

Additional Performance Tips

  • Batch operations: Use bulk endpoints when creating multiple related settings
  • Group retrieval: Use getGroupValues() to fetch all settings in a group at once

Migration and Setup

Initial Setup

  1. Environment Variable: Set DEPLOYSTACK_ENCRYPTION_SECRET in your environment
  2. Database Migration: Run npm run db:generate and restart the server
  3. Admin Access: Ensure you have a user with global_admin role

Migrating from Category-Based System

The new group-based system replaces the old category-based approach. The migration is handled automatically:
  1. Database Migration: The category column is renamed to group_id
  2. Auto-Initialization: Groups are created automatically from setting definitions
  3. Setting Linking: Existing settings are linked to appropriate groups

Plugin-Contributed Global Settings

In addition to core global settings, plugins can also define and register their own global settings and setting groups. These are managed through the same system and are subject to the same access controls (i.e., editable by global_admin). Key points for plugin-contributed settings:
  • Declaration: Plugins declare global settings via a globalSettingsExtension property in their main class.
  • Initialization: The PluginManager processes these definitions at startup, creating new groups and settings if they don’t already exist.
  • Precedence: Core global settings always take precedence. If a plugin tries to define a setting with a key that already exists (either from core or another plugin), the plugin’s definition for that specific key is ignored.
  • Documentation: For details on how plugins can define global settings, refer to the Backend Plugins Docs document.

Helper Methods API Reference

GlobalSettings Class Methods

Boolean Value Parsing

The getBoolean() method accepts these string values:

Usage Patterns

Simple Value Retrieval

Type-Safe Retrieval

Batch Retrieval

Validation and Checks

REST API Reference Summary


For more information about the role-based access control system, see ROLES. For security details, see SECURITY.