定制 netresearch/nr-vault 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

netresearch/nr-vault

最新稳定版本:v0.2.0

Composer 安装命令:

composer require netresearch/nr-vault

包简介

Secure secrets management for TYPO3 with envelope encryption, access control, and audit logging

README 文档

README

CI codecov Security OpenSSF Scorecard OpenSSF Best Practices TYPO3 PHP PHPStan License Latest Release Contributor Covenant SLSA 3

Enterprise-grade secret management without enterprise-grade complexity.

The Problem

Your TYPO3 site integrates with Stripe, SendGrid, Google Maps, and a dozen other services. Where are those API keys right now?

Probably in plain text in LocalConfiguration.php, unencrypted in a database field, or hardcoded somewhere accessible to every backend user.

If your database leaks, your secrets leak. If you need to rotate a compromised key, you're editing config files and redeploying.

How Secrets Are Typically Stored

Method Security Operational Reality
External Services (HashiCorp Vault, AWS SM) ⭐⭐⭐⭐⭐ Infrastructure cost, network access, auth to service
Environment Variables ⭐⭐⭐ Deployment/host access required, restart to change, no rotation UI, no audit trail
Files outside webroot ⭐⭐⭐ Deployment/host access required, hard to rotate, no management interface
nr-vault (encrypted DB) ⭐⭐⭐⭐ Runtime manageable via TYPO3 backend, rotate anytime, full audit trail
Plain text in config/DB ❌ No protection

Why nr-vault?

All "more secure" methods require either external infrastructure, deployment pipelines, or server access. And they all lack a management UI and audit trail.

Challenge Env Vars / Files nr-vault
Rotate a compromised API key Call DevOps, redeploy, restart Click in backend, done
See who accessed a secret Check deploy logs (if any) Full audit log with timestamps
Emergency credential revocation Wait for deployment pipeline Immediate via backend module
Non-technical editor updates SMTP password Create support ticket Self-service in backend
Compliance audit: prove access history Manually correlate logs Export tamper-evident audit trail

Solution

nr-vault provides:

  • Envelope encryption with AES-256-GCM via libsodium
  • Master key management (file, environment variable, or derived)
  • Per-secret access control via backend user groups with context scoping
  • Audit logging of all secret access with tamper-evident hash chain
  • Key rotation support for both secrets and master key
  • TCA integration via custom vaultSecret field type
  • Vault HTTP Client - make authenticated API calls without exposing secrets
  • CLI commands for DevOps automation
  • Pluggable adapter architecture (external vault adapters planned for future releases)

Architecture

flowchart TB
    subgraph TYPO3["TYPO3 Backend"]
        subgraph Entry["Entry Points"]
            TCA["TCA Field<br/>(vaultSecret)"]
            Backend["Backend Module<br/>(Secrets Manager)"]
            CLI["CLI Commands"]
        end

        TCA & Backend & CLI --> VaultService

        subgraph VaultService["VaultService"]
            API["store() | retrieve() | rotate() | delete() | list() | http()"]
        end

        VaultService --> AccessControl["AccessControl<br/>Service"]
        VaultService --> Encryption["EncryptionService"]
        VaultService --> Audit["AuditLogService"]

        Encryption --> Adapters

        subgraph Adapters["Vault Adapters"]
            Local["LocalDatabase<br/>(DEFAULT)"]
            Future["Future: HashiCorp,<br/>AWS, Azure"]
        end
    end
Loading

Encryption Model

Uses envelope encryption (same pattern as AWS KMS, Google Cloud KMS):

flowchart TB
    MK["🔐 Master Key<br/>(stored outside database)"]
    DEK["🔑 Data Encryption Key (DEK)<br/>(unique per secret)"]
    Secret["📄 Secret Value<br/>(API key, password, token)"]

    MK -->|encrypts| DEK
    DEK -->|encrypts| Secret
Loading

Benefits:

  • Master key rotation only requires re-encrypting DEKs (fast)
  • Each secret has unique encryption
  • Compromise of one secret doesn't expose others

Quick Start

Store and Retrieve Secrets

