-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add some docs on Embedded Wallet (#36)
* Add some docs on Embedded Wallet * Rename technical Embedded wallet to WaaS
- Loading branch information
Showing
6 changed files
with
167 additions
and
32 deletions.
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
docs/pages/solutions/technical-references/wallet-as-a-service/01-overview.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Overview | ||
|
||
Sequence WaaS (Wallet as a Service) is an API service that runs on the [AWS Nitro Enclaves](https://aws.amazon.com/ec2/nitro/nitro-enclaves/) platform and allows for secure wallet management. It is the technology that powers the [Embedded Wallet](/solutions/wallets/embedded-wallet/01-overview). | ||
|
||
## Security | ||
|
||
Wallet private keys are stored encrypted using a split responsibility strategy between Sequence and a trusted third party: | ||
|
||
1. Sequence is able to access only the encrypted blobs stored in the database with no means of decryption. | ||
2. A Trusted Third Party owns and operates the [KMS](https://aws.amazon.com/kms/) (AWS' hardware security module) used to encrypt the wallet key data. They have no way to export the key material and no access to the encrypted data itself. | ||
|
||
The WaaS Enclave is the only entity able to use the encrypted wallet data. Its security is guaranteed by: | ||
|
||
1. The AWS Nitro hypervisor generates and signs a cryptographic attestation based on the actually running enclave code. The document includes a PCR0 (a hash of the enclave code) signed by the Amazon Public Key Infrastructure. | ||
2. The KMS operated by the Trusted Third Party specifies a policy that only allows access to the cryptographic operations if the attestation is valid and the PCR0 hash of the enclave matches the expected value. This means that any - even the smallest - change to the enclave will result in a different attestation and PCR0 hash, effectively invalidating it. | ||
3. The enclave code is open source and anyone may audit it and verify that the service uses the exact audited version of the source code. [Learn more about verification](/solutions/technical-references/embedded-wallet/03-enclave-verification). |
43 changes: 43 additions & 0 deletions
43
docs/pages/solutions/technical-references/wallet-as-a-service/02-intents.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Intents | ||
|
||
All user interactions with their account, sessions and wallet are performed through actions called "intents." This page provides details on how they work internally. While it will further your understanding of the entire system as a whole, it is not required as the official SDKs handle all the complexity transparently. | ||
|
||
## What are they? | ||
|
||
At a high level an intent is simply a JSON object specifying the action the user intents to perform and signed using their session key. For example, to sign a message, the client would send the following intent to the WaaS API: | ||
|
||
``` | ||
{ | ||
"version": "0.0.0", | ||
"issuedAt": 1712775116, | ||
"expiresAt": 1712775416, | ||
"name": "signMessage", | ||
"data": { | ||
"wallet": "0x7B7D7BA79542584f9AeF539F6696c070a4e1Ced6", | ||
"network": "1", | ||
"message": "0x48656c6c6f2c20686176652061206e69636520646179" | ||
}, | ||
"signatures": [ | ||
{ | ||
"sessionId": "0x01047de46debeeb83e1270b80ae65996ea64ad2c033e330cfffe9b725bf078423140124dce0cfe0cab9a61b385ca74fe77cd5e8a7147bfd87052f334cfbadc45c79a", | ||
"signature": "0x28ec6ddcdbc0987a99dde19792ff0c9be69ad2be873fb9351353171b74d2df3380f0ffcae2b8cb37a0659e374859420500b4399a2aab0209ee7919aaea575ac7" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Let's take a closer look at the intent anatomy, starting from the bottom. | ||
|
||
## Signatures | ||
|
||
Normally a single signature is specified, representing the user's session. A session here is nothing more but a locally created assymmetric key pair where the public key becomes part of the `sessionId` while the private key never leaves the device. As it gives anyone access to the user's wallet, it must be stored securely, in a secure on-device enclave whenever possible. The session must be registered with the WaaS API before use. | ||
|
||
The signature is an EIP-191 of the canonical representation of the intent (keys ordered alphabetically, without whitespace) JSON without the `signatures` field. | ||
|
||
## Name and data | ||
|
||
These depend on the intent in question and will be different for each intent. The type of the intent and thus the data it contains is specified by the name. | ||
|
||
## Timestamps | ||
|
||
These are unix timestamps of when the intent becomes and stops being valid. They are validated by the API to ensure old intents cannot be reused again in the future. |
68 changes: 68 additions & 0 deletions
68
.../solutions/technical-references/wallet-as-a-service/03-enclave-verification.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Enclave verification | ||
|
||
The security of an WaaS enclave depends on being able to independently verify the integrity of the code that powers it. | ||
|
||
You have two options when it comes to verifying the integrity of a running enclave depending on your risk tolerance and technical means. | ||
|
||
## The easy way | ||
|
||
### Prerequisites | ||
|
||
The verification procedure will currently only work on Linux or macOS systems. Additionally, you need to have a recent versions of the following tools installed and configured locally: | ||
|
||
- [Docker](https://www.docker.com/) | ||
- git | ||
- make | ||
|
||
### Find out the PCR0 | ||
|
||
Open the following page in the browser or through curl: [https://waas.sequence.app/status](https://waas.sequence.app/status). | ||
|
||
Note the values of `ver` and `pcr0` - these will be needed later. | ||
|
||
Sample output might look like: | ||
|
||
``` | ||
{ | ||
"healthOK": true, | ||
"startTime": "2024-04-08T17:06:20.177514099Z", | ||
"uptime": 167168, | ||
"ver": "v1.1.1", | ||
"pcr0": "77541a3d09cdf2728417c1537d190be0998cc84f8aec95a4f1e823c91a007d97f276c2453be7f653fd73fb862b42fcee" | ||
} | ||
``` | ||
|
||
### Build the enclave file | ||
|
||
1. Clone the repository locally, substituting `v1.1.1` with the value of `ver` from the previous step: | ||
``` | ||
git clone -b v1.1.1 https://github.com/0xsequence/waas-authenticator.git | ||
cd waas-authenticator | ||
``` | ||
2. Run the following command, again substituting the version as before: | ||
``` | ||
make VERSION=v1.1.1 eif | ||
``` | ||
3. Compare the output of the command with the previously noted PCR0 value, for example: | ||
``` | ||
Output written into /out/waas-auth.v1.1.1.eif | ||
BootMeasurement: Sha384 { ... }: {"HashAlgorithm": "Sha384 { ... }", "PCR0": "77541a3d09cdf2728417c1537d190be0998cc84f8aec95a4f1e823c91a007d97f276c2453be7f653fd73fb862b42fcee", "PCR1": "b7ada9ee8a3fa0a2c74c23ddd04a58f0b095d0465327b2d8461b9b81bcbc7236563ff0326c8614fe9205669636955199", "PCR2": "365294f408bcc5913b44110544bb611255d05666f89fd182900330bc117744fa563c2afcf74808b719ac7a29492099c6"} | ||
SHA256 checksum: | ||
3843b48b32b98fa311cbcd1604c0c6931f03c75075212e8bb4c06d02a3d53509 waas-auth.v1.1.1.eif | ||
``` | ||
|
||
Please note that the checksum might differ between runs as it's only used to verify the integrity of the **file**. However, the PCR0 for the same **code** will always be the same, as can be seen in the example above. | ||
|
||
## The hard way | ||
|
||
The above lets us compare the PCR0 of the built enclave file with the "live" enclave. But it's not foolproof. You might notice that such a simple comparison of two values is not real proof. After all, the enclave might have been tampered with and what we see is make believe. Indeed, the PCR0 values for each release are [publicly available](https://github.com/0xsequence/waas-authenticator/releases). | ||
|
||
This is where *cryptographic attestation* comes in. While we haven't yet published tools that would do the validation, it can be performed using [this great guide by AWS](https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html). | ||
|
||
Every enclave request returns the attestation document in a Base64-encoded format in the `X-Attestation-Document` response header. A request might optionally include a `X-Attestation-Nonce` header containing a value that will be signed and included in the attestation document as well. | ||
|
||
For example, you can get the attestation document by running: | ||
|
||
``` | ||
curl -si https://waas.sequence.app/health -H X-Attestation-Nonce:0123456789abcdef | grep x-attestation-document | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Architecture overview | ||
|
||
Sequence Embedded Wallets are native smart contract multisigs, the configuration of the multisig can be seen as a 2/2, both of which are required to sign in order to operate them; each one of the signers protects the wallet from a different facet of possible threats. | ||
|
||
## Signer 1: Sequence Auth | ||
|
||
Sequence Auth provides a simple way to add account creation, login, session management, and wallet support to your app, enabling applications to provide traditional web experiences (e.g. social login, email login, etc.) while providing access to crypto wallets to interact with smart contracts. | ||
|
||
All user and session data is encrypted by a Hardware Security Module operated by a third party. This makes it protected from both external attackers and internal access by Sequence Team or anyone else. **Nobody** can access a user's wallet but the user themselves. | ||
|
||
You won't need to trust us, this is a guarantee you can verify yourself: this service is hosted in a cryptographically attested secure enclave on Amazon Nitro platform. And we offer [publicly available independently audited source code](https://github.com/0xsequence/waas-authenticator), so you can rest assured that it hasn't been tampered with. | ||
|
||
## Signer 2: Sequence Guard | ||
|
||
Sequence Guard is a service hosted by Sequence and contains the other key of the wallets. It's meant to be another line of defense, verifying not only user's _identity_ but also their _intent_. It achieves this in two different ways: | ||
|
||
1 - Limits and allowlists: you can (from the development dashboard) configure what kind of actions are allowed, this means that the guard will only sign transactions within these constraints. For example, you can define that only NFT contract X can be called, and the guard will enforce that no other transactions can take place. | ||
|
||
2 - Authenticating the user: the Sequence Guard will authenticate the user **independently of the Sequence Auth**, it performs this action either by using a 3rd party OAuth 2.0 id token (from Meta, Google, X, etc.) or by directly communicating with the user via email/phone number with an OTP code. The direct communication is not always required and, when it does happen, it's seamless and branded with your project details. | ||
|
||
## Threat model | ||
|
||
With these safeguards in place wallets are **safe** against the following scenarios: | ||
|
||
1. Sequence.app backend is compromised, or guard keys are leaked: in this scenario, the user's identity must still be verified by Sequence Auth. | ||
|
||
2. Sequence Auth is compromised: in this scenario the Sequence Guard protects the wallets, because it independently authenticates the user, an attacker in this scenario wouldn't be able to access any wallets. | ||
|
||
The model also provides partial protection against the scenario: | ||
|
||
3. Partner frontend is compromised, or MITM on the partner side: If an attacker were to be able to vulnerate the frontend of the partner, it could gain access to wallets at the time of login, but it cannot gain access to wallets of users who are currently inactive. This means that recovery from such a scenario is possible, with limited damage. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters