承接 netresearch/nr-vault 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

netresearch/nr-vault

Composer 安装命令:

composer require netresearch/nr-vault

包简介

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

README 文档

README

CI codecov 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
  • Usage analytics dashboard that surfaces stale, expired, never-rotated, and unused secrets (redaction candidates), counting automated vs. manual reads separately
  • 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 GuzzleHttp\Psr7\Request;
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
    {
        // Configure vault-based authentication (returns a new immutable client)
        $client = $this->httpClient->withAuthentication('stripe_api_key', SecretPlacement::Bearer);

        // Send a standard PSR-7 request - the secret is injected automatically
        $request = new Request(
            'POST',
            'https://api.stripe.com/v1/charges',
            ['Content-Type' => 'application/json'],
            json_encode($payload),
        );
        $response = $client->sendRequest($request);

        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

All 12 vault:* commands (full options and examples in Documentation/Developer/Commands.rst):

# --- Setup ---
# Initialize the vault by generating a master key
vendor/bin/typo3 vault:init

# --- Secret CRUD ---
# Store a secret in the vault (value via --value, --stdin, --file, or interactive prompt)
vendor/bin/typo3 vault:store my_secret_id --value="s3cr3t-value"
# Retrieve a secret from the vault
vendor/bin/typo3 vault:retrieve my_secret_id
# List secrets in the vault (respects access control)
vendor/bin/typo3 vault:list
# Rotate (update) a secret
vendor/bin/typo3 vault:rotate my_secret_id --reason="Scheduled rotation"
# Delete a secret from the vault
vendor/bin/typo3 vault:delete my_secret_id

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

# --- Migration & hardening ---
# Migrate an existing plaintext DB field value into the vault
vendor/bin/typo3 vault:migrate-field tx_myext_settings api_key
# Scan database and configuration for potential plaintext secrets
vendor/bin/typo3 vault:scan
# Clean up orphaned vault secrets from deleted TCA records
vendor/bin/typo3 vault:cleanup-orphans

# --- Audit ---
# Query and export vault audit logs (filter by --since / --until, Y-m-d)
vendor/bin/typo3 vault:audit --identifier=my_secret_id --since=2026-05-01
# Migrate the audit log hash chain from SHA-256 to HMAC-SHA256
vendor/bin/typo3 vault:audit-migrate-hmac

Requirements

  • TYPO3: v13.4 LTS / v14.3 LTS+
  • PHP: ^8.2
  • 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

netresearch/nr-vault 适用场景与选型建议

netresearch/nr-vault 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 25.84k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2026 年 01 月 06 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「security」 「oauth」 「encryption」 「typo3」 「credentials」 「secrets」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 netresearch/nr-vault 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 netresearch/nr-vault 我们能提供哪些服务?
定制开发 / 二次开发

基于 netresearch/nr-vault 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

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

GitHub 信息

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

其他信息

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