Skip to content

🔒 Use iApps with Protected Data

Protected data is the cornerstone of privacy-preserving computation on iExec. This guide shows you how to use iApps with protected data, from granting access to processing and retrieving results.

Understanding Protected Data and iApps

Protected data is encrypted information that can only be processed by authorized iApps within Trusted Execution Environments (TEEs). The data remains confidential throughout the entire computation process.

The Workflow

  1. Protect Your Data: Encrypt sensitive information using the Data Protector
  2. Grant Access: Authorize specific iApps to process your data
  3. Execute iApp: Run the iApp with your protected data
  4. Retrieve Results: Get the computation results while data remains private

Step 1: Protect Your Data

Before using an iApp, you need to protect your sensitive data.

Basic Data Protection

ts
// Protect your data
const { 
address
:
protectedDataAddress
} = await
dataProtectorCore
.
protectData
({
name
: 'My Sensitive Data',
data
: {
email
: 'user@example.com',
apiKey
: 'secret-api-key-12345',
preferences
: {
theme
: 'dark',
notifications
: true,
}, }, });

Protecting Different Data Types

ts
// Protect contact list for email applications
const { 
address
:
contactListAddress
} = await
dataProtectorCore
.
protectData
({
name
: 'Email Contact List',
data
: {
contacts
: {
'0x123abc...': 'john@example.com', '0x456def...': 'jane@example.com', '0x789ghi...': 'bob@example.com', }, }, }); // Protect trading data for oracle applications const {
address
:
tradingDataAddress
} = await
dataProtectorCore
.
protectData
({
name
: 'Trading History',
data
: {
trades
: {
'2024-01-01': {
price
: 50000,
volume
: 100 },
'2024-01-02': {
price
: 51000,
volume
: 150 },
'2024-01-03': {
price
: 49000,
volume
: 200 },
}, }, }); // Protect financial data for payment applications const {
address
:
paymentDataAddress
} = await
dataProtectorCore
.
protectData
({
name
: 'Payment Information',
data
: {
bankAccount
: '1234567890',
routingNumber
: '987654321',
accountHolder
: 'John Doe',
}, });

Step 2: Grant Access to iApps

iApps need explicit authorization to access your protected data.

Grant Access to a Specific iApp

ts
// Grant access to an iApp
const 
grantedAccess
= await
dataProtectorCore
.
grantAccess
({
protectedData
: '0x123abc...',
authorizedApp
: '0x456def...', // The iApp address
authorizedUser
: '0x789abc...', // Your wallet address
pricePerAccess
: 5, // Price per access in nRLC
numberOfAccess
: 10, // Number of allowed accesses
});

Check Granted Access

ts
// Check what access you've granted
const 
grantedAccessList
= await
dataProtectorCore
.
getGrantedAccess
({
protectedData
: '0x123abc...',
authorizedApp
: '0x456def...',
authorizedUser
: '0x789abc...',
});

Step 3: Execute iApp with Protected Data

Once access is granted, you can execute the iApp with your protected data.

Using DataProtector

ts
// Execute iApp with protected data
const 
result
= await
dataProtectorCore
.
processProtectedData
({
protectedData
: '0x123abc...',
app
: '0x456def...', // The iApp address
});

Using SDK Library

ts
// Create & Sign a request order with protected data
const 
requestorderToSign
= await
iexec
.
order
.
createRequestorder
({
app
: '0x456def...', // The iApp address
category
: 0,
appmaxprice
: 10, // Maximum price in nRLC
dataset
:
protectedDataAddress
, // Protected data address
datasetmaxprice
: 5, // Maximum price for dataset access
workerpool
: '0xa5de76...', // ENS address for iExec's debug workerpool
}); const
requestOrder
= await
iexec
.
order
.
signRequestorder
(
requestorderToSign
);
// Fetch app orders const
appOrders
= await
iexec
.
orderbook
.
fetchAppOrderbook
(
'0x456def...' // Filter by specific app ); if (
appOrders
.
orders
.
length
=== 0) {
throw new
Error
('No app orders found for the specified app');
} // Fetch protected data orders const
datasetOrders
= await
iexec
.
orderbook
.
fetchDatasetOrderbook
(
protectedDataAddress
// Filter by specific dataset
); if (
datasetOrders
.
orders
.
length
=== 0) {
throw new
Error
(
'No protectedData orders found for the specified protectedData' ); } // Fetch workerpool orders const
workerpoolOrders
= await
iexec
.
orderbook
.
fetchWorkerpoolOrderbook
({
workerpool
: '0xa5de76...', // Filter by specific workerpool
}); if (
workerpoolOrders
.
orders
.
length
=== 0) {
throw new
Error
('No workerpool orders found for the specified workerpool');
} // Execute the task const
taskId
= await
iexec
.
order
.
matchOrders
({
requestorder
:
requestOrder
,
apporder
:
appOrders
.
orders
[0].
order
,
datasetorder
:
datasetOrders
.
orders
[0].
order
,
workerpoolorder
:
workerpoolOrders
.
orders
[0].
order
,
});

Using iExec CLI with Protected Data

bash
# Execute with protected data
iexec app run 0x456def... --dataset 0x123abc...

