> ## Documentation Index
> Fetch the complete documentation index at: https://docs.turnkey.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Turnkey Verifiable Cloud quickstart

> Run any code in isolated, verifiable secure enclaves powered by Turnkey’s trusted infrastructure.

<Warning>
  Turnkey Verifiable Cloud is currently in Private Beta. Join the waitlist [here](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist).
</Warning>

## Prerequisites

This guide assumes you've been enabled for Turnkey Verifiable Cloud, and you've completed the steps to create an account and an organization
as described in the [account setup](/getting-started/quickstart) section.

⚠️ To be enabled for TVC you will need to get in touch with our team (via Slack, typically) and tell us your new organization ID.
Our team will enable your new organization for TVC and you will be able to see a new "Verifiable Cloud" section appear in the top-level navigation.

## Installation

Install the TVC CLI from crates.io ([`tvc` crate](https://crates.io/crates/tvc)):

```bash theme={"system"}
cargo install tvc
```

## Create your first verifiable app

<Steps>
  <Step title="Login">
    With your new organization ID ready, login through the CLI.

    ```bash theme={"system"}
    tvc login
    ```

    You will be asked to paste in your organization ID, and prompted to add a new generated API key to your organization.

    <Note>
      This step generates an operator P256 keypair locally for you. It is stored in `~/.config/turnkey/orgs/<name>/operator.json`.
      The public key will be used in the following steps.
    </Note>
  </Step>

  <Step title="Create a new TVC app">
    Visit the [TVC dashboard](https://app.turnkey.com/dashboard/tvc) and click on "Create app".

    <Frame>
      <img src="https://mintcdn.com/turnkey-0e7c1f5b/rJTTWYFU15WtHd3K/assets/files/tvc_create-app-dashboard.png?fit=max&auto=format&n=rJTTWYFU15WtHd3K&q=85&s=0dcb19bc3a4ea380ab77f02f6a05c70c" alt="Create app button on the TVC dashboard" width="2626" height="778" data-path="assets/files/tvc_create-app-dashboard.png" />
    </Frame>

    A modal should appear:

    <Frame>
      <img src="https://mintcdn.com/turnkey-0e7c1f5b/6OpGbFFmZylvdVYL/assets/files/tvc_create-app-modal.png?fit=max&auto=format&n=6OpGbFFmZylvdVYL&q=85&s=aeef0b6d9b12dfdb7774733ea11227fd" alt="Create app modal" width="1232" height="928" data-path="assets/files/tvc_create-app-modal.png" />
    </Frame>

    Name your app something identifiable; for this demo it can be `"TVC Hello World"`.
    Paste in your operator public key from the TVC CLI login step, then click "Create new TVC App" to create your app.

    <Accordion title="CLI steps (same functionality as dashboard)">
      Create a local app template by running

      ```bash theme={"system"}
      tvc app init --output <my-app-template>.json
      ```

      This step is purely local, and generates an editable json template for your app to be used during creation.
      Your template will look something like this when first generated:

      ```json theme={"system"}
      {
        "name": "<FILL_IN_APP_NAME>",
        "quorumPublicKey": KNOWN_QUORUM_KEY,
        "externalConnectivity": false,
        "manifestSetId": null,
        "manifestSetParams": {
          "name": "<FILL_IN_MANIFEST_SET_NAME>",
          "threshold": 1,
          "newOperators": [
            {
              "name": "operator-1",
              "publicKey": PUBLIC_KEY_AUTOPOPULATED_FROM_LOGIN
            }
          ],
          "existingOperatorIds": []
        }
      }
      ```

      Name your app something identifiable; for this demo it can be `"TVC Hello World"`.
      Your manifest set is currently just the public key generated during login;
      give it an easy to remember name, such as `"TVC Manifest"`.

      <Warning>
        The CLI has also automatically populated this template with a known quorum key, which is sufficient for
        running verifiable code but not advised for encrypting sensitive data.
      </Warning>

      Create your app in TVC by running

      ```bash theme={"system"}
      tvc app create my-app-template.json
      ```

      This creates your app, and saves its quorum key and manifest settings to the Turnkey Verifiable Cloud platform.
      Check out your new app on the [TVC dashboard](https://app.turnkey.com/dashboard/tvc).
    </Accordion>
  </Step>

  <Step title="Create new TVC deployment">
    Once your app is created, click into it on the [dashboard](https://app.turnkey.com/dashboard/tvc). Click on "Create deployment"
    to start a new deployment for your app.

    <img src="https://mintcdn.com/turnkey-0e7c1f5b/rJTTWYFU15WtHd3K/assets/files/tvc_create-deployment.png?fit=max&auto=format&n=rJTTWYFU15WtHd3K&q=85&s=836d09cb46b362776e9bcf9c374fcf4f" alt="Create deployment button" width="200" data-path="assets/files/tvc_create-deployment.png" />

    This should open a modal with all your deployment settings:

    <Frame>
      <img src="https://mintcdn.com/turnkey-0e7c1f5b/6OpGbFFmZylvdVYL/assets/files/tvc_deployment-modal.png?fit=max&auto=format&n=6OpGbFFmZylvdVYL&q=85&s=7ae0999d8c87eb0474fce9c956819148" alt="Deployment settings modal" width="1182" height="1608" data-path="assets/files/tvc_deployment-modal.png" />
    </Frame>

    If you do not have your own app, try our helloworld template:

    * **Container Image URL**: `ghcr.io/tkhq/helloworld:latest@sha256:c9c18f78b05d29ebfc2c60ab7143df4b0a808765a34d6a88bbf99523f473cafd`
      * If you are bringing private container images, TVC supports uploading pull secrets by encrypting them to a known public key. This will be used by TVC infrastructure to access your container images. Read more about pull secrets [here](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/).
    * **Executable Path**: `/tvc_app`
    * **Executable Args**: `--host 0.0.0.0 --port 3000`. These arguments are passed to the executable on startup. Here we are telling the `helloworld` binary to start on port 3000
    * **Public ingress port**: `3000`. This is the port that will be exposed to the outside world
    * **Health check port**: `3000`. Our `tvc_app` binary answers healthchecks on `/health` on the same port (3000)
    * **Health check type**: `HTTP`.
    * **Executable digest**: the hash of the binary file inside the container. For our helloworld example this should be `cbe01169428f144086bfaef348bbf3db70f9217628996cafd2ecb85d5f2b47a1`. You can compute it locally with:
      ```
      # Pull the container image, create a "tmp-extract" container, and extract our helloworld binary
      docker create --name tmp-extract ghcr.io/tkhq/helloworld@sha256:c9c18f78b05d29ebfc2c60ab7143df4b0a808765a34d6a88bbf99523f473cafd /bin/true \
            && docker cp tmp-extract:/tvc_app ./tvc_app \
            && docker rm tmp-extract

      # Locally compute the digest of the binary file
      sha256sum ./tvc_app
      cbe01169428f144086bfaef348bbf3db70f9217628996cafd2ecb85d5f2b47a1
      ```
      This digest will be to ensure TVC is running the code you expect.

    When ready, click "Deploy TVC App"!

    <Accordion title="CLI steps (same functionality as dashboard)">
      Start with this local-only step, which generates a deployment template:

      ```bash theme={"system"}
      tvc deploy init
      ```

      The generated JSON file is named by its time of creation, but you can name it anything by specifying
      a name after the `--output` flag. Open it and fill in each field:

      * `appId` is populated with the last app you created. You may edit it to be the id of any app you've created in the past.
      * `pivotContainerImageUrl`: link to a public image. For this demo, feel free to use
        ```json theme={"system"}
        "ghcr.io/tkhq/helloworld@sha256:c9c18f78b05d29ebfc2c60ab7143df4b0a808765a34d6a88bbf99523f473cafd"
        ```
      * `pivotPath`: location of your binary in the container. Use `"/tvc_app"` for the demo app.
      * `pivotArgs`: leave this empty unless you have arguments to pass to your application
      * `expectedPivotDigest`: for the demo, use
        ```json theme={"system"}
        "cbe01169428f144086bfaef348bbf3db70f9217628996cafd2ecb85d5f2b47a1"
        ```
      * `pivotContainerEncryptedPullSecret`: your pull secret, if your container image isn't public. Delete this field otherwise.
      * `publicIngressPort`: 3000
      * `healthCheckPort`: 3000
      * `healthCheckType`: `TVC_HEALTH_CHECK_TYPE_HTTP`

        For an arbitrary app, compute the expected digest with

        ```bash theme={"system"}
        docker create --name tmp-extract <container URL> /bin/true \
          && docker cp tmp-extract:/path/to/binary ./binary \
          && docker rm tmp-extract

        sha256sum ./binary
        ```

      Deploy to TVC by running

      ```bash theme={"system"}
      tvc deploy create deploy-YYYY-MM-DD.json [--pull-secret <path-to-pull-secret>.json]
      ```

      Find the newly created deployment by clicking into your app on the [TVC dashboard](https://app.turnkey.com/dashboard/tvc).
    </Accordion>
  </Step>

  <Step title="Approve deployment">
    By design, your deployment is not live yet. TVC requires approvals by the manifest set to fully deploy your application.
    Your app should be at the `Approve` stage on the dashboard:

    <img src="https://mintcdn.com/turnkey-0e7c1f5b/rJTTWYFU15WtHd3K/assets/files/tvc_approve-stage.png?fit=max&auto=format&n=rJTTWYFU15WtHd3K&q=85&s=484eab33ff8050cd3e4acc4b0da0367b" alt="Approve stage on the dashboard" width="400" data-path="assets/files/tvc_approve-stage.png" />

    For this demo app, your manifest set is the public key you created at login. To approve your deployment, use the TVC CLI:

    ```bash theme={"system"}
    tvc deploy approve \
      --deploy-id <DEPLOYMENT_UUID_FROM_CREATING_DEPLOYMENT> \
      --operator-id <OPERATOR_UUID>
    ```

    You may find your operator ID by clicking into your app, then under **Manifest Operators**:

    <img src="https://mintcdn.com/turnkey-0e7c1f5b/hMEub4DsF9TS6_lc/assets/files/tvc_manifest-operators.png?fit=max&auto=format&n=hMEub4DsF9TS6_lc&q=85&s=2d8915b307709ae3679bda9f54ced7d7" alt="Manifest Operators in app page" width="200" data-path="assets/files/tvc_manifest-operators.png" />

    This command generates an approval from the public keys created in step 1.
    If you didn't change anything during the demo, that should be the only required approval from your manifest set.

    In the dashboard you will see the "stage" transition to "LIVE". This means everything is done on your side. You can look at the deployment details in the recap table on on the individual deployment page to know whether your deployment is coming up healthy and whether it's receiving traffic.

    <img src="https://mintcdn.com/turnkey-0e7c1f5b/5mE0UREXlx4Xao8T/assets/files/tvc_live_deployment_details.png?fit=max&auto=format&n=5mE0UREXlx4Xao8T&q=85&s=30d14335b028262902134b2b22ff7451" alt="Deployment details when LIVE" width="620" data-path="assets/files/tvc_live_deployment_details.png" />

    Our infrastructure automatically provisions network ingress for your application. You can visit `https://app-<YOUR_APP_UUID>.turnkey.cloud` to interact with it. If you used our `helloworld` template, try visiting `/time` in your browser!
  </Step>
</Steps>

## Next steps

Once the deployment is approved, your app can serve traffic and produce App Proofs, which are cryptographic
signatures that prove TVC is running the correct, expected software on a legitimate AWS Nitro Enclave. Learn
more about app proofs in [our documentation](/security/turnkey-verified#app-proofs).

If you are not yet signed up for Turnkey Verifiable Cloud, join the waitlist
[here](https://www.turnkey.com/turnkey-verifiable-cloud#waitlist)!
