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, prefix, queryParam, bodyField, 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.

withTimeout ( int $seconds) : static

Create a new client instance with a request timeout override. Applies Guzzle's timeout option (total request duration) to every request sent through the returned instance, authenticated or not — use it for long-running API calls that exceed the instance-wide $GLOBALS['TYPO3_CONF_VARS']['HTTP']['timeout'] . Connection establishment (connect_timeout) stays platform-managed.

param int $seconds

Timeout in seconds; non-positive values mean "no override" and fall back to the platform default.

Returns

New client instance with the timeout 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).
prefix
Auth scheme/prefix prepended to the secret (for SecretPlacement::Header ). Use for non-Bearer Authorization: <scheme> <secret> schemes — e.g. 'Key ' for the TYPO3 FAL providers or 'DeepL-Auth-Key ' for DeepL.
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')
);

// Custom Authorization scheme (e.g. DeepL "Authorization: DeepL-Auth-Key <key>")
$client = $this->vault->http()
    ->withAuthentication('deepl_api_key', SecretPlacement::Header, [
        'headerName' => 'Authorization',
        'prefix' => 'DeepL-Auth-Key ',
    ]);
$response = $client->sendRequest(
    new Request('POST', 'https://api-free.deepl.com/v2/translate', [], $body)
);

// 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.