Skip to content

Load secrets from _FILE environment variables#2019

Closed
itsalljustdata wants to merge 1 commit into
grimmory-tools:developfrom
itsalljustdata:_FILE-env_vars
Closed

Load secrets from _FILE environment variables#2019
itsalljustdata wants to merge 1 commit into
grimmory-tools:developfrom
itsalljustdata:_FILE-env_vars

Conversation

@itsalljustdata

@itsalljustdata itsalljustdata commented Jul 15, 2026

Copy link
Copy Markdown

Added processing of _FILE environment variables to load secrets from files.

Description

Linked Issue

Changes

Manual Testing Steps

Screenshots (Optional)

Additional Context (Optional)

AI Disclosure

Checklist

  • This PR links and implements an accepted issue.
  • This PR is a single focused change.
  • There are new or updated tests validating this change.
  • I ran just ui check and just api check.
  • I have added screenshots if there were any UI changes.
  • I have disclosed any AI usage as per the organization AI Policy above.
  • I understand all of my submitted changes.

Summary by CodeRabbit

  • New Features
    • Added support for loading environment variable values from files using the _FILE suffix.
    • Displays a success message when a referenced file is read successfully.
    • Warns when a specified environment variable file cannot be found.

Added processing of _FILE environment variables to load secrets from files.
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The Docker entrypoint now resolves environment variables ending in _FILE by reading existing file paths, exporting their contents under corresponding variable names, and warning when files are missing. Existing user and group setup behavior remains unchanged.

Changes

Docker entrypoint environment handling

Layer / File(s) Summary
Resolve _FILE environment variables
packaging/docker/entrypoint.sh
Scans _FILE variables, reads existing files, exports the corresponding non-_FILE variables, and reports success or missing files.

Estimated code review effort: 2 (Simple) | ~5 minutes

Suggested labels: enhancement


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (2 errors)

