API 

This chapter documents the public API of the nr-vault extension.

VaultService 

The main service for interacting with the vault.

interface VaultServiceInterface
Fully qualified name
\Netresearch\NrVault\Service\VaultServiceInterface

Main interface for vault operations.

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

Store a secret in the vault. $secret is a #[\SensitiveParameter].

param string $identifier

Unique identifier for the secret.

param string $secret

The secret value to store (#[\SensitiveParameter]).

param array $options

Optional configuration: owner (int BE-user UID), groups (int[] BE-group UIDs), context (string), expiresAt (int|DateTimeInterface|null), metadata (array), description (string), scopePid (int).

throws ValidationException

If the identifier is invalid.

throws EncryptionException

If encryption fails.

retrieve ( string $identifier)

Retrieve a secret from the vault.

param string $identifier

The secret identifier.

returntype

string|null

throws AccessDeniedException

If user lacks read permission.

throws SecretExpiredException

If the secret has expired.

Returns

The decrypted secret value or null if not found.

exists ( string $identifier) : bool

Check if a secret exists.

param string $identifier

The secret identifier.

Returns

True if the secret exists.

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

Delete a secret from the vault.

param string $identifier

The secret identifier.

param string $reason

Optional reason for deletion (logged).

throws SecretNotFoundException

If secret doesn't exist.

throws AccessDeniedException

If user lacks delete permission.

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

Rotate a secret with a new value. $newSecret is a #[\SensitiveParameter].

param string $identifier

The secret identifier.

param string $newSecret

The new secret value (#[\SensitiveParameter]).

param string $reason

Optional reason for rotation (logged).

list ( ?string $pattern = null) : array

List accessible secrets.

param string|null $pattern

Optional pattern to filter identifiers (supports the * wildcard).

Returns

A list<SecretMetadata> of secret metadata DTOs (Netresearch\NrVault\Domain\Dto\SecretMetadata).

getMetadata ( string $identifier) : SecretDetails

Get metadata for a secret without retrieving its value.

param string $identifier

The secret identifier.

throws SecretNotFoundException

If secret doesn't exist.

throws AccessDeniedException

If user lacks permission.

Returns

A SecretDetails DTO (Netresearch\NrVault\Domain\Dto\SecretDetails) with identifier, description, owner, groups, version, etc.

clearCache ( ) : void

Clear the request-scoped cache of decrypted secrets, securely wiping cached plaintext from memory.

http ( ) : VaultHttpClientInterface

Get an HTTP client that can inject secrets into requests.

Returns

A PSR-18 compatible vault-aware HTTP client.

EncryptionService 

The crypto boundary: libsodium envelope encryption (per-secret DEK wrapped by the master key).

interface EncryptionServiceInterface
Fully qualified name
\Netresearch\NrVault\Crypto\EncryptionServiceInterface

Low-level encryption operations. Most callers use VaultServiceInterface instead.

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

Encrypt a plaintext value with a unique DEK. $plaintext is a #[\SensitiveParameter].

param string $plaintext

The value to encrypt (#[\SensitiveParameter]).

param string $identifier

Secret identifier (used as AAD).

throws EncryptionException

If encryption fails.

Returns

An EncryptedData value object (Netresearch\NrVault\Crypto\EncryptedData) holding the ciphertext, encrypted DEK, and nonces.

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

Decrypt a previously encrypted value. $encryptedValue and $encryptedDek are #[\SensitiveParameter].

param string $encryptedValue

Base64-encoded ciphertext (#[\SensitiveParameter]).

param string $encryptedDek

Base64-encoded encrypted DEK (#[\SensitiveParameter]).

param string $dekNonce

Base64-encoded DEK nonce.

param string $valueNonce

Base64-encoded value nonce.

param string $identifier

Secret identifier (used as AAD).

throws EncryptionException

If decryption fails.

Returns

The decrypted plaintext.

generateDek ( ) : string

Generate a new Data Encryption Key.

Returns

A 32-byte random key.

calculateChecksum ( string $plaintext) : string

Calculate a value checksum for change detection. $plaintext is a #[\SensitiveParameter].

param string $plaintext

The secret value (#[\SensitiveParameter]).

Returns

SHA-256 hash (64 hex characters).

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

Re-encrypt a DEK with a new master key (used during master-key rotation). $encryptedDek, $oldMasterKey and $newMasterKey are #[\SensitiveParameter].

param string $encryptedDek

Current encrypted DEK (#[\SensitiveParameter]).

param string $dekNonce

Current DEK nonce.

param string $identifier

Secret identifier.

param string $oldMasterKey

Previous master key (#[\SensitiveParameter]).

param string $newMasterKey

New master key (#[\SensitiveParameter]).

Returns

A ReEncryptedDek value object (Netresearch\NrVault\Crypto\ReEncryptedDek).

Usage examples 

Storing a secret 

Store a secret with VaultService
use Netresearch\NrVault\Service\VaultServiceInterface;

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

    public function storeApiKey(string $apiKey): void
    {
        $this->vault->store(
            'my_extension_api_key',
            $apiKey,
            [
                'description' => 'API key for external service',
                'groups' => [1, 2], // Admin, Editor groups
                'context' => 'payment',
                'expiresAt' => time() + 86400 * 90, // 90 days
            ]
        );
    }
}
Copied!

Retrieving a secret 

Retrieve a secret value
public function getApiKey(): ?string
{
    return $this->vault->retrieve('my_extension_api_key');
}
Copied!

Vault HTTP client 

The vault provides a PSR-18 compatible HTTP client that can inject secrets into requests without exposing them to your code. Configure authentication with withAuthentication(), then use standard sendRequest().

Via VaultService 

HTTP client via VaultService
use GuzzleHttp\Psr7\Request;
use Netresearch\NrVault\Http\SecretPlacement;

$client = $this->vaultService->http()
    ->withAuthentication('stripe_api_key', SecretPlacement::Bearer);

$request = new Request(
    'POST',
    'https://api.stripe.com/v1/charges',
    ['Content-Type' => 'application/json'],
    json_encode($payload),
);

$response = $client->sendRequest($request);
Copied!
interface VaultHttpClientInterface
Fully qualified name
\Netresearch\NrVault\Crypto\VaultHttpClientInterface

PSR-18 compatible HTTP client with vault-based authentication. Extends \Psr\Http\Client\ClientInterface .

withAuthentication ( string $secretIdentifier, SecretPlacement $placement = SecretPlacement::Bearer, array $options = []) : static

Create a new client instance configured with authentication. Returns an immutable instance - the original is unchanged.

param string $secretIdentifier

Vault identifier for the secret.

param SecretPlacement $placement

How to inject the secret.

param array $options

Additional options (headerName, queryParam, usernameSecret, reason).

Returns

New client instance with authentication configured.

withOAuth ( OAuthConfig $config, string $reason = 'OAuth2 API call') : static

Create a new client instance configured with OAuth 2.0 authentication.

param OAuthConfig $config

OAuth configuration.

param string $reason

Audit log reason.

Returns

New client instance with OAuth configured.

withReason ( string $reason) : static

Create a new client instance with a custom audit reason.

param string $reason

Audit log reason for requests.

Returns

New client instance with reason configured.

sendRequest ( RequestInterface $request) : ResponseInterface

Send an HTTP request (PSR-18 method).

param RequestInterface $request

PSR-7 request.

throws ClientExceptionInterface

If request fails.

Returns

PSR-7 response.

Authentication options 

The withAuthentication() method accepts these options:

headerName
Custom header name (for SecretPlacement::Header, default: X-API-Key).
queryParam
Query parameter name (for SecretPlacement::QueryParam, default: api_key).
bodyField
Body field name (for SecretPlacement::BodyField, default: api_key).
usernameSecret
Separate username secret identifier (for SecretPlacement::BasicAuth).
reason
Reason for access (logged in audit).

SecretPlacement enum 

placement

Authentication placement using SecretPlacement enum:

  • SecretPlacement::Bearer - Bearer token in Authorization header.
  • SecretPlacement::BasicAuth - HTTP Basic Authentication.
  • SecretPlacement::Header - Custom header value.
  • SecretPlacement::QueryParam - Query parameter.
  • SecretPlacement::BodyField - Field in request body.
  • SecretPlacement::OAuth2 - OAuth 2.0 with automatic token refresh.
  • SecretPlacement::ApiKey - X-API-Key header (shorthand).
Authentication examples
use GuzzleHttp\Psr7\Request;
use Netresearch\NrVault\Http\SecretPlacement;

// Bearer authentication
$client = $this->vault->http()
    ->withAuthentication('stripe_api_key', SecretPlacement::Bearer);
$response = $client->sendRequest(
    new Request('POST', 'https://api.stripe.com/v1/charges', [], $body)
);

// Custom header
$client = $this->vault->http()
    ->withAuthentication('api_token', SecretPlacement::Header, [
        'headerName' => 'X-API-Key',
    ]);
$response = $client->sendRequest(
    new Request('GET', 'https://api.example.com/data')
);

// Basic authentication with separate credentials
$client = $this->vault->http()
    ->withAuthentication('service_password', SecretPlacement::BasicAuth, [
        'usernameSecret' => 'service_username',
        'reason' => 'Fetching secure data',
    ]);
$response = $client->sendRequest(
    new Request('GET', 'https://api.example.com/secure')
);

// Query parameter
$client = $this->vault->http()
    ->withAuthentication('api_key', SecretPlacement::QueryParam, [
        'queryParam' => 'key',
    ]);
$response = $client->sendRequest(
    new Request('GET', 'https://maps.example.com/geocode')
);
Copied!

PSR-14 events 

The vault dispatches events during secret operations.

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

Dispatched when a new secret is created.

  • getIdentifier(): The secret identifier.
  • getSecret(): The Secret entity.
  • getActorUid(): User ID who created it.
class SecretAccessedEvent
Fully qualified name
\Netresearch\NrVault\Crypto\SecretAccessedEvent

Dispatched when a secret is read.

  • getIdentifier(): The secret identifier.
  • getActorUid(): User ID who accessed it.
  • getContext(): The secret's context.
class SecretRotatedEvent
Fully qualified name
\Netresearch\NrVault\Crypto\SecretRotatedEvent

Dispatched when a secret is rotated.

  • getIdentifier(): The secret identifier.
  • getNewVersion(): The new version number.
  • getActorUid(): User ID who rotated it.
  • getReason(): The rotation reason.
class SecretDeletedEvent
Fully qualified name
\Netresearch\NrVault\Crypto\SecretDeletedEvent

Dispatched when a secret is deleted.

  • getIdentifier(): The secret identifier.
  • getActorUid(): User ID who deleted it.
  • getReason(): The deletion reason.
class SecretUpdatedEvent
Fully qualified name
\Netresearch\NrVault\Crypto\SecretUpdatedEvent

Dispatched when a secret value is updated (without rotation).

  • getIdentifier(): The secret identifier.
  • getNewVersion(): The new version number.
  • getActorUid(): User ID who updated it.
class MasterKeyRotatedEvent
Fully qualified name
\Netresearch\NrVault\Crypto\MasterKeyRotatedEvent

Dispatched after master key rotation completes.

  • getSecretsReEncrypted(): Number of secrets re-encrypted.
  • getActorUid(): User ID who performed the rotation.
  • getRotatedAt(): DateTimeImmutable of when rotation completed.