@lanonasis/security-sdk
v1.0.5
Published
Centralized security and encryption SDK for LanOnasis ecosystem
Downloads
74
Maintainers
Readme
@lanonasis/security-sdk
Centralized Security and Encryption SDK for the Lanonasis/Onasis Ecosystem.
Purpose
This SDK provides a unified, secure encryption layer used across all Onasis services:
- MCP Router - Encrypt user credentials for third-party services
- API Gateway - Secure API key storage and validation
- IDE Extensions - Secure token storage
- SDK/CLI - Credential management
- Dashboard - Sensitive data encryption
Features
- ✅ AES-256-GCM Encryption - Industry-standard authenticated encryption
- ✅ Key Derivation - HKDF and PBKDF2 support
- ✅ Key Rotation - Seamless credential rotation
- ✅ Secure Hashing - Password and token hashing
- ✅ API Key Generation - Secure random key generation
- ✅ Data Sanitization - Safe logging of sensitive data
Installation
# In monorepo (workspace)
bun add @lanonasis/security-sdk
# External (npm registry)
npm install @lanonasis/security-sdkUsage
Basic Encryption/Decryption
import { SecuritySDK } from "@lanonasis/security-sdk";
// Initialize with master key
const security = new SecuritySDK(process.env.ONASIS_MASTER_KEY);
// Encrypt user credentials
const encrypted = security.encrypt(
{ stripe_key: "sk_live_abc123" },
"user_123_stripe" // context for key derivation
);
// Store encrypted.encrypted, encrypted.iv, encrypted.authTag, encrypted.keyId in database
// Later, decrypt
const decrypted = security.decryptJSON(encrypted, "user_123_stripe");
console.log(decrypted.stripe_key); // 'sk_live_abc123'Singleton Pattern
import { getSecuritySDK } from "@lanonasis/security-sdk";
// Get singleton instance
const security = getSecuritySDK();
const encrypted = security.encrypt("sensitive-data", "context");Key Rotation
// Rotate credentials (generates new key)
const newEncrypted = security.rotate(oldEncrypted, "user_123_stripe");Hashing & Validation
// Hash password
const hashed = security.hash("user-password");
// Verify password
const isValid = security.verifyHash("user-password", hashed); // trueAPI Key Generation
// Generate API key
const apiKey = security.generateAPIKey("onasis"); // 'onasis_abc123...'
// Generate random token
const token = security.generateToken(32); // 64 hex charactersHash Utilities (API Key Hashing)
For SHA-256 hashing of API keys (separate from password hashing):
import {
hashApiKey,
hashApiKeyBrowser,
ensureApiKeyHash,
ensureApiKeyHashBrowser,
verifyApiKey,
generateApiKey,
isSha256Hash
} from "@lanonasis/security-sdk/hash-utils";
// Hash API key (Node.js/server-side)
const hash = hashApiKey("lns_abc123..."); // Returns 64-char hex string
// Hash API key (Browser/async)
const hash = await hashApiKeyBrowser("lns_abc123...");
// Normalize (hash if needed, leave hash as-is if already hashed)
const normalized = ensureApiKeyHash("lns_abc123..."); // Always returns hash
const normalized = ensureApiKeyHash("a".repeat(64)); // Returns lowercase hash
// Verify API key against stored hash (constant-time comparison)
const isValid = verifyApiKey("lns_abc123...", storedHash); // true/false
// Generate secure API key
const apiKey = generateApiKey(); // 'lns_...' format
// Check if value is already a hash
const isHash = isSha256Hash(value); // true if 64-char hex stringData Sanitization
// Sanitize for logging
const sanitized = security.sanitize("sk_live_abc123def456"); // 'sk_l...f456'Environment Variables
# Required: 32-byte (64 hex characters) master key
ONASIS_MASTER_KEY=your_64_character_hex_key
# Alternative name (for backward compatibility)
VSECURE_MASTER_KEY=your_64_character_hex_keyGenerate Master Key
import { SecuritySDK } from "@lanonasis/security-sdk";
// Generate a new master key (do this once, store securely)
const masterKey = SecuritySDK.generateMasterKey();
console.log(masterKey); // 64 hex charactersAPI Reference
SecuritySDK
Constructor
new SecuritySDK(masterKeyHex?: string)Methods
Encryption
encrypt(data, context, options?)- Encrypt datadecrypt(encryptedData, context)- Decrypt datadecryptJSON<T>(encryptedData, context)- Decrypt and parse JSONrotate(oldEncrypted, context, newData?)- Rotate encryption
Hashing
hash(data, salt?)- Create secure hashverifyHash(data, hashedData)- Verify hashgenerateToken(bytes?)- Generate random tokengenerateAPIKey(prefix?)- Generate API key
Utilities
sanitize(data, showChars?)- Sanitize for loggingisValidEncryptedData(data)- Validate encrypted data structure
Static
SecuritySDK.generateMasterKey()- Generate new master key
Security Best Practices
Master Key Storage
- Store master key in secure environment variables
- Never commit master key to version control
- Rotate master key periodically
- Use different keys for dev/staging/production
Context Usage
- Use unique context per user/service combination
- Example:
user_${userId}_${serviceKey} - This ensures key isolation
Key Rotation
- Rotate credentials regularly
- Use the
rotate()method for seamless rotation - Keep old encrypted data until rotation complete
Logging
- Always use
sanitize()before logging sensitive data - Never log decrypted credentials
- Use structured logging with sanitized fields
- Always use
Integration Examples
MCP Router
import { getSecuritySDK } from "@lanonasis/security-sdk";
const security = getSecuritySDK();
// Encrypt user's Stripe key
const encrypted = security.encrypt(
{ secret_key: userStripeKey },
`user_${userId}_stripe`
);
// Store in database
await db.insert("user_mcp_services", {
user_id: userId,
service_key: "stripe",
encrypted_credentials: JSON.stringify(encrypted),
});
// Later, decrypt for use
const encryptedData = JSON.parse(row.encrypted_credentials);
const credentials = security.decryptJSON(
encryptedData,
`user_${userId}_stripe`
);Key Manager Service
import { getSecuritySDK } from "@lanonasis/security-sdk";
const security = getSecuritySDK();
// Store vendor API key
const encrypted = security.encrypt(apiKey, `vendor_${vendorName}`);
// Retrieve and decrypt
const decrypted = security.decrypt(encrypted, `vendor_${vendorName}`);Migration from Old Encryption
If you have existing encrypted data using the old key-manager encryption:
// Old format (from key-manager/server.js)
const oldEncrypted = {
encrypted: "...",
iv: "...",
authTag: "...",
};
// Decrypt with old method, re-encrypt with new SDK
const security = new SecuritySDK();
// ... decrypt old data ...
const newEncrypted = security.encrypt(decryptedData, context);Testing
bun testLicense
MIT
Support
For issues or questions, contact the Onasis security team.
