nomyo-js/doc/api-reference.md
alpha nerd 987acf8816
Some checks failed
NYX Security Scan / nyx-scan (pull_request) Failing after 5m51s
feat!: make RSA keys ephemeral by default
BREAKING CHANGE: keyDir now defaults to null (ephemeral) instead of
'client_keys'. Clients that relied on keys persisting across restarts
must now pass keyDir explicitly.

The Python SDK defaults to key_dir=None: a key pair is generated in
memory for the session and never written to disk. The JS port defaulted
to 'client_keys' and always persisted, so merely constructing a client
wrote an RSA private key into the working directory. That is a weaker
default than the client it ports, and one users never asked for.

  - keyDir?: string | null, defaulting to undefined. null and undefined
    both mean ephemeral, matching Python's None.
  - Persistent mode is unchanged when keyDir is set: load the existing
    pair from that directory, otherwise generate and save one there.
  - Browsers are always ephemeral; they have no filesystem.

Key rotation follows the same rule. It previously hardcoded
'client_keys' as its fallback directory, so an ephemeral client would
have started writing private keys to disk on the first rotation tick.
Rotated keys are now persisted only where keyDir or keyRotationDir is
explicitly configured.

Tests assert the intent (that saveKeys is never called) rather than
probing the filesystem, since a leftover client_keys/ from the old
default would otherwise make them pass or fail for the wrong reason.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 11:19:03 +02:00

14 KiB
Raw Blame History

API Reference

SecureChatCompletion

High-level OpenAI-compatible client. The recommended entry point for most use cases.

Constructor

new SecureChatCompletion(config?: ChatCompletionConfig)

ChatCompletionConfig

Option Type Default Description
baseUrl string 'https://api.nomyo.ai' NOMYO router URL. Must be HTTPS in production.
allowHttp boolean false Allow HTTP connections.Local development only.
apiKey string undefined Bearer token sent inAuthorization header.
secureMemory boolean true Enable immediate zeroing of sensitive buffers after use.
timeout number 60000 Request timeout in milliseconds.
debug boolean false Print verbose logging to the console.
keyDir string | null null Directory to load/save RSA keys on startup. If the directory contains an existing key pair it is loaded; otherwise a new pair is generated and saved there. Omit (or pass null) for ephemeral keys generated in memory for this session only and never written to disk — this is the default, matching the Python SDK. Node.js only; browsers are always ephemeral.
keyRotationInterval number 86400000 (24 h) Auto-rotate RSA keys every N milliseconds. Set to0 to disable.
keyRotationDir string value of keyDir Directory where rotated key files are saved. When neither this nor keyDir is set, rotated keys stay in memory. Node.js only.
keyRotationPassword string undefined Password used to encrypt rotated key files.
maxRetries number 2 Maximum extra attempts on retryable errors (429, 500, 502, 503, 504, network errors). Uses exponential backoff (1 s, 2 s, …). Set to0 to disable retries.

Methods

create(request): Promise<ChatCompletionResponse>

Send an encrypted chat completion request. Returns the decrypted response.

async create(request: ChatCompletionRequest): Promise<ChatCompletionResponse>

ChatCompletionRequest fields:

Field Type Description
model string Required. Model ID (see Models).
messages Message[] Required. Conversation history.
temperature number Sampling temperature (02).
top_p number Nucleus sampling.
max_tokens number Maximum tokens to generate.
stop `string string[]`
n number Number of completions to generate.
stream boolean Ignored server-side (encryption requires full response).
presence_penalty number Presence penalty (2.02.0).
frequency_penalty number Frequency penalty (2.02.0).
logit_bias Record<string, number> Token bias map.
user string End-user identifier (passed through).
tools Tool[] Tool/function definitions.
tool_choice ToolChoice Tool selection strategy ("auto", "none", "required", or specific tool).
security_tier string NOMYO-specific."standard" | "high" | "maximum". Not encrypted into the payload.
api_key string NOMYO-specific. Per-request API key override. Not encrypted into the payload.
base_url string NOMYO-specific. Per-request router URL override. Creates a temporary client for this one call. Not encrypted into the payload.

Response shape (ChatCompletionResponse):

{
  id: string;
  object: 'chat.completion';
  created: number;
  model: string;
  choices: Array<{
    index: number;
    message: {
      role: string;
      content: string;
      tool_calls?: ToolCall[];       // present if tools were invoked
      reasoning_content?: string;   // chain-of-thought (Qwen3, DeepSeek-R1, etc.)
    };
    finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;
  }>;
  usage?: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
  _metadata?: {
    payload_id: string;           // echoes the X-Payload-ID sent with the request
    processed_at: number;         // Unix timestamp of server-side processing
    is_encrypted: boolean;        // always true for this endpoint
    encryption_algorithm: string; // e.g. "hybrid-aes256-rsa4096"
    response_status: string;      // "success" on success
    security_tier?: string;       // active tier used by the server
    memory_protection?: {
      platform: string;
      memory_locking: boolean;
      secure_zeroing: boolean;
      core_dump_prevention: boolean;
    };
    cuda_device?: {
      available: boolean;
      device_hash: string;        // SHA-256 of device name (not the raw name)
    };
  };
}

