PHPackages                             moselwal/secret-resolver - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. moselwal/secret-resolver

ActiveTypo3-cms-extension[Utility &amp; Helpers](/categories/utility)

moselwal/secret-resolver
========================

Runtime secret resolution for TYPO3 site configuration — cascading lookup from secret files, /run/secrets/ mounts, and environment variables via %secret(KEY)% placeholder syntax.

v0.5.1(1mo ago)00MITPHPPHP ^8.5

Since Jun 6Pushed 1mo agoCompare

[ Source](https://github.com/Moselwal-Digitalagentur/secret-resolver)[ Packagist](https://packagist.org/packages/moselwal/secret-resolver)[ Docs](https://moselwal.de)[ RSS](/packages/moselwal-secret-resolver/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (5)Versions (4)Used By (0)

moselwal/secret-resolver
========================

[](#moselwalsecret-resolver)

Runtime secret resolution for TYPO3 YAML configuration.

What does this extension do?
----------------------------

[](#what-does-this-extension-do)

TYPO3 supports `%env(VAR)%` in site configuration YAML — but only for plain environment variables. In container and Kubernetes environments, secrets are often mounted as files (`/run/secrets/`) or referenced via `*_FILE` environment variables. And in production setups with HashiCorp Vault, AWS Secrets Manager or similar tools, you may want to resolve secrets directly from these backends.

This extension adds the `%secret(KEY)%` syntax that resolves secrets from configurable sources — with a built-in cascade for file-based secrets and an extensible provider architecture for direct backend integration.

Installation
------------

[](#installation)

```
composer require moselwal/secret-resolver
```text

## Usage

### Simple keys (cascade resolution)

```yaml
# 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 resolution)

[](#extended-keys-provider-targeted-resolution)

```
# Direct Vault lookup — bypasses cascade, routes to "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)%'
```text

Extended key format: `%secret(provider:path/to/secret.subKey)%`

| Part | Required | Description |
|---|---|---|
| `provider` | Yes | Provider name (e.g. `vault`, `aws-sm`) — routes directly to that provider |
| `path` | No | Secret path with `/` separators (e.g. `kv-v2/database`) |
| `subKey` | No | JSON sub-key after last `.` in the final path segment — extracts a field from a JSON response |

**Sub-key extraction**: If the provider returns a JSON string like `{"password":"s3cret","username":"admin"}`, the sub-key `password` extracts `"s3cret"` automatically.

Simple keys (without `:`) continue to work exactly as before — fully backward-compatible.

## Built-in resolution cascade

For simple keys like `%secret(DB_PASSWORD)%`:

| Priority | Provider | Source | Example |
|---|---|---|---|
| 30 | FileEnvSecretProvider | `DB_PASSWORD_FILE` env → read file | `DB_PASSWORD_FILE=/vault/secrets/db-pass` |
| 20 | RunSecretsSecretProvider | `/run/secrets/db_password` | Docker/K8s secret mount |

First match wins. Empty values and whitespace-only files are skipped.

## Works in all TYPO3 YAML files

The `%secret()%` placeholder hooks into TYPO3's central `YamlFileLoader`, so it works in **all** TYPO3 YAML configurations — not just Site Configuration:

- Site Configuration (`config/sites/*/config.yaml`)
- Form Framework YAML definitions
- Services.yaml (Dependency Injection)
- Any YAML loaded through TYPO3's standard YAML loader

## Caching

Resolved values are cached by TYPO3 in `cache.core` (identical to `%env()%`). After secret rotation:

```bash
vendor/bin/typo3 cache:flush
```

Implementing a custom SecretProvider
------------------------------------

[](#implementing-a-custom-secretprovider)

The extension is designed for extensibility. Any TYPO3 extension can add its own secret provider — no modification of the core package required.

### Step 1: Implement `SecretProviderInterface`

[](#step-1-implement-secretproviderinterface)

```
