DatabaseSecretStore
in package
implements
WritableSecretStoreInterface
Table of Contents
Interfaces
Constants
- BINARY_ENCODING_PREFIX : mixed = 'base64:'
- DRIVER_NAME : mixed = 'database'
- OPENSSL_CIPHER : mixed = 'aes-256-gcm'
- SODIUM_CIPHER : mixed = 'xchacha20poly1305-ietf'
Properties
- $connection : Connection|null
- $connectionName : string
- $keyName : string
- $keyVersion : string
- $masterKeyName : string
- $masterStore : SecretStoreInterface
- $namespace : string
- $tenantId : string|null
Methods
- __construct() : mixed
- Constructor.
- delete() : void
- Delete a secret value.
- exists() : bool
- Return true if a secret name exists without revealing or decrypting its value.
- get() : SensitiveString|null
- Fetch a secret value.
- list() : array<int, string>
- put() : void
- Store or replace a secret value.
- putIfMissing() : bool
- Store a value only when no active or deleted row already owns the name.
- rotatedAt() : DateTimeImmutable|null
- Return when a secret was last rotated, if known, without revealing the value.
- activeRow() : array<string, mixed>|null
- assertValidName() : void
- Validate a logical secret name.
- associatedData() : string
- decodeBinaryPayload() : string
- Decode binary ciphertext while still accepting legacy raw BLOB values.
- decryptWithKey() : string
- Decrypt a stored value and fail closed on authentication failure.
- dekAssociatedData() : string
- Derive distinct associated data for wrapping the per-secret DEK.
- encodeBinaryPayload() : string
- Store binary ciphertext in a PostgreSQL-safe ASCII representation.
- encryptWithKey() : array{cipher: string, nonce: string, tag: ?string, ciphertext: string}
- ensureKekRow() : void
- Ensure metadata exists for the active logical KEK version.
- isUniqueConstraintViolation() : bool
- Detect portable SQLSTATE values used for unique/integrity conflicts.
- masterKey() : string
- Load and normalize the master KEK to 32 raw bytes.
- nonceLength() : int
- Return nonce size for a supported cipher.
- now() : string
- Return an audit timestamp in UTC-compatible ATOM format.
- platform() : Connection
- Return the platform metadata connection.
- preferredCipher() : string
- Return the cipher used for new encryptions.
- rowByName() : array<string, mixed>|null
- store() : bool
- Encrypt and persist a secret inside one platform transaction.
- tenantConditionSql() : string
- upsertIndexRow() : void
- Keep the non-secret platform index synchronized.
Constants
BINARY_ENCODING_PREFIX
private
mixed
BINARY_ENCODING_PREFIX
= 'base64:'
DRIVER_NAME
private
mixed
DRIVER_NAME
= 'database'
OPENSSL_CIPHER
private
mixed
OPENSSL_CIPHER
= 'aes-256-gcm'
SODIUM_CIPHER
private
mixed
SODIUM_CIPHER
= 'xchacha20poly1305-ietf'
Properties
$connection
private
Connection|null
$connection
= null
$connectionName read-only
private
string
$connectionName
= 'platform'
$keyName read-only
private
string
$keyName
= 'platform-secrets'
$keyVersion read-only
private
string
$keyVersion
= 'v1'
$masterKeyName read-only
private
string
$masterKeyName
$masterStore read-only
private
SecretStoreInterface
$masterStore
$namespace read-only
private
string
$namespace
= 'platform'
$tenantId read-only
private
string|null
$tenantId
= null
Methods
__construct()
Constructor.
public
__construct(SecretStoreInterface $masterStore, string $masterKeyName[, string $connectionName = 'platform' ][, string $namespace = 'platform' ][, string|null $tenantId = null ][, string $keyName = 'platform-secrets' ][, string $keyVersion = 'v1' ][, Connection|null $connection = null ]) : mixed
Parameters
- $masterStore : SecretStoreInterface
-
Store that provides the master KEK
- $masterKeyName : string
-
Master KEK secret name
- $connectionName : string = 'platform'
-
CakePHP connection name for platform metadata
- $namespace : string = 'platform'
-
Logical secret namespace
- $tenantId : string|null = null
-
Optional tenant scope
- $keyName : string = 'platform-secrets'
-
Logical KEK name recorded with encrypted rows
- $keyVersion : string = 'v1'
-
Logical KEK version recorded with encrypted rows
- $connection : Connection|null = null
-
Optional injected connection for tests
delete()
Delete a secret value.
public
delete(string $name) : void
Parameters
- $name : string
-
Secret name
Tags
exists()
Return true if a secret name exists without revealing or decrypting its value.
public
exists(string $name) : bool
Parameters
- $name : string
Tags
Return values
boolget()
Fetch a secret value.
public
get(string $name) : SensitiveString|null
Parameters
- $name : string
-
Secret name
Tags
Return values
SensitiveString|nulllist()
public
list([string $prefix = '' ]) : array<int, string>
Parameters
- $prefix : string = ''
Tags
Return values
array<int, string> —Secret names only; never values.
put()
Store or replace a secret value.
public
put(string $name, SensitiveString $value) : void
Parameters
- $name : string
-
Secret name
- $value : SensitiveString
-
Secret value
Tags
putIfMissing()
Store a value only when no active or deleted row already owns the name.
public
putIfMissing(string $name, SensitiveString $value) : bool
The unique name constraint closes the race between the existence check and insert. A deleted row is a tombstone and deliberately prevents stale legacy material from reviving a removed secret.
Parameters
- $name : string
- $value : SensitiveString
Return values
bool —True when the value was inserted, false when the name was already reserved
rotatedAt()
Return when a secret was last rotated, if known, without revealing the value.
public
rotatedAt(string $name) : DateTimeImmutable|null
Parameters
- $name : string
-
Secret name
Tags
Return values
DateTimeImmutable|nullactiveRow()
private
activeRow(string $name) : array<string, mixed>|null
Parameters
- $name : string
Return values
array<string, mixed>|nullassertValidName()
Validate a logical secret name.
private
assertValidName(string $name) : void
Parameters
- $name : string
associatedData()
private
associatedData(array<string, mixed> $row) : string
Parameters
- $row : array<string, mixed>
Return values
stringdecodeBinaryPayload()
Decode binary ciphertext while still accepting legacy raw BLOB values.
private
decodeBinaryPayload(mixed $payload) : string
Parameters
- $payload : mixed
Return values
stringdecryptWithKey()
Decrypt a stored value and fail closed on authentication failure.
private
decryptWithKey(string $cipher, string $nonce, string $tag, string $ciphertext, string $aad, string $key) : string
Parameters
- $cipher : string
- $nonce : string
- $tag : string
- $ciphertext : string
- $aad : string
- $key : string
Return values
stringdekAssociatedData()
Derive distinct associated data for wrapping the per-secret DEK.
private
dekAssociatedData(string $secretAssociatedData) : string
Parameters
- $secretAssociatedData : string
Return values
stringencodeBinaryPayload()
Store binary ciphertext in a PostgreSQL-safe ASCII representation.
private
encodeBinaryPayload(string $payload) : string
Parameters
- $payload : string
Return values
stringencryptWithKey()
private
encryptWithKey(string $plaintext, string $aad, string $key) : array{cipher: string, nonce: string, tag: ?string, ciphertext: string}
Parameters
- $plaintext : string
- $aad : string
- $key : string
Return values
array{cipher: string, nonce: string, tag: ?string, ciphertext: string}ensureKekRow()
Ensure metadata exists for the active logical KEK version.
private
ensureKekRow(string $now) : void
Parameters
- $now : string
isUniqueConstraintViolation()
Detect portable SQLSTATE values used for unique/integrity conflicts.
private
isUniqueConstraintViolation(Throwable $exception) : bool
Parameters
- $exception : Throwable
Return values
boolmasterKey()
Load and normalize the master KEK to 32 raw bytes.
private
masterKey() : string
Return values
stringnonceLength()
Return nonce size for a supported cipher.
private
nonceLength(string $cipher) : int
Parameters
- $cipher : string
Return values
intnow()
Return an audit timestamp in UTC-compatible ATOM format.
private
now() : string
Return values
stringplatform()
Return the platform metadata connection.
private
platform() : Connection
Return values
ConnectionpreferredCipher()
Return the cipher used for new encryptions.
private
preferredCipher() : string
Return values
stringrowByName()
private
rowByName(string $name) : array<string, mixed>|null
Parameters
- $name : string
Return values
array<string, mixed>|nullstore()
Encrypt and persist a secret inside one platform transaction.
private
store(string $name, SensitiveString $value, bool $onlyIfMissing) : bool
Parameters
- $name : string
- $value : SensitiveString
- $onlyIfMissing : bool
Return values
booltenantConditionSql()
private
tenantConditionSql(array<int, mixed> &$conditions) : string
Parameters
- $conditions : array<int, mixed>
Return values
stringupsertIndexRow()
Keep the non-secret platform index synchronized.
private
upsertIndexRow(string $name, string $now) : void
Parameters
- $name : string
- $now : string