use Netresearch\NrVault\Service\VaultServiceInterface;

class MyService
{
    public function __construct(
        private readonly VaultServiceInterface $vault,
    ) {}

    public function storeApiKey(string $provider, string $apiKey): void
    {
        $this->vault->store(
            identifier: "my_extension_{$provider}_api_key",
            secret: $apiKey,
            options: [
                'owner' => $GLOBALS['BE_USER']->user['uid'],
                'groups' => [1, 2],  // Admin, Editor groups
                'context' => 'payment',  // Permission scoping
                'expiresAt' => time() + 86400 * 90,  // 90 days
            ]
        );
    }

    public function getApiKey(string $provider): ?string
    {
        return $this->vault->retrieve("my_extension_{$provider}_api_key");
    }
}

Vault HTTP Client

Make authenticated API calls without exposing secrets to your code:

use Netresearch\NrVault\Http\SecretPlacement;
use Netresearch\NrVault\Http\VaultHttpClientInterface;

class PaymentService
{
    public function __construct(
        private readonly VaultHttpClientInterface $httpClient,
    ) {}

    public function chargeCustomer(array $payload): array
    {
        // Secret is injected by vault - never visible to this code
        $response = $this->httpClient->post(
            'https://api.stripe.com/v1/charges',
            [
                'auth_secret' => 'stripe_api_key',
                'placement' => SecretPlacement::Bearer,
                'json' => $payload,
            ],
        );

        return json_decode($response->getBody()->getContents(), true);
    }
}

Secret placement options: Bearer, BasicAuth, Header, QueryParam, BodyField, ApiKey, OAuth2.

TCA Integration

'api_key' => [
    'label' => 'API Key',
    'config' => [
        'type' => 'input',
        'renderType' => 'vaultSecret',
        'size' => 30,
    ],
],

CLI Commands

# Initialize vault (create master key)
vendor/bin/typo3 vault:init

# List secrets (respects access control)
vendor/bin/typo3 vault:list

# Rotate a secret
vendor/bin/typo3 vault:rotate my_secret_id --reason="Scheduled rotation"

# Rotate master key (re-encrypts all DEKs)
vendor/bin/typo3 vault:rotate-master-key --new-key=/path/to/new.key --confirm

# View audit log
vendor/bin/typo3 vault:audit --identifier=my_secret_id --days=30

# Export secrets (encrypted backup)
vendor/bin/typo3 vault:export --output=secrets.enc

Requirements

  • TYPO3: v14.0+
  • PHP: ^8.5
  • Extensions: ext-sodium (bundled with PHP)
  • CPU: AES-NI support recommended (XChaCha20-Poly1305 fallback available)

Documentation

Full documentation is available in the Documentation/ folder and can be rendered with the TYPO3 documentation tools.

Render locally

docker run --rm -v $(pwd):/project ghcr.io/typo3-documentation/render-guides:latest --progress Documentation
# Open Documentation-GENERATED-temp/Index.html

Planning documents

Internal development documents are available in docs/:

Feature Comparison

Feature nr-vault Drupal Key Laravel Secrets Symfony Secrets
Envelope encryption Yes No No No
Per-secret DEKs Yes No No No
External vault support Planned Pluggable Limited HashiCorp
Access control BE groups + context By key N/A N/A
Audit logging Full + hash chain Limited None None
TCA/Form integration Native Form API N/A N/A
Key rotation CLI Yes Manual Yes Yes
HTTP client Yes No No No
OAuth auto-refresh Yes No No No

Roadmap

  • Phase 1-5: Core functionality (current focus)
  • Phase 6: External adapters (HashiCorp, AWS, Azure) + Optional Rust FFI for zero-PHP-exposure
  • Phase 7: Service Registry - abstract away both credentials AND endpoints

Installation

composer require netresearch/nr-vault

Or in DDEV:

ddev start
ddev install-v14
ddev vault-init

License

GPL-2.0-or-later

[n] Developed by Netresearch DTT GmbH - Enterprise TYPO3 Solutions

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 1
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-2.0-or-later
  • 更新时间: 2026-01-06