Developer 

Architecture overview 

nr-vault follows clean architecture principles with these main components:

Service layer
VaultService - Main facade for all vault operations.
Crypto layer
EncryptionService - Envelope encryption implementation. MasterKeyProvider - Master key retrieval abstraction.
Storage layer
SecretRepository - Database persistence. VaultAdapterInterface - Storage backend abstraction.
Security layer
AccessControlService - Permission checks. AuditLogService - Operation logging.

Extending nr-vault 

Custom storage adapters 

Implement VaultAdapterInterface to add new storage backends:

EXT:my_extension/Classes/Adapter/CustomAdapter.php
namespace MyVendor\MyExtension\Adapter;

use Netresearch\NrVault\Adapter\VaultAdapterInterface;
use Netresearch\NrVault\Domain\Model\Secret;

final class CustomAdapter implements VaultAdapterInterface
{
    public function getIdentifier(): string
    {
        return 'custom';
    }

    public function isAvailable(): bool
    {
        // Check if your backend is configured and reachable
    }

    public function store(Secret $secret): void
    {
        // Store secret in your backend
    }

    public function retrieve(string $identifier): ?Secret
    {
        // Retrieve secret from your backend
    }

    public function delete(string $identifier): void
    {
        // Delete from your backend
    }

    public function exists(string $identifier): bool
    {
        // Check if secret exists
    }

    public function list(array $filters = []): array
    {
        // List secret identifiers
    }

    public function getMetadata(string $identifier): ?array
    {
        // Get secret metadata
    }

    public function updateMetadata(string $identifier, array $metadata): void
    {
        // Update metadata
    }
}
Copied!

Register in Services.yaml:

EXT:my_extension/Configuration/Services.yaml
MyVendor\MyExtension\Adapter\CustomAdapter:
  tags:
    - name: nr_vault.adapter
      identifier: custom
Copied!

Custom master key providers 

Implement MasterKeyProviderInterface for custom key sources:

EXT:my_extension/Classes/Crypto/VaultKeyProvider.php
namespace MyVendor\MyExtension\Crypto;

use Netresearch\NrVault\Crypto\MasterKeyProviderInterface;

final class VaultKeyProvider implements MasterKeyProviderInterface
{
    public function getIdentifier(): string
    {
        return 'hashicorp';
    }

    public function isAvailable(): bool
    {
        // Check if HashiCorp Vault is accessible
    }

    public function getMasterKey(): string
    {
        // Retrieve key from HashiCorp Vault
    }

    public function storeMasterKey(string $key): void
    {
        // Store key in HashiCorp Vault
    }

    public function generateMasterKey(): string
    {
        return random_bytes(32);
    }
}
Copied!

Events 

nr-vault dispatches PSR-14 events for extensibility:

SecretAccessedEvent
Dispatched when a secret is read.
SecretCreatedEvent
Dispatched when a new secret is created.
SecretRotatedEvent
Dispatched when a secret is rotated with a new value.
SecretUpdatedEvent
Dispatched when a secret value is updated (without rotation).
SecretDeletedEvent
Dispatched when a secret is deleted.
MasterKeyRotatedEvent
Dispatched after master key rotation completes.

Example listener:

EXT:my_extension/Classes/EventListener/SecretAccessLogger.php
namespace MyVendor\MyExtension\EventListener;

use Netresearch\NrVault\Event\SecretAccessedEvent;

final class SecretAccessLogger
{
    public function __invoke(SecretAccessedEvent $event): void
    {
        // Custom logging or alerting
        $identifier = $event->getIdentifier();
        $actorUid = $event->getActorUid();
    }
}
Copied!

Testing 

Development setup 

Use DDEV for local development:

Start DDEV environment
ddev start
ddev install-v14
ddev vault-init
Copied!

Running tests 

Run test suites
# All tests
ddev exec composer test

# Unit tests only
ddev exec .Build/bin/phpunit -c Tests/Build/phpunit.xml --testsuite Unit

# With coverage
ddev exec .Build/bin/phpunit -c Tests/Build/phpunit.xml --coverage-html .Build/coverage
Copied!

Code quality 

Run code quality tools
# PHP-CS-Fixer
ddev exec composer fix

# PHPStan
ddev exec composer stan
Copied!

Contributing 

See CONTRIBUTING.md for contribution guidelines.

  1. Fork the repository.
  2. Create a feature branch.
  3. Write tests for your changes.
  4. Ensure all tests pass.
  5. Submit a pull request.

API reference 

VaultService 

class VaultService
Fully qualified name
\Netresearch\\NrVault\\Service\VaultService

Main facade for vault operations.

retrieve ( string $identifier)

Retrieve a decrypted secret value.

returntype

string|null

store ( string $identifier, string $secret, array $options = []) : void

Create or update a secret.

exists ( string $identifier) : bool

Check if a secret exists and is accessible.

delete ( string $identifier, string $reason = '') : void

Delete a secret.

rotate ( string $identifier, string $newSecret, string $reason = '') : void

Rotate a secret with a new value.

list ( string $pattern = null) : array

List accessible secrets.

param string|null $pattern

Optional filter pattern.

getMetadata ( string $identifier) : array

Get metadata for a secret.

http ( ) : VaultHttpClientInterface

Get the Vault HTTP Client.

EncryptionService 

class EncryptionService
Fully qualified name
\Netresearch\\NrVault\\Crypto\EncryptionService

Envelope encryption implementation.

encrypt ( string $plaintext, string $identifier) : array

Encrypt a value using envelope encryption.

decrypt ( string $encryptedValue, string $encryptedDek, string $dekNonce, string $valueNonce, string $identifier) : string

Decrypt an envelope-encrypted value.

generateDek ( ) : string

Generate a new Data Encryption Key.

calculateChecksum ( string $plaintext) : string

Calculate value checksum for change detection.

reEncryptDek ( string $encryptedDek, string $dekNonce, string $identifier, string $oldMasterKey, string $newMasterKey) : array

Re-encrypt a DEK with a new master key (for master key rotation).