doc: update for latest changes
This commit is contained in:
parent
d9d2ec98db
commit
3b1792e613
2 changed files with 77 additions and 17 deletions
45
README.md
45
README.md
|
|
@ -81,8 +81,10 @@ console.log(response.choices[0].message.content);
|
|||
- **Automatic key loading**: Existing keys are loaded automatically from `client_keys/` directory (Node.js only)
|
||||
- **No manual intervention required**: The library handles key management automatically
|
||||
- **Optional persistence**: Keys can be saved to `client_keys/` directory for reuse across sessions (Node.js only)
|
||||
- **Password protection**: Optional password encryption for private keys (recommended for production)
|
||||
- **Password protection**: Optional password encryption for private keys (minimum 8 characters required)
|
||||
- **Secure permissions**: Private keys stored with restricted permissions (600 - owner-only access)
|
||||
- **Automatic key rotation**: Keys are rotated on a configurable interval (default: 24 hours) to limit fingerprint lifetime
|
||||
- **Explicit lifecycle management**: Call `dispose()` to immediately zero in-memory key material and stop the rotation timer
|
||||
|
||||
### Secure Memory Protection
|
||||
|
||||
|
|
@ -242,11 +244,38 @@ await client.loadKeys(
|
|||
);
|
||||
```
|
||||
|
||||
### Resource Management
|
||||
|
||||
Always call `dispose()` when finished to zero key material and stop the background rotation timer:
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
baseUrl: 'https://api.nomyo.ai:12434',
|
||||
keyRotationInterval: 3600000, // rotate every hour
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await client.create({ model: 'Qwen/Qwen3-0.6B', messages: [...] });
|
||||
console.log(response.choices[0].message.content);
|
||||
} finally {
|
||||
client.dispose();
|
||||
}
|
||||
```
|
||||
|
||||
To disable key rotation entirely (e.g. short-lived scripts):
|
||||
|
||||
```javascript
|
||||
const client = new SecureChatCompletion({
|
||||
baseUrl: 'https://api.nomyo.ai:12434',
|
||||
keyRotationInterval: 0, // disabled
|
||||
});
|
||||
```
|
||||
|
||||
## 🧪 Platform Support
|
||||
|
||||
### Node.js
|
||||
|
||||
- **Minimum version**: Node.js 15+ (for `crypto.webcrypto`)
|
||||
- **Minimum version**: Node.js 14.17+
|
||||
- **Recommended**: Node.js 18 LTS or later
|
||||
- **Key storage**: File system (`client_keys/` directory)
|
||||
- **Security**: Full implementation with automatic key persistence
|
||||
|
|
@ -273,6 +302,11 @@ new SecureChatCompletion(config?: {
|
|||
allowHttp?: boolean; // Default: false
|
||||
apiKey?: string; // Default: undefined
|
||||
secureMemory?: boolean; // Default: true
|
||||
timeout?: number; // Request timeout ms. Default: 60000
|
||||
debug?: boolean; // Enable verbose logging. Default: false
|
||||
keyRotationInterval?: number; // Key rotation ms. 0 = disabled. Default: 86400000 (24h)
|
||||
keyRotationDir?: string; // Directory for rotated keys. Default: 'client_keys'
|
||||
keyRotationPassword?: string; // Password for rotated key files
|
||||
})
|
||||
```
|
||||
|
||||
|
|
@ -280,6 +314,7 @@ new SecureChatCompletion(config?: {
|
|||
|
||||
- `create(request: ChatCompletionRequest): Promise<ChatCompletionResponse>`
|
||||
- `acreate(request: ChatCompletionRequest): Promise<ChatCompletionResponse>` (alias)
|
||||
- `dispose(): void` — zero key material and stop rotation timer
|
||||
|
||||
### SecureCompletionClient
|
||||
|
||||
|
|
@ -293,6 +328,11 @@ new SecureCompletionClient(config?: {
|
|||
allowHttp?: boolean; // Default: false
|
||||
secureMemory?: boolean; // Default: true
|
||||
keySize?: 2048 | 4096; // Default: 4096
|
||||
timeout?: number; // Request timeout ms. Default: 60000
|
||||
debug?: boolean; // Enable verbose logging. Default: false
|
||||
keyRotationInterval?: number; // Key rotation ms. 0 = disabled. Default: 86400000 (24h)
|
||||
keyRotationDir?: string; // Directory for rotated keys. Default: 'client_keys'
|
||||
keyRotationPassword?: string; // Password for rotated key files
|
||||
})
|
||||
```
|
||||
|
||||
|
|
@ -304,6 +344,7 @@ new SecureCompletionClient(config?: {
|
|||
- `encryptPayload(payload: object): Promise<ArrayBuffer>`
|
||||
- `decryptResponse(encrypted: ArrayBuffer, payloadId: string): Promise<object>`
|
||||
- `sendSecureRequest(payload: object, payloadId: string, apiKey?: string): Promise<object>`
|
||||
- `dispose(): void` — zero key material and stop rotation timer
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -53,18 +53,28 @@ NOMYO.js implements end-to-end encryption for OpenAI-compatible chat completions
|
|||
- Automatic key generation on first use
|
||||
- File-based persistence (Node.js)
|
||||
- In-memory keys (browsers)
|
||||
- Password protection via PBKDF2 + AES-256-CBC
|
||||
- Password protection via PBKDF2 + AES-256-CBC (minimum 8-character password enforced)
|
||||
- Automatic periodic key rotation (default: 24 hours, configurable, or disabled with `keyRotationInterval: 0`)
|
||||
- `dispose()` method severs in-memory key references and cancels the rotation timer
|
||||
|
||||
4. **Transport Security**
|
||||
- HTTPS enforcement (with warnings for HTTP)
|
||||
- HTTPS enforcement using proper URL parsing (`new URL()`) — not string prefix matching
|
||||
- Certificate validation (browsers/Node.js)
|
||||
- Optional HTTP for local development (explicit opt-in)
|
||||
- API key validated to reject CR/LF characters (prevents HTTP header injection)
|
||||
- Server error detail truncated to 100 printable characters (prevents log injection)
|
||||
|
||||
5. **Memory Protection (Pure JavaScript)**
|
||||
- Immediate zeroing of sensitive buffers
|
||||
- Context managers for automatic cleanup
|
||||
- Context managers for automatic cleanup (`SecureByteContext`) with guarded `finally` blocks
|
||||
- Intermediate crypto buffers (password bytes, salt, IV) wrapped in `SecureByteContext` during key encryption
|
||||
- HTTP request body (`ArrayBuffer`) zeroed after data is handed to the socket
|
||||
- Best-effort memory management
|
||||
|
||||
6. **Response Integrity**
|
||||
- Decrypted response validated against required `ChatCompletionResponse` schema fields before use
|
||||
- Generic error messages from all crypto operations (no internal engine details leaked)
|
||||
|
||||
### ⚠️ Limitations (Pure JavaScript)
|
||||
|
||||
1. **No OS-Level Memory Locking**
|
||||
|
|
@ -94,9 +104,10 @@ NOMYO.js implements end-to-end encryption for OpenAI-compatible chat completions
|
|||
✅ **DO:**
|
||||
- Use HTTPS in production (enforced by default)
|
||||
- Enable secure memory protection (default: `secureMemory: true`)
|
||||
- Use password-protected private keys in Node.js
|
||||
- Use password-protected private keys in Node.js (minimum 8 characters)
|
||||
- Set private key file permissions to 600 (owner-only)
|
||||
- Rotate keys periodically
|
||||
- Rely on automatic key rotation (`keyRotationInterval`, default 24h) to limit fingerprint lifetime
|
||||
- Call `dispose()` when the client is no longer needed
|
||||
- Validate server public key fingerprint on first use
|
||||
|
||||
❌ **DON'T:**
|
||||
|
|
@ -248,9 +259,12 @@ class SecureByteContext {
|
|||
try {
|
||||
return await fn(this.data);
|
||||
} finally {
|
||||
// Always zero, even if exception occurs
|
||||
// Always zero, even if exception occurs.
|
||||
// zeroMemory failure is swallowed so it cannot mask the original error.
|
||||
if (this.useSecure) {
|
||||
new Uint8Array(this.data).fill(0);
|
||||
try {
|
||||
this.secureMemory.zeroMemory(this.data);
|
||||
} catch (_zeroErr) { /* intentional */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -328,6 +342,11 @@ npm install nomyo-native
|
|||
✅ **Timing Attacks (Partial)**
|
||||
- Web Crypto API uses constant-time operations
|
||||
- No length leakage in comparisons
|
||||
- Generic error messages from all crypto operations (RSA, AES) — internal engine errors not forwarded
|
||||
|
||||
✅ **Concurrent Key Generation Race**
|
||||
- Promise-chain mutex serialises all `ensureKeys()` callers
|
||||
- No risk of multiple simultaneous key generations overwriting each other
|
||||
|
||||
✅ **Key Compromise (Forward Secrecy)**
|
||||
- Ephemeral AES keys
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue