PHPackages                             tuzelko/yii2-key-storage - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Security](/categories/security)
4. /
5. tuzelko/yii2-key-storage

ActiveYii2-extension[Security](/categories/security)

tuzelko/yii2-key-storage
========================

Named cryptographic key storage with format validation for Yii2 framework

v1.0.0(1mo ago)0109↓72.6%1MITPHPPHP &gt;=8.0CI passing

Since Jun 10Pushed 1mo agoCompare

[ Source](https://github.com/TuzelKO/yii2-key-storage)[ Packagist](https://packagist.org/packages/tuzelko/yii2-key-storage)[ RSS](/packages/tuzelko-yii2-key-storage/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (2)Versions (2)Used By (1)

Yii2 Key Storage extension
==========================

[](#yii2-key-storage-extension)

[![Project Status: Active](https://camo.githubusercontent.com/39c688bf243eeb6d3bfc529dcf3cb27443613deb696c8fa9f49bccf1e63e3bef/68747470733a2f2f7777772e7265706f7374617475732e6f72672f6261646765732f6c61746573742f6163746976652e737667)](https://www.repostatus.org/#active)[![Tests](https://github.com/TuzelKO/yii2-key-storage/actions/workflows/tests.yml/badge.svg)](https://github.com/TuzelKO/yii2-key-storage/actions/workflows/tests.yml)[![Latest Version](https://camo.githubusercontent.com/1641c9cc9eb3859db1bea59bbe640db03a79b6430467023c226f37f8b23a87db/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f74757a656c6b6f2f796969322d6b65792d73746f72616765)](https://packagist.org/packages/tuzelko/yii2-key-storage)[![PHP Version](https://camo.githubusercontent.com/4a11fac9f533e1cb07268993b55e3988604b00b7c5206b19d3dad624784be257/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f74757a656c6b6f2f796969322d6b65792d73746f726167652f706870)](https://packagist.org/packages/tuzelko/yii2-key-storage)[![Total Downloads](https://camo.githubusercontent.com/520046018b177df5a71870a2ead48a776f548963d067c3fbd6439cb368cd3af5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f74757a656c6b6f2f796969322d6b65792d73746f72616765)](https://packagist.org/packages/tuzelko/yii2-key-storage)[![License](https://camo.githubusercontent.com/30c8fee307da912d261837e9b0d1861c4cdd8e97128882ea0ab1608b72bea9e3/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f54757a656c4b4f2f796969322d6b65792d73746f72616765)](https://github.com/TuzelKO/yii2-key-storage/blob/main/LICENSE)

Named cryptographic key storage for the [Yii2](https://www.yiiframework.com/) framework.

Solves one recurring problem: *"give me the raw bytes of key X, taken from env, decoded and validated — and fail loudly at the first use if the key is missing or malformed"*. Encryption keys, signing keys, HMAC secrets, TOTP seeds — all behind one named registry instead of ad-hoc `base64_decode(getenv(...))` calls scattered around the codebase.

Features
--------

[](#features)

- **Named keys** — one registry, keys referenced by name
- **Text sources** — `base64` (standard and url-safe alphabets) or `hex`, typically from env
- **Modular key types** — each format is a small class validating the decoded bytes; ship your own by implementing one interface
- **Fail-fast validation** — wrong length, bad encoding, missing value → `InvalidKeyException` with the key name in the message
- **Interface-first** — consumers depend on `KeyProviderInterface`, not on the concrete storage
- **Memoization** — decode and validation happen once per key per instance
- **No ext requirements** — key-type byte lengths are hardcoded, so describing sodium keys does not require ext-sodium

Requirements
------------

[](#requirements)

- PHP &gt;= 8.0
- yiisoft/yii2 ~2.0

Installation
------------

[](#installation)

```
composer require tuzelko/yii2-key-storage
```

Quick start
-----------

[](#quick-start)

Register the storage in the DI container under the interface, so consumers never know the concrete class:

```
// config/main.php
use tuzelko\yii\keystorage\KeyProviderInterface;
use tuzelko\yii\keystorage\KeyStorage;
use tuzelko\yii\keystorage\types\SodiumSecretboxKey;

'container' => [
    'singletons' => [
        KeyProviderInterface::class => static fn () => new KeyStorage([
            'keys' => [
                'appCrypto' => [
                    'base64' => getenv('APP_CRYPTO_KEY'),
                    'type'   => SodiumSecretboxKey::class,
                ],
            ],
        ]),
    ],
],
```

```
$rawKey = Yii::$container->get(KeyProviderInterface::class)->getRaw('appCrypto');
```

`getRaw()` returns raw binary bytes, ready for `sodium_*` / `hash_hmac` / `openssl_*` calls.

Key configuration
-----------------

[](#key-configuration)

Each entry under `keys` is `name => descriptor`. A descriptor has exactly one source encoding and a mandatory type:

FieldDescription`base64`Base64-encoded key value (standard and url-safe alphabets accepted)`hex`Hex-encoded key value`type``KeyTypeInterface` class name or instance — validates the decoded bytes```
'keys' => [
    'appCrypto'  => ['base64' => getenv('CRYPTO_KEY'),       'type' => SodiumSecretboxKey::class],
    'requestSigning' => ['hex'    => getenv('SIGNING_KEY_HEX'),  'type' => Ed25519SecretKey::class],
    'legacyAes'      => ['base64' => getenv('LEGACY_KEY'),       'type' => new CustomLengthKey(16)],
],
```

Bundled key types
-----------------

[](#bundled-key-types)

TypeValid lengthFor`SodiumSecretboxKey`32 bytes`sodium_crypto_secretbox` (XSalsa20-Poly1305)`Ed25519PublicKey`32 bytes`sodium_crypto_sign` verification`Ed25519SecretKey`64 bytes`sodium_crypto_sign` signing`CustomLengthKey(n)``n` bytesany fixed-length format not shipped with the packageCustom key types
----------------

[](#custom-key-types)

A key type is any class implementing `KeyTypeInterface` — one method, full control over what "valid" means:

```
use tuzelko\yii\keystorage\InvalidKeyException;
use tuzelko\yii\keystorage\types\KeyTypeInterface;

class PemRsaPrivateKey implements KeyTypeInterface
{
    public function validate(string $raw): void
    {
        if (openssl_pkey_get_private($raw) === false) {
            throw new InvalidKeyException('not a valid PEM RSA private key.');
        }
    }
}
```

For plain length checks extend `FixedLengthKey` instead and implement only `length(): int`.

Docker secrets
--------------

[](#docker-secrets)

Keys are always supplied as text via env. If you use Docker secrets, deliver them to env in your entrypoint (the common `*_FILE` pattern) — the storage intentionally does not read files, so there is exactly one secret-loading mechanism and no binary-vs-text file pitfalls.

Error handling
--------------

[](#error-handling)

Every failure throws `tuzelko\yii\keystorage\InvalidKeyException` (extends `RuntimeException`) with the key name in the message:

ConditionMessageUnknown key name`Key "x" is not configured.`Empty / unset env value`Key "x": base64 value is empty or not set.`Bad encoding`Key "x": invalid base64 string.` / `invalid hex string.`Missing source`Key "x" must specify one of: base64, hex.`Missing / wrong type`Key "x" has unknown or missing type; ...`Failed type validation`Key "x": wrong length: expected 32 bytes, got 16.`Running tests
-------------

[](#running-tests)

```
make test
```

Tests run inside Docker (PHP 8.3) with no local setup required.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance90

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/38176435?v=4)[Eugene Frost](/maintainers/TuzelKO)[@TuzelKO](https://github.com/TuzelKO)

---

Top Contributors

[![TuzelKO](https://avatars.githubusercontent.com/u/38176435?v=4)](https://github.com/TuzelKO "TuzelKO (1 commits)")

---

Tags

securitycryptokeyyii2extensionsecretskey-management

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tuzelko-yii2-key-storage/health.svg)

```
[![Health](https://phpackages.com/badges/tuzelko-yii2-key-storage/health.svg)](https://phpackages.com/packages/tuzelko-yii2-key-storage)
```

###  Alternatives

[craftcms/cms

Craft CMS

3.6k3.6M3.2k](/packages/craftcms-cms)[skeeks/cms

SkeekS CMS — control panel and tools based on php framework Yii2

13725.8k63](/packages/skeeks-cms)[nickcv/yii2-encrypter

Openssl Encrypter for Yii2

19680.1k1](/packages/nickcv-yii2-encrypter)[hyperia/yii2-secure-headers

Secure headers for your Yii2 app

21206.7k](/packages/hyperia-yii2-secure-headers)[juliardi/yii2-captcha

Captcha library wrapper for Yii2

168.6k](/packages/juliardi-yii2-captcha)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
