# NOMYO Secure Java Chat Client **OpenAI-compatible secure chat client with end-to-end encryption for NOMYO Inference Endpoints** 🔒 **All prompts and responses are automatically encrypted and decrypted** 🔑 **Uses hybrid encryption (AES-256-GCM + RSA-OAEP with 4096-bit keys)** 🔄 **Drop-in replacement for OpenAI's ChatCompletion API (Java)** ## 🚀 Quick Start ### 0. Try It Now (Demo Credentials) No account needed — use these public demo credentials to test immediately: | | | |---|---| | **API key** | `NOMYO_AI_E2EE_INFERENCE` | | **Model** | `Qwen/Qwen3-0.6B` | > **Note:** The demo endpoint uses a fixed 256-token context window and is intended for evaluation only. ### 1. Installation via Maven (recommended): ```xml com.nomyo nomyo-java 1.0.0 ``` via Gradle: ```groovy implementation 'com.nomyo:nomyo-java:1.0.0' ``` ### 2. Use the client (same API as OpenAI) ```java import com.nomyo.client.SecureChatCompletion; import com.nomyo.client.Constants; import java.util.List; import java.util.Map; public class Main { public static void main(String[] args) { SecureChatCompletion secureChatCompletion = new SecureChatCompletion( Constants.DEFAULT_BASE_URL, "NOMYO_AI_E2EE_INFERENCE" ); List> messages = List.of( Map.of("role", "user", "content", "Hello! How are you today?") ); Map kwargs = Map.of( "security_tier", "standard", "temperature", 0.7 ); var response = secureChatCompletion.create( "Qwen/Qwen3-0.6B", messages, kwargs); System.out.println(response.toString()); } } ``` ## 🔐 Security Features ### Hybrid Encryption - **Payload encryption**: AES-256-GCM (authenticated encryption) - **Key exchange**: RSA-OAEP with SHA-256 - **Key size**: 4096-bit RSA keys - **All communication**: End-to-end encrypted ### Key Management - **Automatic key generation**: Keys are automatically generated on first use - **Automatic key loading**: Existing keys are loaded automatically from `client_keys/` directory - **No manual intervention required**: The library handles key management automatically - **Keys kept in memory**: Active session keys are stored in memory for performance - **Optional persistence**: Keys can be saved to `client_keys/` directory for reuse across sessions - **Password protection**: Optional password encryption for private keys (recommended for production) - **Secure permissions**: Private keys stored with restricted permissions (600 - owner-only access) ### Secure Memory Protection ### Ephemeral AES Keys - **Per-request encryption keys**: A unique AES-256 key is generated for each request - **Automatic rotation**: AES keys are never reused - a fresh key is created for every encryption operation - **Forward secrecy**: Compromise of one AES key only affects that single request - **Secure generation**: AES keys are generated using cryptographically secure random number generation - **Automatic cleanup**: AES keys are zeroed from memory immediately after use - **Automatic protection**: Plaintext payloads are automatically protected during encryption - **Prevents memory swapping**: Sensitive data cannot be swapped to disk - **Guaranteed zeroing**: Memory is zeroed after encryption completes - **Fallback mechanism**: Graceful degradation if SecureMemory module unavailable ## 🔄 OpenAI Compatibility The `SecureChatCompletion` class provides **exact API compatibility** with OpenAI's `ChatCompletion.create()` method. ### Supported Parameters All standard OpenAI parameters are supported: - `model`: Model identifier - `messages`: List of message objects (`List>`) - `temperature`: Sampling temperature (0-2) - `max_tokens`: Maximum tokens to generate - `top_p`: Nucleus sampling - `frequency_penalty`: Frequency penalty - `presence_penalty`: Presence penalty - `stop`: Stop sequences - `n`: Number of completions - `tools`: Tool definitions - `tool_choice`: Tool selection strategy - `user`: User identifier - And more... ### Response Format Responses follow the OpenAI format exactly, with an additional `_metadata` field for debugging and security information. ```java { "id": "chatcmpl-123", "object": "chat.completion", "created": 1234567890, "model": "Qwen/Qwen3-0.6B", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Hello! I'm doing well, thank you for asking.", "tool_calls": [...] // if tools were used }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 10, "completion_tokens": 20, "total_tokens": 30 }, "_metadata": { "payload_id": "openai-compat-abc123", // Unique identifier for this request "processed_at": 1765250382, // Timestamp when server processed the request "is_encrypted": true, // Indicates this response was decrypted "encryption_algorithm": "hybrid-aes256-rsa4096", // Encryption method used "response_status": "success" // Status of the decryption/processing } } ``` The `_metadata` field contains security-related information about the encrypted communication and is automatically added to all responses. ## 🛠️ Usage Examples ### Basic Chat ```java import com.nomyo.client.SecureChatCompletion; import com.nomyo.client.Constants; import java.util.List; import java.util.Map; public class Main { public static void main(String[] args) { SecureChatCompletion client = new SecureChatCompletion( Constants.DEFAULT_BASE_URL, "NOMYO_AI_E2EE_INFERENCE" ); List> messages = List.of( Map.of("role", "system", "content", "You are a helpful assistant."), Map.of("role", "user", "content", "What is the capital of France?") ); Map kwargs = Map.of("security_tier", "standard", "temperature", 0.7); var response = client.create( "Qwen/Qwen3-0.6B", messages, kwargs ); // Extract content safely System.out.println(response.get("choices").get(0).get("message").get("content")); } } ``` ### With Tools ```java import com.nomyo.client.SecureChatCompletion; import com.nomyo.client.Constants; import java.util.List; import java.util.Map; public class Main { public static void main(String[] args) { SecureChatCompletion client = new SecureChatCompletion( Constants.DEFAULT_BASE_URL, "NOMYO_AI_E2EE_INFERENCE" ); List> messages = List.of( Map.of("role", "user", "content", "What's the weather in Paris?") ); Map tools = Map.of( "type", "function", "function", Map.of( "name", "get_weather", "description", "Get weather information", "parameters", Map.of( "type", "object", "properties", Map.of( "location", Map.of("type", "string") ), "required", List.of("location") ) ) ); Map kwargs = Map.of("security_tier", "standard", "temperature", 0.7); var response = client.create( "Qwen/Qwen3-0.6B", messages, kwargs ); System.out.println(response.get("choices").get(0).get("message").get("content")); } } ``` ## 📦 Dependencies - **Maven Coordinates**: `com.nomyo:nomyo-java` - **Java Version**: Java 11+ (Required for HTTP Client and crypto primitives) - **JSON Processing**: Jackson Databind (for Map/JSON handling) - **HTTP Client**: Apache HttpClient or Java NIO (Included in core) - **Crypto**: BouncyCastle or JDK Crypto (Included in core) ## 🔧 Configuration ### Custom Base URL ```java SecureChatCompletion client = new SecureChatCompletion("https://NOMYO-Pro-Router:12434", "YOUR_API_KEY"); ``` ### API Key Authentication ```java // Initialize with API key (recommended for production) SecureChatCompletion client = new SecureChatCompletion( "https://api.nomyo.ai", "your-api-key-here" ); // Or pass API key in the create() method if supported by extension // Map kwargs = Map.of("security_tier", "standard", "api_key", "your-api-key-here"); ``` ### Secure Memory Configuration The library enables secure memory protection by default. ```java // Enable secure memory protection (default) SecureChatCompletion client = new SecureChatCompletion("https://api.nomyo.ai", "YOUR_API_KEY"); // Disable secure memory (not recommended, for testing only) // Requires passing specific config flag if available in version SecureChatCompletion client = new SecureChatCompletion("https://api.nomyo.ai", "YOUR_API_KEY"); ``` ### Key Management Keys are automatically generated on first use. #### Generate Keys Manually ```java import com.nomyo.client.SecureCompletionClient; public class KeyManager { public static void main(String[] args) { SecureCompletionClient client = new SecureCompletionClient(); client.generateKeys(true, "client_keys", "your-password"); } } ``` #### Load Existing Keys ```java import com.nomyo.client.SecureCompletionClient; public class KeyManager { public static void main(String[] args) { SecureCompletionClient client = new SecureCompletionClient(); client.loadKeys("client_keys/private_key.pem", "client_keys/public_key.pem", "your-password"); } } ``` ## 📚 API Reference ### SecureChatCompletion #### Constructor ```java SecureChatCompletion( String base_url, String api_key ) ``` **Parameters:** - `base_url`: Base URL of the NOMYO Router (must use HTTPS for production) - `api_key`: Optional API key for bearer authentication #### Methods - `create(String model, List> messages, Map kwargs)`: Create a chat completion ### SecureCompletionClient #### Constructor ```java SecureCompletionClient( String router_url ) ``` #### Methods - `generateKeys(boolean saveToFile, String keyDir, String password)`: Generate RSA key pair - `loadKeys(String private_key_path, String public_key_path, String password)`: Load keys from files - `fetchServerPublicKey()`: Fetch server's public key - `encryptPayload(Map payload)`: Encrypt a payload - `decryptResponse(Map encrypted_response, String payload_id)`: Decrypt a response - `sendSecureRequest(Map payload, String payload_id)`: Send encrypted request and receive decrypted response ## 📝 Notes ### Security Best Practices - Always use password protection for private keys in production - Keep private keys secure (permissions set to 600) - Never share your private key - Verify server's public key fingerprint before first use ### Performance - Key generation takes ~1-2 seconds (one-time operation) - Encryption/decryption adds minimal overhead (~10-20ms per request) ### Compatibility - Works with any OpenAI-compatible code - No changes needed to existing OpenAI client code - Simply replace `openai.ChatCompletion.create()` with `SecureChatCompletion.create()` ## 🤝 Contributing Contributions are welcome! Please open issues or pull requests on the project repository. ## 📄 License See LICENSE file for licensing information. ## 📞 Support For questions or issues, please refer to the project documentation or open an issue.