Check name Status Explanation Resolution
Title check ❌ Error The title is descriptive, but it does not follow the required conventional commit format. Rewrite the title as a conventional commit, e.g. "feat: load secrets from _FILE environment variables".
Description check ❌ Error Only the summary sentence is filled; the required Description, Linked Issue, Changes, Testing, AI Disclosure, and Checklist sections are empty. Complete each required section with real details, add a linked issue, exact manual test steps, AI disclosure, and check the checklist items.
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packaging/docker/entrypoint.sh`:
- Around line 38-42: Update the environment-variable discovery loop in the
entrypoint script to extract and validate variable names before processing them,
accepting only names whose suffix is exactly _FILE. Ensure names such as
CACHE_FILE_BACKUP are excluded, while preserving the existing file existence
check and export behavior for valid variables.
- Around line 38-39: Replace the eval-based lookup in the environment-variable
loop with a safe lookup using the variable name as data, such as printenv
"$var". Validate that each var matches the expected environment-variable naming
pattern before using it, then preserve the existing export behavior without
evaluating environment-derived shell code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: fbd83c43-801c-49c7-80dc-5a47dd40a5f9

📥 Commits

Reviewing files that changed from the base of the PR and between 634e9e2 and 811fcb3.

📒 Files selected for processing (1)
  • packaging/docker/entrypoint.sh
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • grimmory-tools/grimmory-docs (manual)
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*

⚙️ CodeRabbit configuration file

**/*: This project is being developed using current and future-facing technologies:

  • Java 25 with --enable-preview (preview features are INTENTIONAL and encouraged)
  • Spring Boot 4 (latest major version, check APIs accordingly)
  • Jackson 3 (new package: tools.jackson.* instead of com.fasterxml.jackson.*)
  • Hibernate 7.3.x (Jakarta Persistence 3.2, new APIs; avoid deprecated Hibernate 5/6 patterns)
  • Angular 21 (signals-based reactivity, no NgModules unless legacy)

Grimmory Internal Tools

Metadata Standards and Compliance

  • For all metadata writing and parsing logic, double-check against Dublin Core and ANSI standards to ensure perfect official compliance.
  • We strictly follow the widespread and official XML-compliant methods for EPUB2, EPUB3, CBX, and PDF formats.

General Java and Spring rules

  • ALWAYS prefer modern, idiomatic Java 25 constructs over legacy patterns.
  • Preview features (--enable-preview) are enabled and intentional; do NOT flag them as risky unless there is a concrete runtime issue.
  • Prefer: records, sealed classes/interfaces, pattern matching (switch expressions, instanceof), structured concurrency (StructuredTaskScope), scoped values, string templates, unnamed patterns/variables.
  • Prefer virtual threads (Thread.ofVirtual(), Executors.newVirtualThreadPerTaskExecutor()) over platform threads for I/O-bound work.
  • Prefer the new Sequenced Collections API (SequencedCollection, SequencedMap) where applicable.
  • Prefer var for local variables when the type is obvious from context.
  • Use stream().toList() instead of stream().collect(Collectors.toList()) for imm...

Files:

  • packaging/docker/entrypoint.sh
🪛 ast-grep (0.44.1)
packaging/docker/entrypoint.sh

[error] 38-38: eval is invoked on a variable, parameter expansion, or command-substitution result, which re-parses the value as shell code. If any part of that value is attacker-controlled (arguments, environment, file contents, network output), it allows arbitrary command execution. Do not eval dynamic data: invoke the command directly with proper quoting (e.g. "$cmd" "$arg"), use arrays for argument lists (cmd=(prog --flag "$value"); "${cmd[@]}"), or restrict input to a validated allowlist before running it.
Context: eval echo $$var
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(eval-on-variable-bash)

🪛 Shellcheck (0.11.0)
packaging/docker/entrypoint.sh

[info] 39-39: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 42-42: Quote this to prevent word splitting.

(SC2046)

🔇 Additional comments (1)
packaging/docker/entrypoint.sh (1)

42-42: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Quote the complete export assignment.

Because the command-substitution result is unquoted, file contents containing spaces or glob characters can be split or expanded. Use:

-        export "$var_name"=$(cat "$file_path")
+        export "$var_name=$(cat "$file_path")"
			> Likely an incorrect or invalid review comment.

Source: Linters/SAST tools

Comment on lines +38 to +39
for var in $(env | grep '_FILE=' | cut -d= -f1); do
file_path=$(eval echo \$$var)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Remove eval from environment-variable lookup.

eval echo \$$var reparses the environment-derived name as shell code. A crafted environment variable name can therefore execute arbitrary commands before su-exec drops privileges. Use a safe lookup such as printenv "$var" and validate the variable name before exporting it.

🧰 Tools
🪛 ast-grep (0.44.1)

[error] 38-38: eval is invoked on a variable, parameter expansion, or command-substitution result, which re-parses the value as shell code. If any part of that value is attacker-controlled (arguments, environment, file contents, network output), it allows arbitrary command execution. Do not eval dynamic data: invoke the command directly with proper quoting (e.g. "$cmd" "$arg"), use arrays for argument lists (cmd=(prog --flag "$value"); "${cmd[@]}"), or restrict input to a validated allowlist before running it.
Context: eval echo $$var
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(eval-on-variable-bash)

🪛 Shellcheck (0.11.0)

[info] 39-39: Double quote to prevent globbing and word splitting.

(SC2086)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/docker/entrypoint.sh` around lines 38 - 39, Replace the eval-based
lookup in the environment-variable loop with a safe lookup using the variable
name as data, such as printenv "$var". Validate that each var matches the
expected environment-variable naming pattern before using it, then preserve the
existing export behavior without evaluating environment-derived shell code.

Source: Linters/SAST tools

Comment on lines +38 to +42
for var in $(env | grep '_FILE=' | cut -d= -f1); do
file_path=$(eval echo \$$var)
if [ -n "$file_path" ] && [ -f "$file_path" ]; then
var_name=${var%_FILE}
export "$var_name"=$(cat "$file_path")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restrict discovery to variable names ending in _FILE.

The grep '_FILE=' pattern matches names such as CACHE_FILE_BACKUP, while ${var%_FILE} leaves those names unchanged. The script can then overwrite unrelated configuration variables with file contents. Extract and validate names first, then process only an exact _FILE suffix.

