@praecise/tere
TypeScript icon, indicating that this package has built-in type declarations

0.1.0-preview.1 • Public • Published

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 Build Status

Table of Contents

Installation

Install the TERE SDK using npm:

npm install @praecise/tere

Or using yarn:

yarn add @praecise/tere

Quick Start

Deploying a TERE Application

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)

// 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

const client = new TereClient({
  endpoint: 'https://api.tere.praecise.com', // Optional
  apiKey: 'your-api-key',                    // Required
  timeout: 30000                             // Optional
});

Deployment

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

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

// 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

// 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

// 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

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

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

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)

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

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

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

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

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:

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

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

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

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:

// See examples/secure-data-vault/index.ts

Healthcare Data Processor

An example application for processing healthcare data with HIPAA compliance:

// See examples/healthcare-processor/index.ts

Financial Transaction System

A demonstration of secure financial transactions with HSM-backed key protection:

// See examples/financial-transactions/index.ts

API Reference

For detailed API documentation, see the API Reference.

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:

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.

Package Sidebar

Install

npm i @praecise/tere

Weekly Downloads

4

Version

0.1.0-preview.1

License

none

Unpacked Size

111 kB

Total Files

17

Last publish

Collaborators

  • hilarl