Lightweight envelope-encryption service: your own data keys, wrapped by a master key that never leaves the server, with rotation and a complete audit trail.
Instead of encrypting your data directly with the master key, the platform generates a random data key (32 bytes) for each of your keys. Your data is encrypted with the data key (AES-256-GCM), and the data key itself is encrypted by the master key and stored wrapped. Result: the master key only ever wraps keys and never touches your data — the same principle used by major cloud encryption systems.
Every key belongs to your account alone. You can create keys, rotate them (a new data key version, the old one kept so old data still decrypts), and disable them any time. A disabled key refuses new encryptions but can still decrypt — you always recover your data.
Every operation (create, encrypt, decrypt, rotate, disable) is logged with the time and IP address. The log carries metadata only — no keys, no ciphertexts, no decrypted data.
| Method | Path | Access | Description |
|---|---|---|---|
POST | /api/kms/keys | Customer account | Create a new data key |
POST | /api/kms/encrypt | Customer account | Encrypt text (up to 64KB) — refused when the key is disabled |
POST | /api/kms/decrypt | Customer account | Decrypt an envelope — works even for disabled keys (recovery) |
POST | /api/kms/rotate | Customer account | Rotate: new data-key version, old one kept for decrypting |
POST | /api/kms/disable | Customer account | Disable the key (blocks new encryptions only) |
GET | /api/kms/keys | Customer account | Your keys — metadata only, never wrapped keys |
// Node.js — create a key, encrypt, decrypt (customer session cookie)
const base = 'https://securecelleouatine.com';
const k = await (await fetch(base + '/api/kms/keys', { method: 'POST' })).json();
const keyId = k.key_id; // ek_...
const enc = await (await fetch(base + '/api/kms/encrypt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key_id: keyId, plaintext_b64: Buffer.from('secret').toString('base64') })
})).json();
// enc.envelope = { v, iv, ct, tag } — store it, it only decrypts with this key
const dec = await (await fetch(base + '/api/kms/decrypt', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key_id: keyId, envelope: enc.envelope })
})).json();
console.log(Buffer.from(dec.plaintext_b64, 'base64').toString()); // 'secret'