Extension · moselwal/secret-resolver

secret-resolver — secrets in site configs, at runtime.

Write %secret(API_KEY)% straight into your TYPO3 site configs — resolved at runtime in a cascade: first KEY_FILE env, then /run/secrets/, then env fallback. Extensible via SecretProviderInterface. Container deployments need exactly this.

Das Problem

Secrets in site configs are plain text — or not loaded at all.

With secret-resolver

  • %secret(API_KEY)% syntax directly in site config YAMLs
  • Cascading lookup: API_KEY_FILE/run/secrets/api_keyAPI_KEY env
  • Compatible with Docker and Kubernetes secrets out of the box
  • Custom providers via SecretProviderInterface (e.g. Vault, AWS SM)
  • Cache-aware — no re-lookups on every request

Until now

  • API keys hard-coded in YAML configs (in the Git repo)
  • Or: referenced via ENV variables in TypoScript (clunky)
  • Docker/K8s secrets via /run/secrets/ not usable out of the box
  • Multi-provider lookup (Vault, AWS Secrets Manager) as custom boilerplate

Four building blocks

Extensibility

Implement SecretProviderInterface — and Vault, AWS Secrets Manager, or Bitwarden Secrets are usable as an additional lookup step.

Container-ready

Works seamlessly with Docker secrets and Kubernetes mounted secrets — no image-build adjustment required.

Cascading lookup

Default order: {KEY}_FILE env (path), /run/secrets/{key}, then {KEY} env as fallback. Configurable per provider.

%secret() syntax

Usable directly in YAML site configs — no custom bootstrap logic required.

Installation: composer require moselwal/secret-resolver

TYPO3: 14.0+ · PHP: 8.3+

Add the Composer repository at gitlab.moselwal.io, then run composer require moselwal/secret-resolver. For clean configuration integration, combine it with moselwal/typo3-config if needed.

Usage

Simple keys (cascade resolution)

 

# config/sites/main/config.yaml
apiKey: '%secret(API_KEY)%'
dbPassword: '%secret(DB_PASSWORD)%'

# Inline in strings:
dsn: 'mysql://user:%secret(DB_PASSWORD)%@db:3306/app'

 

The key is resolved through all registered providers in priority order — first match wins.

Extended keys (provider-targeted)

 

# Direct vault lookup — bypasses cascade, goes to the "vault" provider
dbPassword: '%secret(vault:kv-v2/database.password)%'
apiToken: '%secret(vault:transit/api_token)%'

# AWS Secrets Manager
dbPassword: '%secret(aws-sm:prod/database.password)%'

 

Format: %secret(provider:path/to/secret.subKey)%

PartRequiredDescription
providerYesProvider name (vault, aws-sm …) — routes directly
pathNoSecret path with / separators
subKeyNoJSON sub-key after the last . in the final path segment

Sub-key extraction: if a provider returns e.g. {"password":"s3cret","username":"admin"}, the sub-key password automatically extracts "s3cret". Simple keys (without :) keep working as before — fully backwards-compatible.

Source code & docs

TYPO3 Extension Repository

Not in the official TER — install via Composer only.

Composer package

moselwal/secret-resolver via the Moselwal Composer repo.

Open the Composer repo

GitLab (source of truth)

Primary repository including CI/CD and Composer package registry.

gitlab.moselwal.io

GitHub

GitHub mirror (placeholder — verify before publish).

github.com/moselwal/secret-resolver
Nächster Schritt

Tidy up your container deployment?

secret-resolver is open source and compact. For Vault or AWS Secrets Manager integration, cluster setups or migration away from plain-text secrets, we are happy to support you.

Secret-Setup besprechen

Oder direkt schreiben: kontakt@moselwal.de