- Set Spanish as default language with ephemeral/encrypted privacy focus - Translate all user-facing strings and legal pages to Spanish - Replace Norwegian flag with Spanish flag in footer - Remove Hemmelig/terces.cloud links, add cloudhost.es sponsorship - Rewrite PrivacyPage: zero data collection, ephemeral design emphasis - Rewrite TermsPage: Spanish law, RGPD, paste.es/CloudHost.es references - Update PWA manifest, HTML meta tags, package.json branding - Rename webhook headers to X-Paste-Event / X-Paste-Signature - Update API docs title and contact to paste.es / cloudhost.es Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 KiB
Managed Mode
Run Hemmelig with all instance settings controlled via environment variables. Perfect for containerized deployments, GitOps workflows, and infrastructure-as-code setups where you want configuration locked down and version-controlled.
Overview
When managed mode is enabled, all instance settings are read from environment variables instead of the database. The admin dashboard becomes read-only, preventing any runtime modifications.
Key benefits:
- Immutable configuration - Settings can't be changed through the UI
- GitOps-friendly - Version control your configuration
- Reproducible deployments - Same config across all environments
- Security hardening - No accidental configuration changes
Quick Start
Enable managed mode by setting:
HEMMELIG_MANAGED=true
Then configure your settings via environment variables:
# Enable managed mode
HEMMELIG_MANAGED=true
# Instance branding
HEMMELIG_INSTANCE_NAME="Company Secrets"
HEMMELIG_INSTANCE_DESCRIPTION="Secure secret sharing for our team"
# Security
HEMMELIG_ALLOW_PASSWORD_PROTECTION=true
HEMMELIG_ALLOW_IP_RESTRICTION=true
HEMMELIG_ENABLE_RATE_LIMITING=true
# Organization
HEMMELIG_REQUIRE_REGISTERED_USER=true
HEMMELIG_ALLOWED_EMAIL_DOMAINS="company.com,partner.com"
Environment Variables
Core
| Variable | Description | Default |
|---|---|---|
HEMMELIG_MANAGED |
Enable managed mode | false |
General Settings
| Variable | Description | Default |
|---|---|---|
HEMMELIG_INSTANCE_NAME |
Display name for your instance | "" |
HEMMELIG_INSTANCE_DESCRIPTION |
Description shown on the homepage | "" |
HEMMELIG_INSTANCE_LOGO |
Base64-encoded logo image (max 512KB) | "" |
HEMMELIG_ALLOW_REGISTRATION |
Allow new user signups | true |
HEMMELIG_REQUIRE_EMAIL_VERIFICATION |
Require email verification | false |
HEMMELIG_DEFAULT_SECRET_EXPIRATION |
Default expiration in hours | 72 |
HEMMELIG_MAX_SECRET_SIZE |
Max secret size in KB | 1024 |
HEMMELIG_IMPORTANT_MESSAGE |
Alert banner shown to all users | "" |
Security Settings
| Variable | Description | Default |
|---|---|---|
HEMMELIG_ALLOW_PASSWORD_PROTECTION |
Allow password-protected secrets | true |
HEMMELIG_ALLOW_IP_RESTRICTION |
Allow IP range restrictions | true |
HEMMELIG_ALLOW_FILE_UPLOADS |
Allow users to attach files | true |
HEMMELIG_ENABLE_RATE_LIMITING |
Enable API rate limiting | true |
HEMMELIG_RATE_LIMIT_REQUESTS |
Max requests per window | 100 |
HEMMELIG_RATE_LIMIT_WINDOW |
Rate limit window in seconds | 60 |
Organization Settings
| Variable | Description | Default |
|---|---|---|
HEMMELIG_REQUIRE_INVITE_CODE |
Require invite code for registration | false |
HEMMELIG_ALLOWED_EMAIL_DOMAINS |
Comma-separated list of allowed domains | "" |
HEMMELIG_REQUIRE_REGISTERED_USER |
Only registered users can create and read secrets | false |
HEMMELIG_DISABLE_EMAIL_PASSWORD_SIGNUP |
Disable email/password registration (social only) | false |
Webhook Settings
| Variable | Description | Default |
|---|---|---|
HEMMELIG_WEBHOOK_ENABLED |
Enable webhook notifications | false |
HEMMELIG_WEBHOOK_URL |
Webhook endpoint URL | "" |
HEMMELIG_WEBHOOK_SECRET |
HMAC secret for webhook signatures | "" |
HEMMELIG_WEBHOOK_ON_VIEW |
Send webhook when secret is viewed | true |
HEMMELIG_WEBHOOK_ON_BURN |
Send webhook when secret is burned | true |
Metrics Settings
| Variable | Description | Default |
|---|---|---|
HEMMELIG_METRICS_ENABLED |
Enable Prometheus metrics endpoint | false |
HEMMELIG_METRICS_SECRET |
Bearer token for /api/metrics |
"" |
Docker Compose Example
services:
hemmelig:
image: hemmeligapp/hemmelig:v7
restart: unless-stopped
ports:
- '3000:3000'
volumes:
- ./database:/app/database
- ./uploads:/app/uploads
environment:
# Required
- DATABASE_URL=file:/app/database/hemmelig.db
- BETTER_AUTH_SECRET=your-secret-key-min-32-chars
- BETTER_AUTH_URL=https://secrets.example.com
- NODE_ENV=production
# Enable managed mode
- HEMMELIG_MANAGED=true
# General
- HEMMELIG_INSTANCE_NAME=ACME Secrets
- HEMMELIG_INSTANCE_DESCRIPTION=Internal secret sharing
- HEMMELIG_ALLOW_REGISTRATION=true
- HEMMELIG_DEFAULT_SECRET_EXPIRATION=24
- HEMMELIG_MAX_SECRET_SIZE=2048
# Security
- HEMMELIG_ALLOW_PASSWORD_PROTECTION=true
- HEMMELIG_ALLOW_IP_RESTRICTION=false
- HEMMELIG_ENABLE_RATE_LIMITING=true
- HEMMELIG_RATE_LIMIT_REQUESTS=50
- HEMMELIG_RATE_LIMIT_WINDOW=60
# Organization
- HEMMELIG_REQUIRE_REGISTERED_USER=true
- HEMMELIG_ALLOWED_EMAIL_DOMAINS=acme.com
# Metrics
- HEMMELIG_METRICS_ENABLED=true
- HEMMELIG_METRICS_SECRET=prometheus-scrape-token
Kubernetes Example
apiVersion: v1
kind: ConfigMap
metadata:
name: hemmelig-config
data:
HEMMELIG_MANAGED: 'true'
HEMMELIG_INSTANCE_NAME: 'ACME Secrets'
HEMMELIG_ALLOW_REGISTRATION: 'true'
HEMMELIG_REQUIRE_REGISTERED_USER: 'true'
HEMMELIG_ALLOWED_EMAIL_DOMAINS: 'acme.com'
HEMMELIG_ENABLE_RATE_LIMITING: 'true'
HEMMELIG_METRICS_ENABLED: 'true'
---
apiVersion: v1
kind: Secret
metadata:
name: hemmelig-secrets
type: Opaque
stringData:
BETTER_AUTH_SECRET: 'your-secret-key-min-32-chars'
HEMMELIG_WEBHOOK_SECRET: 'webhook-signing-secret'
HEMMELIG_METRICS_SECRET: 'prometheus-token'
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hemmelig
spec:
replicas: 1
selector:
matchLabels:
app: hemmelig
template:
metadata:
labels:
app: hemmelig
spec:
containers:
- name: hemmelig
image: hemmeligapp/hemmelig:v7
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: hemmelig-config
- secretRef:
name: hemmelig-secrets
env:
- name: DATABASE_URL
value: 'file:/app/database/hemmelig.db'
- name: BETTER_AUTH_URL
value: 'https://secrets.example.com'
- name: NODE_ENV
value: 'production'
Admin Dashboard Behavior
When managed mode is enabled:
- Settings are read-only - All form inputs are disabled
- Save buttons are hidden - No option to modify settings
- Banner is displayed - Admins see a clear "Managed Mode" indicator
- API rejects updates -
PUT /api/instance/settingsreturns403 Forbidden
Admins can still view all settings, making it easy to verify the configuration.
API Behavior
Check Managed Mode Status
curl https://secrets.example.com/api/instance/managed
Response:
{
"managed": true
}
Settings Update (Blocked)
When managed mode is enabled, attempting to update settings returns:
curl -X PUT https://secrets.example.com/api/instance/settings \
-H "Content-Type: application/json" \
-d '{"instanceName": "New Name"}'
Response:
{
"error": "Instance is in managed mode. Settings cannot be modified."
}
Migration Guide
From Database Settings to Managed Mode
-
Export current settings - Note your current configuration from the admin dashboard
-
Create environment configuration - Translate settings to environment variables
-
Enable managed mode - Set
HEMMELIG_MANAGED=true -
Deploy - Restart with new configuration
Your database settings will be ignored once managed mode is active. The database is still used for secrets, users, and other data - only instance settings come from environment variables.
Reverting to Database Settings
Simply remove or set HEMMELIG_MANAGED=false. Settings will be read from the database again, and the admin dashboard becomes editable.
Best Practices
-
Use secrets management - Store sensitive values like
HEMMELIG_WEBHOOK_SECRETandHEMMELIG_METRICS_SECRETin a secrets manager (Vault, AWS Secrets Manager, etc.) -
Version control your config - Keep your docker-compose or Kubernetes manifests in git
-
Use CI/CD for changes - Deploy configuration changes through your pipeline, not manual edits
-
Document your settings - Add comments in your configuration files explaining each setting
-
Test in staging first - Validate configuration changes in a non-production environment
Troubleshooting
Settings Not Applying
- Verify
HEMMELIG_MANAGED=trueis set (case-insensitive) - Check environment variables are being passed to the container
- Restart the application after changing environment variables
Dashboard Still Editable
- Clear your browser cache
- Verify the
/api/instance/managedendpoint returns{"managed": true} - Check server logs for configuration errors
Rate Limiting Not Working
- Ensure
HEMMELIG_ENABLE_RATE_LIMITING=true - Verify
HEMMELIG_RATE_LIMIT_REQUESTSandHEMMELIG_RATE_LIMIT_WINDOWare set - Rate limiting applies per IP address