Skip to content

Repository files navigation

Opaque

Secrets as PHP value objects. An opaque value does not leak through var_dump, print_r, var_export, json_encode, serialize, a string cast or a reflection-based serializer; disclose() is the one way out. A ciphered value is what may be stored, and a Symfony Serializer bridge ciphers opaque values on their way into a payload — such as gplanchat/durable's journal.

use Gplanchat\Opaque\Opaque;
use function Gplanchat\Opaque\disclose;

final class ApiKey extends Opaque {}

$key = ApiKey::fromString($_ENV['PAYMENT_API_KEY']);
echo $key;                          // **SECRET**
$client->authenticate(disclose($key));

Monorepo:

Package Role PHP
src/Opaque — gplanchat/opaque Opaque, disclose(), Ciphered, the ciphers (SodiumSecretBox, SodiumSealedBox, and two unsecured encodings) and the Keyring that rotates keys. Framework-free, ext-sodium. ≥ 8.2
src/Bridge/Serializer — gplanchat/opaque-bridge-serializer OpaqueNormalizer: Symfony Serializer 6.4 / 7 / 8. ≥ 8.2
root Dev tooling only; installs both by path. ≥ 8.2

The user guide is in documentation/user/. The decisions — why, and what was turned down — are in documentation/adr/: start with OPQ001 and OPQ002.

Development

composer install
composer test        # PHPUnit
composer phpstan     # level 8, no baseline
composer psalm
composer cs:check    # PER-CS 3.0
loop/guardrails/verify.sh   # all of the above, as CI runs them

Contributions follow CLAUDE.md and the working agreements in documentation/wa/: English, TDD, one prise per branch (.worktrees/PRISES.md).

License

MIT — see LICENSE.

About

Opaque value objects for PHP: secrets that do not leak, ciphered storage with key rotation, and a Symfony Serializer bridge (monorepo)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages