Sentinel Core API
The identity-sentinel-core.js module provides the cryptographic foundation for SAP identity management. It handles sealing (encryption) and unsealing (decryption) of identity data.
Installation
Section titled “Installation”No installation required—uses Node.js built-in crypto module.
const { sealIdentity, unsealIdentity } = require('./src/identity-sentinel-core.js');API Reference
Section titled “API Reference”sealIdentity(key, data)
Section titled “sealIdentity(key, data)”Encrypts identity data into a sealed backup artifact.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | Buffer | Yes | Master passphrase or key material |
data | object | string | Buffer | Yes | Data to encrypt |
Returns
Section titled “Returns”SealedBackup object:
interface SealedBackup { header: { format: "IdentitySentinel/SealedBackup"; formatVersion: number; createdAt: string; // ISO 8601 timestamp cipher: { name: "aes-256-gcm" }; kdf: { name: "scrypt"; N: number; // CPU/memory cost (default: 32768) r: number; // Block size (default: 8) p: number; // Parallelization (default: 1) keyLen: number; // Key length (default: 32) }; saltB64: string; // Base64-encoded 16-byte salt ivB64: string; // Base64-encoded 12-byte IV contentType: string; // MIME type of original data }; ciphertextB64: string; // Base64-encoded encrypted data authTagB64: string; // Base64-encoded 16-byte auth tag}Content Type Detection
Section titled “Content Type Detection”| Input Type | Detected contentType |
|---|---|
Buffer | application/octet-stream |
string | text/plain; charset=utf-8 |
object | application/json; charset=utf-8 |
Example
Section titled “Example”const { sealIdentity } = require('./src/identity-sentinel-core.js');
// Seal JSON dataconst identityData = { name: "my-agent", keys: { operational: "..." }, created: "2026-02-06"};
const sealed = sealIdentity("my-master-passphrase", identityData);
console.log(sealed.header.format);// "IdentitySentinel/SealedBackup"
console.log(sealed.header.contentType);// "application/json; charset=utf-8"
// Save to fileconst fs = require('fs');fs.writeFileSync('backup.json', JSON.stringify(sealed, null, 2));unsealIdentity(key, sealedBackup)
Section titled “unsealIdentity(key, sealedBackup)”Decrypts a sealed backup and returns the original data.
Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
key | string | Buffer | Yes | Same key used for sealing |
sealedBackup | SealedBackup | string | Yes | Sealed backup object or JSON string |
Returns
Section titled “Returns”UnsealResult object:
interface UnsealResult { header: SealedBackup['header']; // Original header raw: Buffer; // Raw decrypted bytes data: object | string | Buffer; // Parsed data based on contentType}Data Parsing
Section titled “Data Parsing”contentType | data Type |
|---|---|
application/json* | Parsed JSON object |
text/* | UTF-8 string |
| Other | Raw Buffer |
Example
Section titled “Example”const { unsealIdentity } = require('./src/identity-sentinel-core.js');const fs = require('fs');
// Read sealed backupconst sealedJson = fs.readFileSync('backup.json', 'utf8');
// Unsealconst { data, header, raw } = unsealIdentity("my-master-passphrase", sealedJson);
console.log(data);// { name: "my-agent", keys: {...}, created: "2026-02-06" }
console.log(header.createdAt);// "2026-02-06T12:00:00.000Z"
console.log(raw.length);// 123 (bytes)Error Handling
Section titled “Error Handling”try { const result = unsealIdentity(wrongKey, sealed);} catch (e) { // Common errors: // - "Bad format" - Not a valid sealed backup // - "Unsupported formatVersion" - Version mismatch // - "Unsupported cipher" - Unknown encryption algorithm // - [Node.js crypto error] - Wrong key or corrupted data console.error('Unseal failed:', e.message);}CLI Reference
Section titled “CLI Reference”Encrypt data from file or stdin.
node src/identity-sentinel-core.js seal \ --key <passphrase> \ [--in <input-file>] \ [--out <output-file>]| Option | Required | Default | Description |
|---|---|---|---|
--key | Yes* | $IDENTITY_KEY | Master passphrase |
--in | No | stdin | Input file path |
--out | No | stdout | Output file path |
Examples:
# From file to filenode src/identity-sentinel-core.js seal \ --key "passphrase" \ --in identity.json \ --out sealed.json
# From stdin to stdoutecho '{"name":"agent"}' | node src/identity-sentinel-core.js seal --key "pass"
# Using environment variableexport IDENTITY_KEY="passphrase"node src/identity-sentinel-core.js seal --in identity.json --out sealed.jsonunseal
Section titled “unseal”Decrypt a sealed backup and output plaintext.
node src/identity-sentinel-core.js unseal \ --key <passphrase> \ --in <sealed-file>| Option | Required | Default | Description |
|---|---|---|---|
--key | Yes* | $IDENTITY_KEY | Master passphrase |
--in | Yes | - | Sealed backup file |
Output:
- JSON data: Pretty-printed JSON
- Text data: UTF-8 string
- Binary data: Base64-encoded
Examples:
# Unseal to stdoutnode src/identity-sentinel-core.js unseal --key "pass" --in sealed.json
# Unseal to filenode src/identity-sentinel-core.js unseal --key "pass" --in sealed.json > recovered.json
# Pipe to jqnode src/identity-sentinel-core.js unseal --key "pass" --in sealed.json | jq '.name'verify
Section titled “verify”Verify a sealed backup is valid without extracting content.
node src/identity-sentinel-core.js verify \ --key <passphrase> \ --in <sealed-file>| Option | Required | Default | Description |
|---|---|---|---|
--key | Yes* | $IDENTITY_KEY | Master passphrase |
--in | Yes | - | Sealed backup file |
Output:
- Success:
OK formatVersion=1 createdAt=2026-02-06T...(exit 0) - Failure:
VERIFY_FAILED: <reason>(exit 1)
Examples:
# Verify backupnode src/identity-sentinel-core.js verify --key "pass" --in sealed.json# OK formatVersion=1 createdAt=2026-02-06T12:00:00.000Z
# Use in scriptsif node src/identity-sentinel-core.js verify --key "$KEY" --in backup.json; then echo "Backup is valid"else echo "Backup is corrupted or key is wrong"fiCryptographic Details
Section titled “Cryptographic Details”Key Derivation (Scrypt)
Section titled “Key Derivation (Scrypt)”Master Key (passphrase) │ ▼ ┌─────────┐ │ Scrypt │ ◄── Salt (16 random bytes) │ │ │ N=32768 │ Cost parameter (2^15) │ r=8 │ Block size │ p=1 │ Parallelization └────┬────┘ │ ▼Derived Key (32 bytes / 256 bits)Encryption (AES-256-GCM)
Section titled “Encryption (AES-256-GCM)”Derived Key ──────────────────┐ │IV (12 random bytes) ─────────┤ ▼ ┌─────────┐Plaintext ─────────────►│AES-256 │────► Ciphertext │ GCM │Header (AAD) ──────────►│ │────► Auth Tag (16 bytes) └─────────┘Security Properties
Section titled “Security Properties”| Property | Guarantee |
|---|---|
| Confidentiality | AES-256 encryption |
| Integrity | GCM authentication tag |
| Authenticity | AEAD binds header to ciphertext |
| Key stretching | Scrypt resists brute force |
| Randomness | Fresh salt + IV per seal operation |
Error Reference
Section titled “Error Reference”| Error | Cause | Solution |
|---|---|---|
Missing --key | No key provided | Add --key or set $IDENTITY_KEY |
Bad format | Input isn’t sealed backup | Check file is valid sealed backup JSON |
Unsupported formatVersion | Version mismatch | Use compatible library version |
Unsupported cipher | Unknown algorithm | Use compatible library version |
Unsupported kdf | Unknown KDF | Use compatible library version |
| Crypto error | Wrong key or corruption | Verify key; check file integrity |
Best Practices
Section titled “Best Practices”// ✅ Use strong passphrasessealIdentity("correct-horse-battery-staple-quantum", data);
// ✅ Handle errorstry { const result = unsealIdentity(key, backup);} catch (e) { console.error('Failed to unseal:', e.message); process.exit(1);}
// ✅ Verify before trustingconst { header } = unsealIdentity(key, backup);if (header.formatVersion !== 1) { throw new Error('Unsupported version');}// ❌ Weak passphrasesealIdentity("password", data);
// ❌ Ignoring errorsconst result = unsealIdentity(key, backup); // May throw!
// ❌ Storing passphrase with backupfs.writeFileSync('backup.json', JSON.stringify({ key, sealed })); // NO!