diff --git a/docs/Introduction.md b/docs/Introduction.md index ba97735..0b1bcc8 100644 --- a/docs/Introduction.md +++ b/docs/Introduction.md @@ -25,7 +25,11 @@ At a structural level, a Turnkey Organization is comprised of a few core resourc

- resources + resources

diff --git a/docs/Security/Quorum-deployment.md b/docs/Security/Quorum-deployment.md index 9aed595..138575c 100644 --- a/docs/Security/Quorum-deployment.md +++ b/docs/Security/Quorum-deployment.md @@ -11,8 +11,12 @@ Each instance of QOS is configured with a Quorum Set – A group of individuals After the service is launched, QOS responds to attestation requests and waits to receive key shares from QOS Operators or members of the Quorum Set. Once a threshold number of shares have been sent into the enclave it will reconstruct its core secret and launch the application it was provisioned with. This process is outlined in the images below: -

- qos-deployments +

+ qos-deployments

Remote attestation is the process by which core attributes of a machine can be retrieved and verified from a remote location. The enclave’s secure co-processor, in this case AWS’s NSM, observes the enclave as it is being launched and records certain important values such as the hash of the enclave image, the hash of the kernel, and the hash of the boot filesystem. This means that each attestation request verifies that the code actually running in the enclave is only the code we expect to be running. diff --git a/docs/Security/Secure-enclaves.md b/docs/Security/Secure-enclaves.md index 763662b..fc3b3cc 100644 --- a/docs/Security/Secure-enclaves.md +++ b/docs/Security/Secure-enclaves.md @@ -11,8 +11,12 @@ Secure enclaves, also called Trusted Execution Environments, are highly constrai The following outlines the structure of a single enclave application: -

- secure-enclaves +

+ secure-enclaves