acreate(request): Promise<ChatCompletionResponse>

Alias for create(). Provided for code that follows the OpenAI SDK naming convention.

dispose(): void

Stop the key-rotation timer and sever in-memory RSA key references so they can be garbage-collected. After calling dispose(), all methods throw DisposedError.

client.dispose();

SecureCompletionClient

Lower-level client that exposes key management and individual encryption/decryption operations. Use this when you need fine-grained control; for most use cases prefer SecureChatCompletion.

Constructor

new SecureCompletionClient(config?: ClientConfig)

ClientConfig

All options from ChatCompletionConfig, plus:

Option Type Default Description
routerUrl string 'https://api.nomyo.ai' NOMYO router base URL.
keySize `2048 4096` 4096

(baseUrl is renamed to routerUrl at this level; all other options are identical.)

Methods

generateKeys(options?): Promise<void>

Generate a fresh RSA key pair.

await client.generateKeys({
  keySize?: 2048 | 4096,     // default: 4096
  saveToFile?: boolean,      // default: false
  keyDir?: string,           // default: 'client_keys'
  password?: string,         // minimum 8 characters if provided
});

loadKeys(privateKeyPath, publicKeyPath?, password?): Promise<void>

Load an existing key pair from PEM files. Node.js only.

await client.loadKeys(
  'client_keys/private_key.pem',
  'client_keys/public_key.pem',  // optional; derived from private key path if omitted
  'your-password'                // required if private key is encrypted
);

fetchServerPublicKey(): Promise<string>

Fetch the server's RSA public key from /pki/public_key over HTTPS. Called automatically on every encryption; exposed for diagnostics.

encryptPayload(payload): Promise<ArrayBuffer>

Encrypt a request payload. Returns the encrypted binary package ready to POST.

decryptResponse(encrypted, payloadId): Promise<object>

Decrypt a response body received from the secure endpoint.

sendSecureRequest(payload, payloadId, apiKey?, securityTier?): Promise<object>

Full encrypt → POST → decrypt cycle with retry logic. Called internally by SecureChatCompletion.create().

dispose(): void

Same as SecureChatCompletion.dispose().


Secure Memory API

import {
  getMemoryProtectionInfo,
  disableSecureMemory,
  enableSecureMemory,
  SecureByteContext,
} from 'nomyo-js';

getMemoryProtectionInfo(): ProtectionInfo

Returns information about the memory protection available on the current platform:

interface ProtectionInfo {
  canLock: boolean;       // true if mlock is available (requires native addon)
  isPlatformSecure: boolean;
  method: 'mlock' | 'zero-only' | 'none';
  details?: string;
}

disableSecureMemory(): void

Disable secure-memory zeroing globally. Affects new SecureByteContext instances that do not pass an explicit useSecure argument. Existing client instances are unaffected (they pass useSecure explicitly).

enableSecureMemory(): void

Re-enable secure memory operations globally.

SecureByteContext

Low-level context manager that zeros an ArrayBuffer in a finally block even if an exception occurs. Analogous to Python's secure_bytearray() context manager.

const context = new SecureByteContext(sensitiveBuffer);
const result = await context.use(async (data) => {
  return doSomethingWith(data);
});
// sensitiveBuffer is zeroed here regardless of whether doSomethingWith threw

Error Classes

All errors are exported from the package root.

import {
  APIError,
  AuthenticationError,
  InvalidRequestError,
  RateLimitError,
  ForbiddenError,
  ServerError,
  ServiceUnavailableError,
  APIConnectionError,
  SecurityError,
  DisposedError,
} from 'nomyo-js';
Class HTTP status Thrown when
AuthenticationError 401 Invalid or missing API key
InvalidRequestError 400 Malformed request (e.g. streaming requested)
ForbiddenError 403 Model not allowed for the requested security tier
RateLimitError 429 Rate limit exceeded (after all retries exhausted)
ServerError 500 Internal server error (after all retries exhausted)
ServiceUnavailableError 503 Inference backend unavailable (after all retries exhausted)
APIError varies Other HTTP errors (404, 502, 504, etc.)
APIConnectionError Network failure or timeout (after all retries exhausted)
SecurityError HTTPS not used, header injection detected, or crypto failure
DisposedError Method called afterdispose()

All errors that extend APIError expose statusCode?: number and errorDetails?: object.