Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,6 @@ export function getSidebar() {
text: 'Build your first SGX app',
link: '/guides/build-iapp/advanced/build-your-first-sgx-iapp',
},
{
text: 'End-to-end Encryption',
link: '/guides/build-iapp/advanced/protect-the-result',
},
{
text: 'Access Confidential Assets',
link: '/guides/build-iapp/advanced/access-confidential-assets',
Expand Down Expand Up @@ -200,6 +196,10 @@ export function getSidebar() {
text: 'Run iApp without ProtectedData',
link: '/guides/use-iapp/run-iapp-without-ProtectedData',
},
{
text: 'Encrypt results and decrypt them',
link: '/guides/use-iapp/encrypt-and-decrypt-results',
},
{
text: 'Integrate Web3 Messaging',
link: '/guides/use-iapp/integrate-web3-messaging',
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ please see our [CONTRIBUTING.md](CONTRIBUTING.md) guide.**
- Refactor "advanced" section in build-iapp
- Rework src\get-started\protocol\iexec-doracle.md (transfer to guide or
rewrite)
- Talk about encrypting results in use-iapp (link in outputs, iapp generator...)
- Rework src\get-started\protocol\oracle.md (transfer to guide or rewrite)
- Talk about iApp secret
- Improve Guide in build-iapp section - be more clear for builder ( how to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ to use some confidential data to get the full potential of the **Confidential
Computing** paradigm. Check out next chapters to see how:

- [Access confidential assets from your iApp](access-confidential-assets.md)
- [Protect the result](/guides/build-iapp/advanced/protect-the-result.md)
- [Protect the result](/guides/use-iapp/encrypt-and-decrypt-results.md)

<script setup>
import { computed } from 'vue';
Expand Down
156 changes: 0 additions & 156 deletions src/guides/build-iapp/advanced/protect-the-result.md

This file was deleted.

4 changes: 2 additions & 2 deletions src/guides/build-iapp/outputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ Continue building with these guides:

- **[Inputs](/guides/build-iapp/inputs)** - Learn about the different input
types available to your iApp
- **[Encrypt results and decrypt them](/guides/use-iapp/encrypt-and-decrypt-results)** -
End-to-end result protection and local decryption
- **[App Access Control and Pricing](/guides/build-iapp/manage-access)** -
Control who can use your iApp
- **[Debugging Your iApp](/guides/build-iapp/debugging)** - Troubleshoot
execution issues
- **[How to Get and Decrypt Results](/guides/use-iapp/getting-started)** -
User-side result handling
178 changes: 178 additions & 0 deletions src/guides/use-iapp/encrypt-and-decrypt-results.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---
title: Encrypt results and decrypt them
description:
Learn how to encrypt iApp results end-to-end and decrypt them locally using
the iExec SDK
---

# 🔐 Encrypt Results and Decrypt Them

Secure your outputs with end‑to‑end encryption so only you (the beneficiary) can

Check notice on line 10 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L10

[Google.Parens] Use parentheses judiciously.
Raw output
{"message": "[Google.Parens] Use parentheses judiciously.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 10, "column": 60}}}, "severity": "INFO"}
read them. Results leave the enclave and may traverse untrusted storage and
networks; encryption ensures nobody else (operators, storage providers,

Check notice on line 12 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L12

[Google.Semicolons] Use semicolons judiciously.
Raw output
{"message": "[Google.Semicolons] Use semicolons judiciously.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 12, "column": 9}}}, "severity": "INFO"}
intermediaries) can access the content. In this guide, you will generate a key

Check warning on line 13 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L13

[Google.Will] Avoid using 'will'.
Raw output
{"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 13, "column": 60}}}, "severity": "WARNING"}
pair, publish the public key to the Secret Management Service (SMS) — which

Check notice on line 14 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L14

[Google.Parens] Use parentheses judiciously.
Raw output
{"message": "[Google.Parens] Use parentheses judiciously.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 14, "column": 63}}}, "severity": "INFO"}
provides it at runtime to the enclave running your iApp — run tasks with

Check failure on line 15 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L15

[Google.EmDash] Don't put a space before or after a dash.
Raw output
{"message": "[Google.EmDash] Don't put a space before or after a dash.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 15, "column": 56}}}, "severity": "ERROR"}
encrypted results, and download and decrypt them locally.

::: info You don't need to change your application's code or redeploy it to add

Check warning on line 18 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L18

[Google.WordList] Use 'app' instead of 'application'.
Raw output
{"message": "[Google.WordList] Use 'app' instead of 'application'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 18, "column": 40}}}, "severity": "WARNING"}
this feature. :::

## Prerequisites

Before you begin, make sure you have the iExec SDK installed.

::: code-group

```sh [npm]
npm install iexec
```

```sh [yarn]
yarn add iexec
```

```sh [pnpm]
pnpm add iexec
```

```sh [bun]
bun add iexec
```

:::

## 1) Generate your encryption key pair

The beneficiary key pair is the root of trust for result confidentiality. The
public key will be used inside the TEE to encrypt results for the beneficiary;

Check warning on line 48 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L48

[Google.Will] Avoid using 'will'.
Raw output
{"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 48, "column": 12}}}, "severity": "WARNING"}

Check notice on line 48 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L48

[Google.Passive] In general, use active voice instead of passive voice ('be used').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('be used').", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 48, "column": 17}}}, "severity": "INFO"}

Check notice on line 48 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L48

[Google.Acronyms] Spell out 'TEE', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'TEE', if it's unfamiliar to the audience.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 48, "column": 36}}}, "severity": "INFO"}

Check notice on line 48 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L48

[Google.Semicolons] Use semicolons judiciously.
Raw output
{"message": "[Google.Semicolons] Use semicolons judiciously.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 48, "column": 78}}}, "severity": "INFO"}
the private key stays with the beneficiary to decrypt them locally.

Run from your iExec project directory:

```bash
iexec result generate-encryption-keypair
```

This creates two files in `.secrets/beneficiary/`:

```
.secrets/
└─ beneficiary/
├─ <0x-your-wallet-address>_key # PRIVATE KEY (keep safe)
└─ <0x-your-wallet-address>_key.pub # PUBLIC KEY
```

Back up the private key securely. You will only need it locally to decrypt

Check warning on line 66 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L66

[Google.Will] Avoid using 'will'.
Raw output
{"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 66, "column": 39}}}, "severity": "WARNING"}
results.

## 2) Push your public key to the SMS

Check warning on line 69 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L69

[Google.Headings] '2) Push your public key to the SMS' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] '2) Push your public key to the SMS' should use sentence-style capitalization.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 69, "column": 4}}}, "severity": "WARNING"}

The Secret Management Service securely delivers your public key, at runtime, to
the enclave running your iApp. Without this, the iApp cannot encrypt outputs for

Check notice on line 72 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L72

[Google.Contractions] Use 'can't' instead of 'cannot'.
Raw output
{"message": "[Google.Contractions] Use 'can't' instead of 'cannot'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 72, "column": 55}}}, "severity": "INFO"}
you.

Make the public key available to TEEs at runtime:

```bash
iexec result push-encryption-key --tee-framework scone
```

Verify it:

```bash
iexec result check-encryption-key --tee-framework scone
```

## 3) Run the iApp with encrypted results

The --encrypt-result flag instructs the platform to perform envelope encryption
inside the enclave using your public key, so the archive that leaves the TEE is

Check notice on line 90 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L90

[Google.Acronyms] Spell out 'TEE', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'TEE', if it's unfamiliar to the audience.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 90, "column": 74}}}, "severity": "INFO"}
unreadable to others.

Trigger a task and request encrypted outputs:

```bash
iexec app run <0x-app-address> \
--workerpool <0x-workerpool-address> \
--tag tee,scone \
--encrypt-result \
--watch
```

When completed, download the results archive:

```bash
iexec task show <0x-task-id> --download
```

Inside the archive, `iexec_out/result.zip.aes` is encrypted.

Check notice on line 109 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L109

[Google.Passive] In general, use active voice instead of passive voice ('is encrypted').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is encrypted').", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 109, "column": 48}}}, "severity": "INFO"}

Note: Results are encrypted for the task beneficiary. Ensure the beneficiary

Check warning on line 111 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L111

[Google.Colons] ': R' should be in lowercase.
Raw output
{"message": "[Google.Colons] ': R' should be in lowercase.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 111, "column": 5}}}, "severity": "WARNING"}

Check notice on line 111 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L111

[Google.Passive] In general, use active voice instead of passive voice ('are encrypted').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are encrypted').", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 111, "column": 15}}}, "severity": "INFO"}
address is yours to be able to decrypt the archive.

If you extract the archive and try to read the encrypted file, you'll see
unreadable content:

```bash
mkdir /tmp/trash && \
unzip <0x-your-task-id>.zip -d /tmp/trash && \
cat /tmp/trash/iexec_out/result.zip.aes
```

The output will look like:

Check warning on line 123 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L123

[Google.Will] Avoid using 'will'.
Raw output
{"message": "[Google.Will] Avoid using 'will'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 123, "column": 12}}}, "severity": "WARNING"}

```bash
)3XqYvzEfRu<\ݵmm疞rc(a{{'ܼ͛q/[{hgD$g\.kj"s?"hJ_Q41_[{XԚa蘟vEr肽
Յ]9WTL*tdzO`!e&snoL3K6L9%
```

This confirms the results are properly encrypted and unreadable without the
private key.

## 4) Decrypt results locally

Check warning on line 133 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L133

[Google.Headings] '4) Decrypt results locally' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] '4) Decrypt results locally' should use sentence-style capitalization.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 133, "column": 4}}}, "severity": "WARNING"}

Results are encrypted end‑to‑end; only your private key can decrypt them. This

Check notice on line 135 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L135

[Google.Passive] In general, use active voice instead of passive voice ('are encrypted').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('are encrypted').", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 135, "column": 9}}}, "severity": "INFO"}

Check notice on line 135 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L135

[Google.Semicolons] Use semicolons judiciously.
Raw output
{"message": "[Google.Semicolons] Use semicolons judiciously.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 135, "column": 33}}}, "severity": "INFO"}
step restores the plaintext so you can use the output files.

Check failure on line 136 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L136

[Vale.Spelling] Did you really mean 'plaintext'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'plaintext'?", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 136, "column": 19}}}, "severity": "ERROR"}

Use your private key generated in step 1:

```bash
iexec result decrypt iexec_out/result.zip.aes
```

This produces `results.zip`. Extract it to view plaintext outputs:

Check failure on line 144 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L144

[Vale.Spelling] Did you really mean 'plaintext'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'plaintext'?", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 144, "column": 49}}}, "severity": "ERROR"}

```bash
unzip results.zip -d my-decrypted-result
```

And you can see the content of your result file:

```bash
$ cat my-decrypted-result/result.txt
Hello, world!
```

Your results are now decrypted and ready to use.

## Notes and tips

- Keep the private key offline and backed up.
- You can rotate keys by re-running generation and push steps; old tasks remain
decryptable with the old private key.

Check failure on line 163 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L163

[Vale.Spelling] Did you really mean 'decryptable'?
Raw output
{"message": "[Vale.Spelling] Did you really mean 'decryptable'?", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 163, "column": 3}}}, "severity": "ERROR"}
- iApp code does not need changes to enable result encryption; it is enforced by

Check notice on line 164 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L164

[Google.Contractions] Use 'doesn't' instead of 'does not'.
Raw output
{"message": "[Google.Contractions] Use 'doesn't' instead of 'does not'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 164, "column": 13}}}, "severity": "INFO"}

Check notice on line 164 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L164

[Google.Contractions] Use 'it's' instead of 'it is'.
Raw output
{"message": "[Google.Contractions] Use 'it's' instead of 'it is'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 164, "column": 64}}}, "severity": "INFO"}

Check notice on line 164 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L164

[Google.Passive] In general, use active voice instead of passive voice ('is enforced').
Raw output
{"message": "[Google.Passive] In general, use active voice instead of passive voice ('is enforced').", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 164, "column": 67}}}, "severity": "INFO"}
the TEE using the public key from SMS.

Check notice on line 165 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L165

[Google.Acronyms] Spell out 'TEE', if it's unfamiliar to the audience.
Raw output
{"message": "[Google.Acronyms] Spell out 'TEE', if it's unfamiliar to the audience.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 165, "column": 7}}}, "severity": "INFO"}

## Related guides

- [Outputs](/guides/build-iapp/outputs) - Learn how to generate proper outputs
from your iApp
- [Run iApp with ProtectedData](/guides/use-iapp/run-iapp-with-ProtectedData) -

Check failure on line 171 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L171

[Vale.Terms] Use 'protectedData' instead of 'ProtectedData'.
Raw output
{"message": "[Vale.Terms] Use 'protectedData' instead of 'ProtectedData'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 171, "column": 18}}}, "severity": "ERROR"}
Execute iApp with encrypted data inputs
- [Run iApp without ProtectedData](/guides/use-iapp/run-iapp-without-ProtectedData) -

Check failure on line 173 in src/guides/use-iapp/encrypt-and-decrypt-results.md

View workflow job for this annotation

GitHub Actions / vale

[vale] src/guides/use-iapp/encrypt-and-decrypt-results.md#L173

[Vale.Terms] Use 'protectedData' instead of 'ProtectedData'.
Raw output
{"message": "[Vale.Terms] Use 'protectedData' instead of 'ProtectedData'.", "location": {"path": "src/guides/use-iapp/encrypt-and-decrypt-results.md", "range": {"start": {"line": 173, "column": 21}}}, "severity": "ERROR"}
Basic iApp execution methods
- [How to Pay for Executions](/guides/use-iapp/how-to-pay-executions) -
Understanding costs and payment options
- [iApp Generator](/references/iapp-generator) - Build your own confidential
computing applications
2 changes: 2 additions & 0 deletions src/references/iapp-generator.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Once you've built your first iApp, level up with these practical guides:
- **[Inputs](/guides/build-iapp/inputs)** - Handle data inputs
- **[Outputs](/guides/build-iapp/outputs)** - Handle data outputs flow in TEE
environment
- **[Encrypt results and decrypt them](/guides/use-iapp/encrypt-and-decrypt-results)** -
Enable end-to-end result encryption and local decryption
- **[Debugging Your iApp](/guides/build-iapp/debugging)** - Troubleshoot
execution issues
- **[App Access Control and Pricing](/guides/build-iapp/manage-access)** -
Expand Down
Loading