In this diagram _Host_ represents a standard AWS virtual machine. We run a basic application that receives traffic from the network and calls into the enclave. This creates a layer of insulation from our most secure environment and offers a convenient place to gather metrics and other operational information about the enclaves. diff --git a/docs/Security/Verifiable-data.md b/docs/Security/Verifiable-data.md index b029a84..f140b13 100644 --- a/docs/Security/Verifiable-data.md +++ b/docs/Security/Verifiable-data.md @@ -12,5 +12,8 @@ By verifying the authenticity of data using cryptographic signatures (no passwor The entire Turnkey architecture including this verifiable data flow is described below:

- turnkey_architecture + turnkey_architecture

\ No newline at end of file diff --git a/docs/getting-started/Examples.md b/docs/getting-started/Examples.md index 10270e1..6e9eaeb 100644 --- a/docs/getting-started/Examples.md +++ b/docs/getting-started/Examples.md @@ -54,7 +54,11 @@ A wallet application showing how users can register and authenticate using passk This demo uses the Turnkey API to create a new [Turnkey Sub-Organization](./Sub-Organizations.md) for each user, create a testnet Ethereum address and send a transaction on Sepolia (ETH testnet).

- demo passkey wallet screenshot + demo passkey wallet screenshot

See https://wallet.tx.xyz (and https://github.com/tkhq/demo-passkey-wallet for the code). @@ -64,7 +68,11 @@ See https://wallet.tx.xyz (and https://github.com/tkhq/demo-passkey-wallet for t A simple application demonstrating how to create sub-organizations, create private keys, and sign with the [`@turnkey/ethers`](https://github.com/tkhq/sdk/tree/main/packages/ethers) signer, using passkeys.

- ethers ui screenshot + ethers ui screenshot

See https://github.com/tkhq/demo-ethers-passkeys for the code. @@ -74,7 +82,11 @@ See https://github.com/tkhq/demo-ethers-passkeys for the code. A similar, simple application demonstrating how to create sub-organizations, create private keys, and sign with the [`@turnkey/viem`](https://github.com/tkhq/sdk/tree/main/packages/viem) signer, using passkeys.

- viem ui screenshot + viem ui screenshot

See https://github.com/tkhq/demo-viem-passkeys for the code. @@ -84,7 +96,11 @@ See https://github.com/tkhq/demo-viem-passkeys for the code. A simple example using Turnkey and Figment to easily automate ETH staking.

- turnkey figment integration + turnkey figment integration

See https://docs.figment.io/recipes/stake-eth-from-turnkey for the code. \ No newline at end of file diff --git a/docs/getting-started/Quickstart.md b/docs/getting-started/Quickstart.md index 26130f9..5e69647 100644 --- a/docs/getting-started/Quickstart.md +++ b/docs/getting-started/Quickstart.md @@ -18,7 +18,11 @@ This quickstart will guide you through Turnkey’s onboarding, adding an API key All API requests require an organization ID. Yours can be located in the user dropdown menu at the top right corner of the dashboard. -Find organization ID +Find organization ID For convenience, it's worth setting this as a permanent shell variable: @@ -50,7 +54,11 @@ When you run this command, Turnkey’s CLI generates an API key pair and **store Navigate to your user page by clicking on "User Details" in the user dropdown menu. -Find user details +Find user details Click on "Create API keys" and follow the prompts to add the generated public API key. You'll be required to authenticate with the same authenticator used during onboarding. After this succeeds, you should be all set to interact with our API. diff --git a/docs/getting-started/email-recovery.md b/docs/getting-started/email-recovery.md index 9a68539..4a0802a 100644 --- a/docs/getting-started/email-recovery.md +++ b/docs/getting-started/email-recovery.md @@ -19,7 +19,11 @@ Email recovery starts with a new activity posted to Turnkey. This activity has t This activity generates a new temporary API key pair (a "recovery credential"), saves the public key in organization data under the target user, and sends an email with the encrypted recovery credential:

- recovery email + recovery email

Initiating a new email recovery require proper permissions via policies or being a parent organization. See [Authorization](#authorization) for more details. @@ -35,7 +39,11 @@ Authorization for email recovery is based on our usual activity authorization: o * `ACTIVITY_TYPE_RECOVER_USER` should be signed by the recovery credential sent via email. Even if not explicitly allowed by policy, a user is always able to add credentials to their own user. This includes adding a new authenticator when authenticated with a recovery credential. In other words, no special policy is needed to make this work: users are able to recover out-of-the-box.

- email recovery authorization + email recovery authorization

diff --git a/docs/integration-guides/export-wallets.md b/docs/integration-guides/export-wallets.md index 96b881a..ff1c9c6 100644 --- a/docs/integration-guides/export-wallets.md +++ b/docs/integration-guides/export-wallets.md @@ -28,7 +28,11 @@ In the rest of this guide we'll assume you are using these helpers. Here's a diagram summarizing the wallet export flow step-by-step ([direct link](/img/wallet_export_steps.png)):

- wallet export steps + wallet export steps

Let's review these steps in detail: @@ -75,7 +79,11 @@ Let's review these steps in detail: Export is complete! The iframe now displays a numbered 3-column grid of words that form the mnemonic, directly to your end user.

- wallet mnemonic + wallet mnemonic

The exported wallet will remain stored within Turnkey’s infrastructure. In your Turnkey dashboard, the exported user Wallet will be flagged as “Exported”. @@ -113,7 +121,11 @@ It works by anchoring export in a **target encryption key** (TEK). This target e The following diagram summarizes the flow:

- export cryptography + export cryptography

The public part of this key pair is passed as a parameter inside of a signed `EXPORT_WALLET` or `EXPORT_PRIVATE_KEY` activity. diff --git a/docs/passkeys/discoverable.md b/docs/passkeys/discoverable.md index 2db5ee9..4392142 100644 --- a/docs/passkeys/discoverable.md +++ b/docs/passkeys/discoverable.md @@ -23,8 +23,16 @@ With terminology out of the way, what is a "discoverable" credential compared to A discoverable credential is a self-contained key pair, stored on the end-user's device. Discoverable credentials are preferred because keys are self-contained, can easily be synced and can be used across devices independently. Crucially for UX, the end-user is able to list their passkeys and choose which device/passkey they'd like to use:

- device selection on Chrome - passkey selection on Chrome + device selection on Chrome + passkey selection on Chrome

With discoverable credentials you don't have to keep track of credential IDs. Your authentication flow can simply be: "prompt the user with passkey authentication", and let the browser or device native UX handle the rest! The downside is you lose some control over these prompts, because they will vary depending on your users' OS and browser. diff --git a/docs/passkeys/integration.md b/docs/passkeys/integration.md index 74bc90a..9272f80 100644 --- a/docs/passkeys/integration.md +++ b/docs/passkeys/integration.md @@ -11,7 +11,11 @@ sidebar_position: 2 A typical passkey flow is composed of 4 main steps, depicted below:

- passkey prompt on Turnkey + passkey prompt on Turnkey

1. Your app frontend triggers a passkey prompt. diff --git a/docs/passkeys/introduction.md b/docs/passkeys/introduction.md index 5e44807..e9664b1 100644 --- a/docs/passkeys/introduction.md +++ b/docs/passkeys/introduction.md @@ -47,8 +47,16 @@ Support also varies by operating system: [this matrix](https://passkeys.dev/devi We believe **it's time to move away from passwords** so we've built Turnkey without them. When you authenticate to Turnkey you'll be prompted to create a new passkey:

- Authenticator selection on Turnkey - Passkey prompt on Turnkey + Authenticator selection on Turnkey + Passkey prompt on Turnkey

Authentication to Turnkey requires a passkey signature. No password needed! diff --git a/docs/passkeys/options.md b/docs/passkeys/options.md index ca45905..80f0366 100644 --- a/docs/passkeys/options.md +++ b/docs/passkeys/options.md @@ -21,10 +21,11 @@ This is the challenge signed by the end-user for registration. During registrati Number of seconds before "giving up". The browser will simply show a timeout popup:

- authenticatorAttachment unspecified + authenticatorAttachment unspecified

-
-
This UI isn't very helpful, so we recommend making the timeout long (5 minutes). The less your users see this, the better. @@ -37,7 +38,11 @@ The `rp` options is an object with 2 fields: `id` and `name`. `rp.id` will show up in the initial registration popup:

- RPID in registration prompt + RPID in registration prompt

`rp.name` doesn't show up in the popup so can be set to anything. We recommend setting it to the correctly capitalized name of your app, in case browsers start showing it in their native UIs in the future. @@ -58,9 +63,9 @@ Turnkey currently supports P256 only. In the near future Turnkey will support RS The `user` field has three sub-fields: - `id`: also known as "user handle", isn't visible to the end-user. We **strongly recommend setting this to a random value** (e.g. `const id = new Uint8Array(32); crypto.getRandomValues(id)`) to make sure a new passkey is created. Be aware: **if you accidentally set this value to an existing user handle, the corresponding passkey will be overridden!**. [This section of spec](https://www.w3.org/TR/webauthn-2/#dictionary-user-credential-params) is clear on the matter: "the user handle ought not be a constant value across different accounts, even for non-discoverable credentials". -- `name`: this will show up in the passkey list modal (see screenshot below). We recommend setting this to something the user will recognize: their email, the name of your app, or potentially leave this up to the user:
+- `name`: this will show up in the passkey list modal (see screenshot below). We recommend setting this to something the user will recognize: their email, the name of your app, or potentially leave this up to the user:

- RPID in registration prompt + RPID in registration prompt

- `displayName`: as far as we can tell this doesn't show up in current browser UIs. It might show up in future iterations so it's best to populate this with the same value as `name`. @@ -122,13 +127,20 @@ The credential ID needs to be passed as a buffer but is returned from registrati If the wrong credential ID is specified, `transports: ["internal"]` is set, browsers error right away because they can enumerate internal credentials. Chrome, for example, displays the following error:

- Chrome error when no matching passkey has been found for the provided Credential ID + Chrome error when no matching passkey has been found for the provided Credential ID

However, if the wrong credential ID is specified without `transports` set (or with other-than-internal `transports` set), browsers won't error right away because they can't enumerate external credentials. They will display an error once the user has pressed their security key or gone through the cross-device passkey flow:

- Chrome error when the credential ID used by the user is not in the allowCredentials list + Chrome error when the credential ID used by the user is not in the allowCredentials list

### `attestation` diff --git a/docs/policy-management/Policy-overview.md b/docs/policy-management/Policy-overview.md index 14941bf..87c8c64 100644 --- a/docs/policy-management/Policy-overview.md +++ b/docs/policy-management/Policy-overview.md @@ -34,8 +34,12 @@ All policies defined within an Organization are evaluated on each request. The i Stated differently: -

- policy_overview +

+ policy_overview

Almost all actions on Turnkey are implicitly denied by default. There are a few exceptions, however: