UNPKG

@praecise/tere

Version:

Trusted Execution Runtime Environment SDK

784 lines (598 loc) 21 kB
# TERE SDK The Trusted Execution Runtime Environment (TERE) SDK provides a comprehensive set of tools for building, deploying, and interacting with secure applications running in hardware-protected Trusted Execution Environments (TEEs). [![npm version](https://img.shields.io/npm/v/@praecise/tere.svg)](https://www.npmjs.com/package/@praecise/tere) [![Build Status](https://img.shields.io/github/workflow/status/praecise/tere-sdk/CI)](https://github.com/praecise/tere-sdk/actions) ## Table of Contents - [TERE SDK](#tere-sdk) - [Table of Contents](#table-of-contents) - [Installation](#installation) - [Quick Start](#quick-start) - [Deploying a TERE Application](#deploying-a-tere-application) - [Using Hardware Security Module (HSM)](#using-hardware-security-module-hsm) - [Key Concepts](#key-concepts) - [Trusted Execution Environment (TEE)](#trusted-execution-environment-tee) - [Hardware Security Module (HSM)](#hardware-security-module-hsm) - [Attestation](#attestation) - [Client API](#client-api) - [Initialization](#initialization) - [Deployment](#deployment) - [Execution](#execution) - [Asynchronous Jobs](#asynchronous-jobs) - [Script Management](#script-management) - [Hardware Security Module Operations](#hardware-security-module-operations) - [Attestation Verification](#attestation-verification) - [Runtime API](#runtime-api) - [State Management](#state-management) - [Cryptography](#cryptography) - [Hardware Security Module (HSM)](#hardware-security-module-hsm-1) - [Access Control](#access-control) - [Cloud KMS](#cloud-kms) - [Attestation](#attestation-1) - [Secure Logging](#secure-logging) - [Packaging](#packaging) - [Security Best Practices](#security-best-practices) - [Key Management](#key-management) - [Data Protection](#data-protection) - [Advanced Usage](#advanced-usage) - [Key Hierarchies with HSM](#key-hierarchies-with-hsm) - [Secure Multi-Party Computation](#secure-multi-party-computation) - [Custom Attestation Policies](#custom-attestation-policies) - [Examples](#examples) - [Secure Data Vault](#secure-data-vault) - [Healthcare Data Processor](#healthcare-data-processor) - [Financial Transaction System](#financial-transaction-system) - [API Reference](#api-reference) - [FAQ](#faq) - [General Questions](#general-questions) - [Technical Questions](#technical-questions) - [HSM Questions](#hsm-questions) - [Support](#support) - [License](#license) ## Installation Install the TERE SDK using npm: ```bash npm install @praecise/tere ``` Or using yarn: ```bash yarn add @praecise/tere ``` ## Quick Start ### Deploying a TERE Application ```typescript import { TereClient, TerePackager } from '@praecise/tere'; // Create code for the TERE script const code = ` import { State } from '@praecise/tere'; export function hello(name) { return \`Hello, \${name}! Your data is secure in the TEE.\`; } export function storeSecretData(data) { State.set('secret_data', data); return { success: true }; } export function getSecretData() { return State.get('secret_data'); } `; // Package the code const scriptBinary = TerePackager.createScript({ code, name: 'my-first-tere-app', version: '1.0.0', functions: ['hello', 'storeSecretData', 'getSecretData'] }); // Create a client const client = new TereClient({ endpoint: 'https://api.tere.praecise.com', apiKey: 'your-api-key' }); // Deploy the script async function deployScript() { const result = await client.deploy({ name: 'my-first-tere-app', tereBinary: scriptBinary, description: 'My first TERE application', config: { teeType: 'confidential_vm', provider: 'gcp', location: 'us-central1-a' } }); console.log(`Script deployed with ID: ${result.scriptId}`); return result.scriptId; } // Execute a function async function executeFunction(scriptId) { const result = await client.execute({ scriptId, function: 'hello', arguments: ['World'] }); console.log(result.result); // "Hello, World! Your data is secure in the TEE." } // Deploy and run the script deployScript().then(executeFunction); ``` ### Using Hardware Security Module (HSM) ```typescript // Deploy with HSM enabled const result = await client.deploy({ name: 'secure-app-with-hsm', tereBinary: scriptBinary, config: { teeType: 'confidential_vm', provider: 'gcp', securitySettings: { enableHsm: true, // Enable HSM support confidentialComputeType: 'SEV_SNP' } } }); // Inside your TERE code: import { Crypto } from '@praecise/tere'; export async function encryptWithHsm(data) { // Create HSM provider const hsmProvider = Crypto.withHsmProvider(); // Get or create a key const keyId = 'my-encryption-key'; await hsmProvider.getOrCreateKey(keyId, 'encrypt'); // Encrypt with HSM const encryptedData = await hsmProvider.encrypt(data, keyId); return encryptedData; } ``` ## Key Concepts ### Trusted Execution Environment (TEE) A TEE is a secure, isolated execution environment that protects sensitive code and data from unauthorized access, even from privileged system users. TERE applications run within these protected environments, ensuring: - **Confidentiality**: Data and code are encrypted in memory - **Integrity**: Execution cannot be tampered with - **Attestation**: Provides cryptographic proof of the environment's security ### Hardware Security Module (HSM) Hardware Security Modules provide FIPS 140-2 Level 3 certified protection for cryptographic keys and operations. When using HSM in TERE: - Keys are generated and stored in tamper-resistant hardware - Cryptographic operations occur within the secure hardware - Keys never leave the HSM in plaintext form ### Attestation Attestation provides cryptographic proof that code is running in a genuine TEE with the expected security properties. This enables: - Verifying the integrity of the execution environment - Ensuring code hasn't been tampered with - Validating the security guarantees of the TEE ## Client API The `TereClient` class provides methods for interacting with the TERE service: ### Initialization ```typescript const client = new TereClient({ endpoint: 'https://api.tere.praecise.com', // Optional apiKey: 'your-api-key', // Required timeout: 30000 // Optional }); ``` ### Deployment ```typescript const result = await client.deploy({ name: 'my-application', tereBinary: scriptBinary, description: 'Application description', config: { teeType: 'confidential_vm', // or 'confidential_gke' provider: 'gcp', // Default, currently only GCP supported location: 'us-central1-a', // GCP zone resourceLimits: { cpuCores: 2, memoryMb: 4096, storageGb: 10 }, securitySettings: { secureBoot: true, integrityMonitoring: true, vtpm: true, confidentialComputeType: 'SEV', // 'SEV', 'SEV_SNP', or 'TDX' enableHsm: true, // Enable Hardware Security Module hsmKeyRing: 'my-key-ring' // Optional custom HSM key ring name }, networkConfig: { usePublicIp: true, networkTags: ['tere-app'] } } }); ``` ### Execution ```typescript const result = await client.execute({ scriptId: 'script_abc123', function: 'myFunction', arguments: ['arg1', 'arg2'], // Or any JavaScript value waitForResult: true, // Default: true callerId: 'user_123', // Optional caller identity nonce: 'unique-nonce-value', // Optional nonce for attestation hsmKeyId: 'my-hsm-key' // Optional HSM key for operations }); ``` ### Asynchronous Jobs ```typescript // Start an async job const jobResult = await client.execute({ scriptId: 'script_abc123', function: 'longRunningTask', arguments: { data: 'large-dataset' }, waitForResult: false }); const jobId = jobResult.jobId; // Later, check the job status const result = await client.getJobStatus(jobId); if (result.result) { console.log('Job completed:', result.result); } ``` ### Script Management ```typescript // List all scripts const scripts = await client.listScripts(); // Get details for a specific script const script = await client.getScript('script_abc123'); // Start/stop scripts await client.startInstance('script_abc123'); await client.stopInstance('script_abc123'); // Delete a script await client.deleteScript('script_abc123'); ``` ### Hardware Security Module Operations ```typescript // List HSM keys for a script const hsmKeys = await client.listHsmKeys('script_abc123'); // Create a new HSM key const keyInfo = await client.createHsmKey( 'script_abc123', 'encryption-key-1', 'encrypt' ); ``` ### Attestation Verification ```typescript const result = await client.verifyAttestation({ attestation: attestationString, expectedNonce: 'expected-nonce-value' }); if (result.valid) { console.log('Attestation verified successfully'); console.log('TEE Type:', result.details?.teeType); console.log('HSM Info:', result.details?.hsmInfo); } ``` ## Runtime API The runtime API provides functionality to code running inside the TEE. ### State Management ```typescript import { State } from '@praecise/tere'; // Store a value State.set('my_key', 'my_value'); State.set('user_123', { name: 'Alice', role: 'admin' }); // Retrieve a value const value = State.get('my_key'); const user = State.get('user_123'); // Check if a key exists if (State.exists('some_key')) { // Key exists } // Remove a value State.remove('temporary_data'); ``` ### Cryptography ```typescript import { Crypto } from '@praecise/tere'; // Encryption function encryptData(data, key) { // Convert string to bytes if needed const dataBytes = typeof data === 'string' ? new TextEncoder().encode(data) : data; // Encrypt const encryptedData = Crypto.encrypt(dataBytes, key); return encryptedData; } // Decryption function decryptData(encryptedData, key) { const decryptedBytes = Crypto.decrypt(encryptedData, key); return new TextDecoder().decode(decryptedBytes); } // Generate a key const key = Crypto.generateKey(); // Create a hash const hash = Crypto.hash('data to hash'); // Generate random data const randomBytes = Crypto.randomBytes(32); // Derive key from password const salt = Crypto.randomBytes(16); const iterations = 100000; const derivedKey = Crypto.deriveKeyFromPassword('secure-password', salt, iterations); ``` ### Hardware Security Module (HSM) ```typescript import { Crypto } from '@praecise/tere'; // Create an HSM provider const hsmProvider = Crypto.withHsmProvider({ keyRing: 'my-key-ring', // Optional location: 'us-central1' // Optional }); // Create a key in HSM async function createHsmKey() { // Create encryption key const encKeyInfo = await hsmProvider.createKey( 'encryption-key-1', 'encrypt' ); // Create signing key with specific algorithm const signKeyInfo = await hsmProvider.createKey( 'signing-key-1', 'sign', 'ec-p256-sha256' ); return { encKeyInfo, signKeyInfo }; } // Get or create a key async function getOrCreateKey(keyId) { return await hsmProvider.getOrCreateKey(keyId, 'encrypt'); } // Encrypt with HSM key async function encryptWithHsm(data, keyId) { return await hsmProvider.encrypt(data, keyId); } // Decrypt with HSM key async function decryptWithHsm(encryptedData, keyId) { return await hsmProvider.decrypt(encryptedData, keyId); } // Sign data with HSM key async function signWithHsm(data, keyId) { return await hsmProvider.sign(data, keyId); } // Verify signature with HSM key async function verifyWithHsm(data, signature, keyId) { return await hsmProvider.verify(data, signature, keyId); } // List all HSM keys async function listKeys() { return await hsmProvider.listKeys(); } ``` ### Access Control ```typescript import { AccessControl } from '@praecise/tere'; // Set an access rule AccessControl.setAccessRule('user_data', { readAccess: ['user_123', 'admin'], writeAccess: ['admin'] }); // Get an access rule const rule = AccessControl.getAccessRule('user_data'); ``` ### Cloud KMS ```typescript import { CloudKms } from '@praecise/tere'; // Encrypt with cloud-managed key async function encryptWithCloudKey(data, keyName) { return await CloudKms.encrypt(data, keyName); } // Decrypt with cloud-managed key async function decryptWithCloudKey(encryptedData, keyName) { return await CloudKms.decrypt(encryptedData, keyName); } // Create a key in Cloud KMS async function createCloudKey(keyName, purpose) { return await CloudKms.createKey(keyName, purpose); } // Sign data with cloud-managed key async function signWithCloudKey(data, keyName) { return await CloudKms.sign(data, keyName); } // Verify signature with cloud-managed key async function verifyWithCloudKey(data, signature, keyName) { return await CloudKms.verify(data, signature, keyName); } ``` ### Attestation ```typescript import { Attestation } from '@praecise/tere'; // Get attestation report function getAttestation(nonce) { return Attestation.getReport(nonce); } // Verify an attestation function verifyAttestation(attestation, expectedNonce) { return Attestation.verify(attestation, expectedNonce); } ``` ### Secure Logging ```typescript import { SecureLog } from '@praecise/tere'; // Log at different levels SecureLog.info('Processing started'); SecureLog.warn('Resource usage is high'); SecureLog.error('Operation failed'); SecureLog.debug('Debug information'); // Or use the generic log method SecureLog.log('Custom message', 'info'); ``` ## Packaging The `TerePackager` class helps create TERE script packages: ```typescript import { TerePackager } from '@praecise/tere'; // Create a TERE script package const scriptBinary = TerePackager.createScript({ code: 'export function hello() { return "Hello, World!"; }', name: 'hello-world', version: '1.0.0', author: 'TERE Developer', description: 'A simple TERE script', functions: ['hello'] }); // Validate a script package const isValid = TerePackager.validateScript(scriptBinary); // Extract metadata from a script const metadata = TerePackager.extractMetadata(scriptBinary); ``` ## Security Best Practices ### Key Management 1. **Use Hardware Security Modules**: - Protect your most sensitive keys with HSM when available - Use key hierarchies with HSM-protected root keys 2. **Implement Key Rotation**: - Rotate encryption keys regularly - Store key versions alongside encrypted data 3. **Separate Keys by Purpose**: - Use different keys for different operations - Separate keys for different data categories ### Data Protection 1. **Always Use Authenticated Encryption**: - Use AES-GCM (default in TERE) for authenticated encryption - Verify integrity of decrypted data 2. **Avoid Sensitive Data in Logs**: - Use SecureLog for secure logging - Avoid logging sensitive data 3. **Validate Attestations**: - Always verify attestation reports for critical operations - Check for HSM attestation when using HSM features ## Advanced Usage ### Key Hierarchies with HSM ```typescript import { Crypto, State } from '@praecise/tere'; async function setupKeyHierarchy() { // Create HSM provider const hsmProvider = Crypto.withHsmProvider(); // 1. Root key - stored in HSM, rarely accessed const rootKeyId = 'root-key'; await hsmProvider.getOrCreateKey(rootKeyId, 'encrypt'); // 2. Key encryption keys (KEKs) - protected by root key const kekBytes = Crypto.generateKey(); const wrappedKek = await hsmProvider.encrypt(kekBytes, rootKeyId); State.set('wrapped-kek', wrappedKek); // 3. Data encryption keys (DEKs) - protected by KEKs const dekBytes = Crypto.generateKey(); // Unwrap the KEK to use it const kek = await hsmProvider.decrypt(wrappedKek, rootKeyId); // Encrypt the DEK with the KEK const encryptedDek = Crypto.encrypt(dekBytes, kek); // Store the encrypted DEK State.set('encrypted-dek', encryptedDek); return { rootKeyId, kekStatus: 'wrapped and stored', dekStatus: 'encrypted and stored' }; } ``` ### Secure Multi-Party Computation ```typescript import { Crypto, State } from '@praecise/tere'; // Alice stores her secret export function storeAliceSecret(secret) { State.set('alice_secret', secret); return { success: true }; } // Bob stores his secret export function storeBobSecret(secret) { State.set('bob_secret', secret); return { success: true }; } // Compute on the secrets without revealing them export function computeSharedResult() { const aliceSecret = State.get('alice_secret'); const bobSecret = State.get('bob_secret'); if (!aliceSecret || !bobSecret) { return { error: 'Missing required secrets' }; } // Perform computation without revealing individual secrets const result = performSecureComputation(aliceSecret, bobSecret); return { result, aliceSecretRevealed: false, bobSecretRevealed: false }; } ``` ### Custom Attestation Policies ```typescript import { Attestation, SecureLog } from '@praecise/tere'; export function secureOperation(data, nonce) { // Get attestation with the provided nonce const attestation = Attestation.getReport(nonce); // Include attestation in the result for verification return { result: processData(data), attestation }; } // Client-side verification async function verifySecureOperation(data) { // Generate a unique nonce const nonce = generateNonce(); // Execute with the nonce const result = await client.execute({ scriptId: 'script_id', function: 'secureOperation', arguments: [data, nonce], nonce: nonce // Also include in execute options }); // Verify the attestation const isValid = await client.verifyAttestation({ attestation: result.attestation, expectedNonce: nonce }); if (!isValid.valid) { throw new Error('Attestation verification failed'); } return result.result; } ``` ## Examples The SDK includes several example applications: ### Secure Data Vault A complete application for storing and retrieving encrypted data with HSM protection: ```typescript // See examples/secure-data-vault/index.ts ``` ### Healthcare Data Processor An example application for processing healthcare data with HIPAA compliance: ```typescript // See examples/healthcare-processor/index.ts ``` ### Financial Transaction System A demonstration of secure financial transactions with HSM-backed key protection: ```typescript // See examples/financial-transactions/index.ts ``` ## API Reference For detailed API documentation, see the [API Reference](https://docs.tere.praecise.com/api). ## FAQ ### General Questions **Q: What cloud providers are supported?** A: Currently, TERE supports Google Cloud Platform (GCP). Support for Azure and AWS is planned for future releases. **Q: What TEE technologies are supported?** A: TERE supports AMD SEV, AMD SEV-SNP, and Intel TDX confidential computing technologies. **Q: How is TERE different from other TEE frameworks?** A: TERE provides a complete solution with deployment, management, and runtime features, with strong integration for Hardware Security Modules. ### Technical Questions **Q: Can I use TypeScript with TERE?** A: Yes, the TERE SDK is fully compatible with TypeScript and includes type definitions. **Q: How do I handle errors in TERE applications?** A: The SDK provides a `TereError` class for error handling. All client methods return Promises that can be caught for error handling. **Q: What is the maximum data size for State storage?** A: The State API supports values up to 10MB per key. For larger data, consider splitting into smaller chunks. **Q: How do I rotate encryption keys?** A: See the "Key Rotation" example in the Advanced Usage section. ### HSM Questions **Q: What is the performance impact of using HSM?** A: HSM operations typically add a few milliseconds of latency compared to software-based cryptography, but provide significantly stronger security guarantees. **Q: Can I export keys from the HSM?** A: No, keys generated in HSM never leave the secure hardware in plaintext form, ensuring maximum security. **Q: What happens if an HSM key is lost?** A: Data encrypted with a lost HSM key cannot be recovered. Make sure to implement proper key management and backup strategies. ## Support For questions, issues, or feature requests: - [Documentation](https://docs.tere.praecise.com) - [GitHub Issues](https://github.com/praecise/tere-sdk/issues) - [Support Email](mailto:support@praecise.com) ## License Copyright (c) 2025 Praecise LTD. All rights reserved. This software is proprietary and confidential. Unauthorized copying of this file, via any medium is strictly prohibited.