0.1.3 • Published 1 month ago
@synet/keys v0.1.3
@synet/keys
Secure key management system for the Synet ecosystem.
Installation
npm install @synet/keys
Features
- Unified storage for multiple key types (RSA, Ed25519, WireGuard)
- Clean architecture with repository pattern
- File-based and in-memory storage options
- Future support for encrypted key storage
- Strong error handling with Result pattern
- Minimal dependencies
Usage
Basic Usage
import { createKeyService, StorageType } from '@synet/keys';
// Create a key service with file storage
const keyService = createKeyService();
const keyId = 'key-12345';
// Or if you're bored, use value object KeyId
// keyId = KeyId.generateNew().toString();
// Save a key
const keyResult = await keyService.saveKey({
id: keyId,
name: 'my-gateway',
description: 'Gateway at Data Center',
createdAt: new Date().toISOString(),
keys: {
rsa: {
privateKey: '-----BEGIN PRIVATE KEY-----\n...',
publicKey: '-----BEGIN PUBLIC KEY-----\n...'
},
wireguard: {
privateKey: 'ABC123...',
publicKey: 'DEF456...'
}
},
metadata: {
environment: 'production'
}
});
if (keyResult.isSuccess) {
console.log('Key saved successfully');
} else {
console.error(`Failed to save key: ${keyResult.errorMessage}`);
}
Retrieving Keys
// Get a key by name
const keyResult = await keyService.getKey('my-gateway');
if (keyResult.isSuccess && keyResult.value) {
console.log('Retrieved key:', keyResult.value);
} else {
console.error('Key not found');
}
// Get a specific key pair
const rsaKeyResult = await keyService.getKeyPair('my-gateway', 'rsa');
if (rsaKeyResult.isSuccess && rsaKeyResult.value) {
const { privateKey, publicKey } = rsaKeyResult.value;
console.log('RSA public key:', publicKey);
}
Listing All Keys
const keysResult = await keyService.getKeys();
if (keysResult.isSuccess) {
console.log(`Found ${keysResult.value.length} keys`);
// List all key names
for (const key of keysResult.value) {
console.log(`- ${key.name}: ${key.description || 'No description'}`);
console.log(` Key types: ${Object.keys(key.keys).join(', ')}`);
}
}
Configuration Options
Using @synet/logger package
import { createKeyService, StorageType } from '@synet/keys';
import { getLogger } from '@synet/logger';
// Create with custom storage location and logger
const keyService = createKeyService(
StorageType.FILE,
{
configDir: '/custom/storage/path',
// Future option: encryptionKey: 'password123'
},
getLogger('Keys')
);
// Use in-memory storage (for testing)
const memoryKeyService = createKeyService(StorageType.MEMORY);
Integration with Existing Systems
Using @synet/core package
import { createKeyService } from '@synet/keys';
import { generateKeyPair } from '@synet/core';
async function setupNewService(serviceName: string) {
const keyService = createKeyService();
// Generate RSA and WireGuard keys with @synet/core
const rsaKeys = generateKeyPair('rsa');
const wireguardKeys = generateKeyPair('wireguard');
// Save as a new key
await keyService.saveKey({
id: `service-${Date.now()}`,
name: serviceName,
description: `Service key for ${serviceName}`,
createdAt: new Date().toISOString(),
keys: {
rsa: rsaKeys,
wireguard: wireguardKeys
},
metadata: {
serviceId: serviceName
}
});
return { rsaKeys, wireguardKeys };
}
API Reference
Storage Types
enum StorageType {
FILE = "file", // Persistent file storage
MEMORY = "memory", // In-memory storage (for testing)
ENCRYPTED = "encrypted" // Future: Encrypted storage
}
KeyService Methods
Method | Description |
---|---|
getKey(id: string) | Get a key by ID or name |
getKeys() | Get all keys |
getKeyPair(id: string, type: KeyType) | Get a specific key pair by type |
saveKey(key: Key) | Save a key |
deleteKey(id: string) | Delete a key |
keyExists(id: string) | Check if a key exists |
migrateKeys(keys: Keys) | Migrate legacy keys to new format |
Types
export interface KeyPair {
privateKey: string;
publicKey: string;
}
export type Keys = {
rsa?: KeyPair;
ed25519?: KeyPair;
wireguard?: KeyPair;
};
/**
* Represents all possible key data
*/
export interface Key {
id: string;
name: string;
description?: string;
createdAt: string;
keys: Keys;
metadata?: Record<string, unknown>;
}
Architecture
This package follows clean architecture principles:
- Domain Layer: Key entities, interfaces, and repository contracts
- Application Layer: KeyService for business logic and operations
- Infrastructure Layer: Storage implementations (file-based, in-memory)
Development
# Install dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm run coverage
# Build the package
npm run build
License
MIT
Keywords
synet, keys manager, the future is not set, Synthetism, Synthetic Minds