dotCMS / dotCMS/core

Provide app secrets via environment variables / Kubernetes secrets (DOT_{APP_KEY}_{HOSTNAME}_{APP_VALUE_KEY})

Open
#35,859 3 comments 0 reactions 0 assignees View on GitHub

A pull request for this has already been merged.

  • #35860 by @wezell — merged
stale Team : Platform
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Parent

User Story / Enhancement

Problem

dotCMS app secrets (the Apps framework, com.dotcms.security.apps) can today only be fully configured through the UI / stored secrets store. There is an existing env-var hook (AppsUtil.guessEnvVarAPP_{APP_KEY}_PARAM_{APP_VALUE_KEY}), but it:

  • is not host-aware (one var overrides a param for every site),
  • only enriches an existing stored blob — it cannot provision an app on a host that has no stored config,
  • has override semantics that aren't expressed as a clear precedence model.

This blocks headless / IaC / Kubernetes deployments where secrets should be injected at the platform level.

Proposal

Add per-host environment-variable / Kubernetes-secret provisioning for all apps using the pattern:

DOT_{APP_KEY}_{HOSTNAME}_{APP_VALUE_KEY}

plus a global System Host form DOT_{APP_KEY}_SYSTEM_HOST_{APP_VALUE_KEY}.

Resolution is per-param, specificity-first (highest → lowest):

  1. host-specific env — DOT_{APP_KEY}_{HOSTNAME}_{APP_VALUE_KEY} (locks the UI field)
  2. host-specific stored / UI value
  3. System Host env — DOT_{APP_KEY}_SYSTEM_HOST_{APP_VALUE_KEY}
  4. legacy global env — APP_{APP_KEY}_PARAM_{APP_VALUE_KEY} (deprecated, throttled warning)
  5. System Host stored value
Behavior
  • Full provisioning: an app with no stored blob is usable purely from env vars (partial provisioning returns only env-backed params).
  • Normalization: env var names use Config.envKey() only (uppercase, dots/dashes → underscores, DOT_ prefix) — no parallel normalization; construct-and-lookup from AppDescriptor.getParams() (never parses arbitrary env vars). A registered descriptor is required.
  • Editability: only tier-1 (host-specific env) locks the field read-only; global tiers stay editable so a deliberate per-host stored value still wins.
  • fromEnv: exposed on the Java Secret object and the REST SecretView (boolean; no tier enum).
  • Listing/presence: listAppKeys, appKeysByHost, filterSitesForAppKey report env-only apps as configured (lazy detection; System Host/legacy tiers mirror the stored System Host cascade).
  • fallbackOnSystemHost=false suppresses both System Host tiers (3 and 5).
  • Masking follows the descriptor param type regardless of source; env values are returned raw (no coercion).
Out of scope

Live/hot secret rotation without restart (env vars are process-static), file-mounted-secret watching, type coercion, startup index, tier-enum REST field.

Backward-compatibility note

The legacy APP_..._PARAM_... pattern keeps working as tier-4 (with a deprecation warning), but precedence becomes specificity-first: a host-specific stored value now wins over the legacy global env var (previously legacy env overrode stored). Existing integration tests asserting the old override semantics will need to be updated.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with AppsUtil.guessEnvVar and the app resolution paths, then inspect AppDescriptor.getParams() and Config.envKey() for environment-name construction. Review the Java Secret and REST SecretView representations, app-key listing methods, and integration tests covering legacy override semantics. Done means the specified precedence, provisioning, masking, presence, and fallback behavior are covered by tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kubernetes
Domain
api, backend, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.