Step 4: Retrieve Results

After execution completes, retrieve the results from the task.

Using DataProtector

ts
// Retrieve the result
const 
taskResult
= await
dataProtectorCore
.
getResultFromCompletedTask
({
taskId
:
taskId
,
});

Using iExec CLI

bash
# Get the task ID from the execution result
TASK_ID="0x7ac398..."

# Retrieve the result
iexec task show $TASK_ID

# Retrieve a specific file from the result
iexec task show $TASK_ID --path "computed.json"

Real-World Examples

Example 1: Data Analysis System

ts
// 1. Protect sensitive dataset
const { 
address
:
datasetAddress
} = await
dataProtectorCore
.
protectData
({
name
: 'Customer Analytics Data',
data
: {
customers
: {
'0': {
id
: 1,
purchases
: 1500,
category
: 'premium' },
'1': {
id
: 2,
purchases
: 800,
category
: 'standard' },
'2': {
id
: 3,
purchases
: 2200,
category
: 'premium' },
}, }, }); // 2. Grant access to analytics iApp await
dataProtectorCore
.
grantAccess
({
protectedData
:
datasetAddress
,
authorizedApp
: '0xanalytics...', // Analytics iApp address
authorizedUser
: '0x789abc...',
pricePerAccess
: 3,
numberOfAccess
: 50,
}); // 3. Execute data analysis const
analysisResult
= await
dataProtectorCore
.
processProtectedData
({
protectedData
:
datasetAddress
,
app
: '0xanalytics...',
args
: '--analyze-customer-segments --output-format json',
appMaxPrice
: 10,
});

Example 2: Oracle Price Update

ts
// 1. Protect trading data
const { 
address
:
tradingDataAddress
} = await
dataProtectorCore
.
protectData
({
name
: 'Trading Data',
data
: {
trades
: {
'2024-01-01': {
price
: 50000,
volume
: 100 },
'2024-01-02': {
price
: 51000,
volume
: 150 },
}, }, }); // 2. Grant access to oracle iApp await
dataProtectorCore
.
grantAccess
({
protectedData
:
tradingDataAddress
,
authorizedApp
: '0xoracle...', // Oracle iApp address
authorizedUser
: '0x789abc...',
pricePerAccess
: 5,
numberOfAccess
: 100,
}); // 3. Execute oracle update const
oracleResult
= await
dataProtectorCore
.
processProtectedData
({
protectedData
:
tradingDataAddress
,
app
: '0xoracle...',
args
: '--update-price-feed --asset ETH',
appMaxPrice
: 10,
});

Example 3: Automated Payment Processing

ts
// 1. Protect payment data
const { 
address
:
paymentDataAddress
} = await
dataProtectorCore
.
protectData
({
name
: 'Payment Data',
data
: {
bankAccount
: '1234567890',
routingNumber
: '987654321',
accountHolder
: 'John Doe',
monthlyAmount
: 1000,
}, }); // 2. Grant access to payment iApp await
dataProtectorCore
.
grantAccess
({
protectedData
:
paymentDataAddress
,
authorizedApp
: '0xpayment...', // Payment iApp address
authorizedUser
: '0x789abc...',
pricePerAccess
: 2,
numberOfAccess
: 12, // Monthly payments
}); // 3. Execute payment processing const
paymentResult
= await
dataProtectorCore
.
processProtectedData
({
protectedData
:
paymentDataAddress
,
app
: '0xpayment...',
args
: '--process-monthly-payment',
secrets
: {
1: 'bank-api-key', },
appMaxPrice
: 8,
});

Best Practices

1. Always Grant Access Before Execution

ts
// Grant access first
await 
dataProtectorCore
.
grantAccess
({
protectedData
:
protectedDataAddress
,
authorizedApp
: '0x456def...',
authorizedUser
: '0x789abc...',
pricePerAccess
: 5,
numberOfAccess
: 10,
}); const
result
= await
dataProtectorCore
.
processProtectedData
({
protectedData
:
protectedDataAddress
,
app
: '0x456def...',
appMaxPrice
: 10,
});

2. Monitor Access Usage

ts
// Check access usage regularly
const 
grantedAccess
= await
dataProtectorCore
.
getGrantedAccess
({
protectedData
: '0x123abc...',
authorizedApp
: '0x456def...',
authorizedUser
: '0x789abc...',
});
console
.
log
('Remaining access:',
grantedAccess
.
count
);

3. Use Appropriate Price Limits

ts
// Set reasonable price limits
const 
result
= await
dataProtectorCore
.
processProtectedData
({
protectedData
: '0x123abc...',
app
: '0x456def...',
appMaxPrice
: 10, // Set appropriate limit
});

4. Handle Results Properly

ts
// Store task ID and retrieve results later
const 
result
= await
dataProtectorCore
.
processProtectedData
({
protectedData
: '0x123abc...',
app
: '0x456def...',
appMaxPrice
: 10,
}); // Store task ID for later retrieval const
taskId
=
result
.
taskId
;
// Later, retrieve the result const
taskResult
= await
dataProtectorCore
.
getResultFromCompletedTask
({
taskId
:
taskId
,
});

Next Steps

Now that you understand how to use iApps with protected data: