PHPackages                             jnativel/sentinel-vault - 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. jnativel/sentinel-vault

ActiveLibrary[Security](/categories/security)

jnativel/sentinel-vault
=======================

A lightweight, self-contained PHP Key Management System (KMS) using XChaCha20-Poly1305 AEAD encryption with per-user DEX keys.

v0.1.3(6mo ago)12MITPHPPHP ^8.2

Since Oct 29Pushed 6mo agoCompare

[ Source](https://github.com/jnativel/sentinel-vault)[ Packagist](https://packagist.org/packages/jnativel/sentinel-vault)[ RSS](/packages/jnativel-sentinel-vault/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (5)Used By (0)

SentinelVault — Secure Key Management and Encryption (KMS)
==========================================================

[](#sentinelvault--secure-key-management-and-encryption-kms)

**SentinelVault** is a standalone PHP class providing a lightweight **Key Management System (KMS)**.
It securely handles encryption, decryption, and user-specific Data Encryption Keys (DEX), all protected by a master key.

---

🔐 Features
----------

[](#-features)

- **XChaCha20-Poly1305 AEAD** encryption (via PHP `libsodium`)
- **Master key** encryption model (`MASTER_KEY_B64`)
- **Per-user Data Encryption Keys (DEX)**, each sealed with the master key
- **Associated Data (AD)** support for contextual encryption
- **Status / Expiration / Metadata** fields for key lifecycle management
- **Key rotation**: re-encrypt DEX with a new master key
- **Rekeying**: regenerate internal DEX keys while preserving metadata

---

🧩 Architecture Overview
-----------------------

[](#-architecture-overview)

```
Master Key (KMS Root)
     │
     ├── DEX Key (per user/context)
     │      - privateKeyB64 (32 bytes)
     │      - associatedData
     │      - exp / status / meta
     │
     └── Encrypted user data (via DEX key)

```

### DEX JSON structure (before encryption)

[](#dex-json-structure-before-encryption)

```
{
  "kty": "DEX",
  "ver": 1,
  "privateKeyB64": "",
  "associatedData": "user:123:scope:profile",
  "created_at": "2025-10-29T12:34:56Z",
  "exp": "2026-01-01T00:00:00Z",
  "status": "ACTIVE",
  "meta": { "label": "Main profile" }
}
```

---

⚙️ Installation
---------------

[](#️-installation)

### Requirements

[](#requirements)

- PHP 8.2+
- `ext-sodium` enabled
- No external dependencies

### Usage

[](#usage)

```
use SentinelVault\SentinelVault;

// Initialize the vault
$vault = (new SentinelVault())
    ->setMasterKeyB64($_ENV['MASTER_KEY_B64']);

// Generate a DEX key for a user
$dex = $vault->createDexKey(
    'dex:user:123:key:main',
    'user:123:scope:profile',
    ['exp' => '2026-01-01T00:00:00Z', 'status' => 'ACTIVE']
);

// Encrypt and decrypt user data
$cipher = $vault->encryptWithDex($dex['dex_blob'], 'dex:user:123:key:main', 'Sensitive Data');
$plain  = $vault->decryptWithDex($dex['dex_blob'], 'dex:user:123:key:main', $cipher);
```

---

🕓 DEX Lifecycle Management
--------------------------

[](#-dex-lifecycle-management)

### Metadata fields

[](#metadata-fields)

FieldTypeDescription`status`string`ACTIVE`, `SUSPENDED`, or `REVOKED``exp`stringISO-8601 UTC expiration date`meta`objectArbitrary metadata (tags, labels, etc.)### Access control

[](#access-control)

When using `encryptWithDex()` or `decryptWithDex()`:

- If `status` is `SUSPENDED` or `REVOKED`, operation fails.
- If `exp` date is in the past, operation fails.

---

🔁 Master Key Rotation
---------------------

[](#-master-key-rotation)

Rotate all stored DEX blobs when the master key changes.

```
$newDexBlob = $vault->rotateDexMasterKey(
    $oldDexBlob,
    'dex:user:123:key:main',
    $_ENV['NEW_MASTER_KEY_B64'],
    'dex:user:123:key:main:v2'
);
```

---

♻️ DEX Rekeying
---------------

[](#️-dex-rekeying)

Regenerate the internal user encryption key while keeping metadata intact.

```
$rekeyedDexBlob = $vault->rekeyDexUserKey($dexBlob, 'dex:user:123:key:main');
```

---

🧪 DEX Metadata Access
---------------------

[](#-dex-metadata-access)

You can safely read non-sensitive information from a DEX without exposing its internal key.

```
$meta = $vault->getDexMeta($dexBlob, 'dex:user:123:key:main');
print_r($meta);
```

---

🧱 Security Design
-----------------

[](#-security-design)

- The **master key** never leaves the environment (`MASTER_KEY_B64` in .env or secret manager).
- Each **DEX** is sealed using AEAD (XChaCha20-Poly1305) with unique **associated data**.
- Each **user data** chunk is encrypted with its own **per-DEX key**, isolated from others.
- AEAD ensures **authentication**: ciphertext tampering causes decryption to fail.
- `status` and `exp` ensure fine-grained key control for suspension and expiration.

---

🧰 Advanced Operations
---------------------

[](#-advanced-operations)

MethodDescription`createDexKey($dexAd, $userAD, $opts)`Create a new DEX with optional metadata`getDexMeta($dexBlob, $dexAd)`Read DEX metadata without revealing the private key`encryptWithDex($dexBlob, $dexAd, $plaintext)`Encrypt data using a DEX`decryptWithDex($dexBlob, $dexAd, $ciphertext)`Decrypt data using a DEX`rotateDexMasterKey($dexBlob, $currentDexAd, $newMasterKeyB64, $newDexAd = null)`Re-encrypt DEX with a new master key`rekeyDexUserKey($dexBlob, $dexAd)`Regenerate internal DEX key---

🧿 Example Workflow
------------------

[](#-example-workflow)

1. **System initialization**

    ```
    $master = SentinelVault::generateMasterKeyB64();
    putenv("MASTER_KEY_B64=$master");
    ```
2. **Create a user DEX**

    ```
    $dex = $vault->createDexKey("dex:user:1:key:default", "user:1:data");
    ```
3. **Encrypt user data**

    ```
    $cipher = $vault->encryptWithDex($dex['dex_blob'], "dex:user:1:key:default", "hello world");
    ```
4. **Rotate master key later**

    ```
    $new = SentinelVault::generateMasterKeyB64();
    $vault->rotateDexMasterKey($dex['dex_blob'], "dex:user:1:key:default", $new);
    ```

---

🧠 Design Principles
-------------------

[](#-design-principles)

- Simple, self-contained, no external dependencies.
- One class = one KMS engine.
- Secure by design: AEAD, zero-copy key handling, context binding via AD.
- Extensible for multi-tenant or multi-service contexts.

---

🧭 Operational Separation &amp; Service Model (Recommended)
----------------------------------------------------------

[](#-operational-separation--service-model-recommended)

For stronger security, **run SentinelVault in an isolated environment**, separate from your main application.

### Why

[](#why)

Running the vault as an independent service ensures that even if your app is compromised, attackers **cannot access the master key** or decrypt sensitive data.
It also allows **independent deployment, scaling, auditing, and key rotation**.

### How

[](#how)

- Deploy SentinelVault as a **dedicated container, host, or microservice**.
- Expose only a **minimal internal API** (private network or mTLS) to handle DEX creation and encryption/decryption.
- Keep the **master key** outside your project files — use environment secrets, HSM, or a managed KMS.
- The main app never stores or reads the master key; it only calls the API.

### Example API endpoints

[](#example-api-endpoints)

```
POST /dex       → create new DEX
POST /encrypt   → encrypt with DEX
POST /decrypt   → decrypt with DEX
POST /rotate    → rotate master key or DEX AD
POST /rekey     → regenerate DEX internal key
GET  /dex/meta  → retrieve DEX metadata

```

### Summary

[](#summary)

Separating SentinelVault from your main stack:

- Prevents direct access to cryptographic materials
- Reduces attack surface and lateral movement risk
- Simplifies auditing, compliance, and recovery

📄 License
---------

[](#-license)

MIT License (c) 2025 Jimmy NATIVEL

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance66

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 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

Every ~0 days

Total

4

Last Release

199d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9a4abb62ae621d3b5d26a9bd1dde980ee0505705aa6c460c7a82fdc21a906abb?d=identicon)[jnativel](/maintainers/jnativel)

---

Top Contributors

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

---

Tags

phpsecuritycryptographyencryptionaeadXchacha20vaultkmskey-managementjnativel

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/jnativel-sentinel-vault/health.svg)

```
[![Health](https://phpackages.com/badges/jnativel-sentinel-vault/health.svg)](https://phpackages.com/packages/jnativel-sentinel-vault)
```

###  Alternatives

[phpseclib/phpseclib

PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.

5.6k434.8M1.3k](/packages/phpseclib-phpseclib)[paragonie/sodium_compat

Pure PHP implementation of libsodium; uses the PHP extension if it exists

934131.6M155](/packages/paragonie-sodium-compat)[poly-crypto/poly-crypto

High-level cryptographic functions that are interoperable between NodeJS and PHP 7.1+

127.8k1](/packages/poly-crypto-poly-crypto)[asymmetricrypt/asymmetricrypt

A simple PHP public key cryptography library

114.1k](/packages/asymmetricrypt-asymmetricrypt)

PHPackages © 2026

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