Skip to content

feat: [settings] environment variables as a third settings source#10845

Merged
iglocska merged 1 commit into
MISP:2.5from
skraft9:feature-env-settings-source-10811
Jul 9, 2026
Merged

feat: [settings] environment variables as a third settings source#10845
iglocska merged 1 commit into
MISP:2.5from
skraft9:feature-env-settings-source-10811

Conversation

@skraft9

@skraft9 skraft9 commented Jun 14, 2026

Copy link
Copy Markdown
Member

What does it do?

Fixes #10811

Adds environment variables as a third configuration source alongside config.php and the system_settings database table. This implementation is explicitly designed for containerized and Kubernetes environments where configuration parameters are dynamically injected at runtime.

  • Any configuration parameter can be supplied as an environment variable using the prefix MISP_SETTING_.
  • The configuration key structure translates dots (.) into double underscores (__).

Mapping Examples

MISP Setting Key Environment Variable Equivalent
MISP.baseurl MISP_SETTING_MISP__baseurl
Security.salt MISP_SETTING_Security__salt
Plugin.Enrichment.services_url MISP_SETTING_Plugin__Enrichment__services_url

How it works

  • Precedence Chain: A lightweight EnvSetting helper reads matching environment variables and writes them into the Configure store. It executes after the flat-file and database bootstrap routines in both AppController and the CLI ConfigLoadTask. Configuration precedence is resolved as follows:

Environment Variables --> Database Table --> config.php File

  • Immutability (Read-Only): Environment-provided settings are strictly read-only. The serverSettingsEditValue method is updated to reject modification attempts via the UI or API, returning a clear error message in line with how cli_only directives are handled.
  • Type Determination: Values undergo deterministic casting to preserve strict type safety. Literal strings matching true, false, or null are cast to their corresponding primitive types, followed by integer and float checks. Valid JSON strings are parsed into associative arrays/objects; otherwise, the value defaults to a raw string. (Numeric strings intended to remain strings should be quoted or JSON-encoded).
  • Category Scoping & Secrets: Only known setting categories registered within the MISP schema are parsed and accepted. Unlike the database configuration pipeline, sensitive low-level configurations (such as the application salt or encryption keys) are permitted, as environment injection is the standard practice for secret management in orchestrated infrastructure.
  • Redis Capabilities: Connection parameters for the Redis backend are supported natively out-of-the-box because they already reside within the centralized settings registry.

Security

  • Header Spoofing Protection: The MISP_SETTING_ prefix completely avoids the HTTP_ namespace defined by CGI/FastCGI implementations. Verification testing on live web servers confirms that a malicious client attempting to send a MISP_SETTING_... HTTP request header lands in PHP as HTTP_MISP_SETTING_... and is safely ignored by the loader.
  • Privilege Alignment: Modifying these variables requires process environment control over the underlying container or service execution context, aligning exactly with the trust level required to modify config.php on disk.
  • UI Masking: Sensitive strings remain masked within administrative menus, as data redaction logic hooks directly into the core setting schema definitions rather than evaluating the backend configuration source.

Out of scope

  • database.php Adjustments: Database backend connection parameters utilize a distinct initialization routine that runs prior to the settings registry bootstrap. Because the official MISP Docker stack already handles the dynamic templating of database.php from standard environment variables, updating this specific layer has been deferred as a potential downstream enhancement.

Questions

  • Does it require a DB change? No
  • Are you using it in production? Verified in local Docker containerized testing environments.
  • Does it require a change in the API (PyMISP for example)? No

Testing

Validation testing was executed on a local containerized v2.5 stack running under the default configuration baseline.

  • Syntax & Stability: Verified php -l compliance across all modified controllers and components; runtime compilation succeeded without performance degradation.
  • Override Verification: Passing MISP_SETTING_MISP__title_text=EnvWins forces getSetting MISP.title_text to correctly return EnvWins.
  • Precedence Verification: Injecting MISP_SETTING_MISP__redis_database=99 successfully overwrites the disk configuration default of 13, confirming that environment strings take absolute priority.
  • Type-Casting Integrity: Validated that literal boolean values (false) and explicit digits resolve as primitive booleans and integers rather than truthy strings.
  • Schema Enforcement: Sensitive keys (Security.salt) were successfully parsed and loaded, unregistered structural categories were dropped, and unrelated process environment variables were ignored.
  • Write-Lock Verification: Attempting a setSetting call against an environment-managed variable returns an explicit modification rejection, while unmanaged keys modify normally.
  • Namespace Defense: Forged client HTTP headers mimicking the configuration layout were rejected cleanly at the application layer.

…P#10811)

Add environment variables as a third configuration source, in addition
to config.php and the system_settings database table. This is primarily
useful for container and Kubernetes deployments where settings are
injected as environment variables.

Variables use the prefix MISP_SETTING_ followed by the setting name with
each dot replaced by a double underscore, for example MISP.baseurl maps
to MISP_SETTING_MISP__baseurl. Values are cast to bool, null, int, float
or JSON, falling back to the raw string.

Environment provided settings take precedence over both the database and
the config file (env > db > file), so EnvSetting::setGlobalSetting() is
applied after the existing sources in AppController and ConfigLoadTask.
They are read only: serverSettingsEditValue rejects changes to a setting
that is provided via the environment.

Unlike the database source, sensitive settings are allowed via the
environment, since environment variables are the intended channel for
injecting secrets. Redis connection settings are covered automatically
as they already live in the settings registry.
@iglocska iglocska merged commit 8a89410 into MISP:2.5 Jul 9, 2026
2 checks passed
@iglocska

iglocska commented Jul 9, 2026

Copy link
Copy Markdown
Member

That looks clean, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Env variables as alternate setting source

2 participants