🧰 Tools
🪛 ast-grep (0.44.1)

[error] 38-38: eval is invoked on a variable, parameter expansion, or command-substitution result, which re-parses the value as shell code. If any part of that value is attacker-controlled (arguments, environment, file contents, network output), it allows arbitrary command execution. Do not eval dynamic data: invoke the command directly with proper quoting (e.g. "$cmd" "$arg"), use arrays for argument lists (cmd=(prog --flag "$value"); "${cmd[@]}"), or restrict input to a validated allowlist before running it.
Context: eval echo $$var
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(eval-on-variable-bash)

🪛 Shellcheck (0.11.0)

[info] 39-39: Double quote to prevent globbing and word splitting.

(SC2086)


[warning] 42-42: Quote this to prevent word splitting.

(SC2046)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packaging/docker/entrypoint.sh` around lines 38 - 42, Update the
environment-variable discovery loop in the entrypoint script to extract and
validate variable names before processing them, accepting only names whose
suffix is exactly _FILE. Ensure names such as CACHE_FILE_BACKUP are excluded,
while preserving the existing file existence check and export behavior for valid
variables.

@imnotjames

imnotjames commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Which environment variables are these for? DATABASE_PASSWORD?

Doesn't this suffer from the same problems that normal environment variables do - that the secrets are stored in the clear where other processes can easily read them?

@webysther

Copy link
Copy Markdown

Which environment variables are these for? DATABASE_PASSWORD?

Doesn't this suffer from the same problems that normal environment variables do - that the secrets are stored in the clear where other processes can easily read them?

Trivial implementation using the same of wide used

https://hub.docker.com/_/mariadb#secrets

LGTM

@webysther

Copy link
Copy Markdown

@balazs-szucs I checked this one, safe and important for security reasons.

@imnotjames

Copy link
Copy Markdown
Contributor

Which environment variables are these for? DATABASE_PASSWORD?
Doesn't this suffer from the same problems that normal environment variables do - that the secrets are stored in the clear where other processes can easily read them?

Trivial implementation using the same of wide used

https://hub.docker.com/_/mariadb#secrets

LGTM

I get that other docker images have used this. I am asking what makes this safer, and when should people be using it?

I would understand it being safer if the process itself read the _FILE env var and stored it in process memory.

These are still available in /proc/$PID/environ, and can be read in various ways.

Where was this discussed?

I checked this one, safe and important for security reasons.

I also checked it, given this is also an implementation that uses eval in an unsafe way I am going to close this for now. Please feel free to open a feature request.

@imnotjames imnotjames closed this Jul 18, 2026
@webysther

webysther commented Jul 18, 2026

Copy link
Copy Markdown

Which environment variables are these for? DATABASE_PASSWORD?
Doesn't this suffer from the same problems that normal environment variables do - that the secrets are stored in the clear where other processes can easily read them?

Trivial implementation using the same of wide used
https://hub.docker.com/_/mariadb#secrets
LGTM

I get that other docker images have used this. I am asking what makes this safer, and when should people be using it?

I would understand it being safer if the process itself read the _FILE env var and stored it in process memory.

These are still available in /proc/$PID/environ, and can be read in various ways.

Where was this discussed?

I checked this one, safe and important for security reasons.

I also checked it, given this is also an implementation that uses eval in an unsafe way I am going to close this for now. Please feel free to open a feature request.

Technical Debt: https://docs.docker.com/compose/how-tos/use-secrets/

Please, reopen.

@webysther

Copy link
Copy Markdown

@imnotjames

imnotjames commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Per the website you linked:

Kubernetes Pod and Deployment manifests use the env or envFrom fields to inject secrets directly into container environment variables. When developers use env with secretKeyRef or envFrom with secretRef, the secret values become accessible to any process within the container via /proc/*/environ, visible in kubectl describe pod output, exposed through container runtime APIs (docker inspect, crictl inspect), and inherited by all child processes spawned within the container, creating widespread secret exposure.

This problem also applies to the implementation here. I will not reopen this. Thanks for understanding!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants