Quickstart Guide

Updated May 17, 202510 min read

Get started with TERE quickly by building your first secure application. This guide will walk you through creating, deploying, and executing a simple application in a Trusted Execution Environment.

Prerequisites

Before you begin, make sure you have:

  • Installed the TERE SDK and CLI (see the Installation Guide)
  • Set up the local development environment or configured a cloud provider
  • Authenticated with your API key

1. Initialize a New Project

First, let's create a new TERE project:

bash
1# Create a new directory
2mkdir my-tere-app
3cd my-tere-app
4
5# Initialize a new TERE project
6tere init

The tere init command will create the basic project structure with the following files:

  • package.json: Project configuration
  • tere.config.js: TERE-specific configuration
  • src/index.ts: Main entry point for your application

2. Write Your First Secure Function

Open the src/index.ts file and replace its contents with the following code:

typescript
1import { State, Crypto } from '@praecise/tere';
2
3/**
4 * Encrypts a message using AES-GCM
5 */
6export function encryptMessage(message: string): string {
7 console.log('Encrypting message in secure TEE');
8
9 // Generate a random key
10 const key = Crypto.generateKey();
11
12 // Convert the message to bytes
13 const messageBytes = new TextEncoder().encode(message);
14
15 // Encrypt the data
16 const encryptedData = Crypto.encrypt(messageBytes, key);
17
18 // Store the key for later retrieval using State API
19 const keyId = `key-${Date.now()}`;
20 State.set(keyId, key);
21
22 // Return the encrypted data and key ID as a Base64-encoded JSON string
23 return Buffer.from(JSON.stringify({
24 keyId,
25 data: Buffer.from(encryptedData).toString('base64')
26 })).toString('base64');
27}
28
29/**
30 * Decrypts a previously encrypted message
31 */
32export function decryptMessage(encryptedPayload: string): string {
33 console.log('Decrypting message in secure TEE');
34
35 // Parse the encrypted payload
36 const payload = JSON.parse(Buffer.from(encryptedPayload, 'base64').toString());
37 const { keyId, data } = payload;
38
39 // Retrieve the encryption key
40 const key = State.get(keyId);
41 if (!key) {
42 throw new Error('Encryption key not found');
43 }
44
45 // Decrypt the data
46 const encryptedData = Buffer.from(data, 'base64');
47 const decryptedBytes = Crypto.decrypt(encryptedData, key);
48
49 // Convert the decrypted bytes back to a string
50 return new TextDecoder().decode(decryptedBytes);
51}
52
53/**
54 * Simple function to demonstrate secure computation
55 */
56export function computeSecurely(a: number, b: number): number {
57 console.log('Performing secure computation in TEE');
58
59 // This is a simple example - in real-world scenarios,
60 // you would perform sensitive computations here
61 return a * b + Math.sqrt(a + b);
62}

This code defines three functions:

  • encryptMessage: Encrypts a message using AES-GCM and stores the encryption key
  • decryptMessage: Decrypts a previously encrypted message
  • computeSecurely: Performs a simple computation (for demonstration purposes)

3. Build Your Application

Build your application using the TERE CLI:

bash
1tere build

This will compile your TypeScript code and package it as a TERE script (.tere file) in the dist directory.

4. Deploy Your Application

Now, deploy your application to a local development TEE:

bash
1tere deploy --dev

The --dev flag tells TERE to deploy to the local development environment. If you want to deploy to a cloud provider, you can specify the provider and configuration:

bash
1# For production deployment to GCP
2tere deploy --provider gcp --tee-type confidential_vm

The deployment will output a script ID that you'll need for the next steps. It should look something like script_abc123.

5. Execute Your Secure Functions

Now that your application is deployed, you can execute the functions in the secure environment:

bash
1# Encrypt a message (replace script_abc123 with your actual script ID)
2tere execute script_abc123 encryptMessage "Hello from the secure world!"
3
4# The output will be a Base64-encoded payload, which you can save for decryption
5# Example output: eyJrZXlJZCI6ImtleS0xNjIwMTIzNDU2Nzg5IiwiZGF0YSI6ImFHVnNiRzhnWm5KdmJTQjBhR...
6
7# Store the encrypted payload in a variable (for Unix/Linux/macOS)
8ENCRYPTED=$(tere execute script_abc123 encryptMessage "Hello from the secure world!" --output-json | jq -r '.result')
9
10# Decrypt the message using the encrypted payload
11tere execute script_abc123 decryptMessage "$ENCRYPTED"
12
13# Execute the secure computation function
14tere execute script_abc123 computeSecurely 5 7

6. Using the SDK in Your Application

Instead of using the CLI, you can also use the TERE SDK in your application code. Create a new file called client.ts with the following content:

typescript
1import { TereClient } from '@praecise/tere';
2
3// Initialize the client
4const client = new TereClient({
5 endpoint: 'https://api.tere.praecise.com',
6 apiKey: 'your-api-key'
7});
8
9// Replace with your script ID from the deployment step
10const scriptId = 'script_abc123';
11
12async function main() {
13 try {
14 // Encrypt a message
15 console.log('Encrypting message...');
16 const encryptResult = await client.execute({
17 scriptId,
18 function: 'encryptMessage',
19 arguments: ['Hello from the secure world!']
20 });
21
22 const encryptedPayload = encryptResult.result;
23 console.log('Encrypted payload:', encryptedPayload);
24
25 // Verify the attestation
26 const verification = await client.verifyAttestation({
27 attestation: encryptResult.attestation
28 });
29
30 if (verification.valid) {
31 console.log('Attestation verified successfully');
32 console.log('TEE Type:', verification.details.teeType);
33 console.log('Secure Boot:', verification.details.secureBoot ? 'Enabled' : 'Disabled');
34 } else {
35 console.error('Attestation verification failed');
36 process.exit(1);
37 }
38
39 // Decrypt the message
40 console.log('\nDecrypting message...');
41 const decryptResult = await client.execute({
42 scriptId,
43 function: 'decryptMessage',
44 arguments: [encryptedPayload]
45 });
46
47 console.log('Decrypted message:', decryptResult.result);
48
49 // Perform a secure computation
50 console.log('\nPerforming secure computation...');
51 const computeResult = await client.execute({
52 scriptId,
53 function: 'computeSecurely',
54 arguments: [5, 7]
55 });
56
57 console.log('Computation result:', computeResult.result);
58
59 } catch (error) {
60 console.error('Error:', error);
61 }
62}
63
64main();

You can run this code with:

bash
1# Install ts-node if you don't have it
2npm install -g ts-node
3
4# Run the client code
5ts-node client.ts

7. Understanding What's Happening

Let's break down what's happening in this example:

  1. 1

    When you deploy your application, TERE provisions a Trusted Execution Environment (TEE) with hardware-backed security guarantees.

  2. 2

    Your code runs in a secure enclave with memory encryption and integrity protection, ensuring that even the infrastructure provider cannot access your sensitive data.

  3. 3

    Each execution generates an attestation report, which provides cryptographic evidence that your code is running in a genuine TEE with the expected security properties.

  4. 4

    The state management API allows you to store and retrieve data securely within the TEE, with automatic encryption and access controls.

8. Next Steps

Now that you've created your first TERE application, you can: