Skip to content

Deploy on Caution-managed infrastructure

Deploy your first application on Caution's fully managed platform using AWS Nitro Enclaves. Your first deployment should take about 10 minutes.

What is fully managed?

Fully managed is a deployment model where Caution hosts and operates the deployment environment end-to-end on Caution-managed infrastructure. For full details, see the fully managed reference.

AWS Nitro support today

Caution currently supports deployments on AWS Nitro Enclaves. We are actively working on support for Intel TDX, AMD SEV-SNP, and TPM 2.0 attestations.

What you need

Before you begin, ensure you have the following:

What you'll need Details
Access code Request access at info@caution.co
Passkey Browser or platform passkey, password manager passkey, or security key or smart card (YubiKey, NitroKey, or LibremKey)
CLI Supported today on Linux (x86_64) or macOS (arm64) (install)
Git For cloning and pushing repositories (install)
Docker With containerd image store enabled (install)
Containerized app Your application must be containerized

Install the CLI

Clone the platform repository and run the automatic installer:

git clone https://git.caution.co/public/platform
cd platform
make install-cli

On every supported platform (Linux/x86_64 and macOS/arm64) this builds the CLI with your local host toolchain, after a one-time acknowledgement that the build is not reproducibility-verified. To build the reproducible StageX CLI instead, run make install-cli-stagex (Linux/x86_64 only). See the CLI README for explicit build targets and verification options.

Create an account

To create an account, you'll need a valid access code and a passkey. You can register in the browser or with the CLI.

If you do not have an access code, request one at info@caution.co.

caution register --alpha-code <your_code>
  1. Go to dashboard.caution.co
  2. Enter your access code
  3. Use your passkey method
  4. Click Continue
  5. Approve Passkey interaction when prompted

Add an SSH key

Add an SSH key so you can authenticate your Caution deployments:

caution ssh-keys add --from-agent

Add an SSH key from the browser dashboard.

Select an application

Deploy your own containerized application, or start with one of the Caution demo apps. For this guide, use hello-world-enclave:

git clone https://git.caution.co/public/demo-hello-world-enclave.git
cd demo-hello-world-enclave

Initialize the application

From your application directory, run the following command to create a caution.hcl and other data required for the application:

caution init

caution.hcl defines how to run your application and which ports to expose. If you're using one of Caution's demo apps, a caution.hcl is already included. caution init generates a template if none exists; customize it for your application. See the caution.hcl reference.

Commit the generated caution.hcl and .caution/deployment.json to your repository. The deployment file stores the Caution app resource ID so CLI commands can infer the target app from the repository.

For your own app, make sure the container builds from the repository root with the standard Docker form:

docker build -f Containerfile .

If you use another file, set containerfile in the build block and replace Containerfile with that path. Caution uses this build shape and does not pass extra build arguments, so public build-time values need to be part of the image inputs. Use Locksmith for secrets.

At minimum, your caution.hcl should specify how to run your application:

enclave "main" {
  unit "default" {
    command = "/app/server"
  }
}

For source verification, add your repository URL:

enclave "main" {
  build {
    app_sources = ["https://git.example.com/myorg/myapp"]
  }
  unit "default" {
    command = "/app/server"
  }
}

Choose HTTP protection before deploying

The generated template leaves http commented out: its ingress port is raw TCP, with no platform-provided TLS. Existing demo configurations may select a different mode; check their http and e2e_encryption blocks.

For a basic HTTPS demo, add this network block inside your existing enclave block, replacing any existing network block. Use your application's listening port and your own domain:

network {
  ingress {
    cidr_ipv4 = "0.0.0.0/0"
    port      = 8080
  }
  http {
    domain = "app.example.com"
    port   = 8080
    # Host TLS termination: e2e_encryption is intentionally omitted.
  }
}

This example selects host TLS, not end-to-end encryption

TLS terminates on the host, which can read application requests and responses. Do not use this mode for traffic that must remain confidential from the host. Deployment verification does not change this transport boundary.

Choose a protected mode before sending sensitive traffic:

  • STEVE (recommended): add e2e_encryption { mode = "steve" } inside http and integrate a STEVE client. Keep plaintext fallback disabled. Requests without STEVE are rejected except for the documented bootstrap/public endpoints.
  • Attested TLS: use the complete linked configuration for ordinary HTTPS clients. Adding only e2e_encryption { mode = "tls" } to the no-egress example above is insufficient: enclave TLS requires egress. Follow its DNS/egress requirements and periodically verify the live attested certificate binding; ordinary HTTPS clients do not verify Nitro evidence themselves.

Configure domain DNS after deployment. Other ingress ports remain raw interfaces and are not protected by the selected HTTP mode.

Add environment variables

For public runtime values, use string literals in unit.env in caution.hcl; no key service or quorum setup is needed. See Public environment variables for an example and how runtime settings differ from build-time inputs.

For secrets, follow Add encrypted secrets before deploying: create a quorum bundle, encrypt the values, package the bundle, policy and ciphertext, and reference them with env::vault.

Skip this step if your application does not need environment variables.

Deploy the application

From your application directory, push the code to Caution:

git push caution main

Caution builds a reproducible enclave image with the standard Docker build and deploys it into the enclave.

Check the lifecycle shown by caution apps get. When the operator's rollout is enabled for new apps, the deployments lifecycle automatically activates a deployment if nothing is live; otherwise a changed push creates a candidate that needs an explicit switch. Legacy apps still replace the running deployment. See Deploy and roll back updates.

Deployment output includes a stable DNS target for the app. If you configured a custom domain in caution.hcl, create a CNAME from that subdomain to the DNS target rather than an A record to the current IP. See Set up a custom domain.

Verify the deployment

From your application directory, reproduce the image and verify that the running enclave matches its expected PCRs:

caution verify

With only one running deployment, this saves verified PCRs to .caution/trusted_hashes.json. With multiple running deployments, explicitly use caution verify -d <deployment>; its trust file is .caution/deployments/<deployment-id>/trusted_hashes.json. Commit the appropriate trust file alongside your other .caution/ files. Secret release must target the same verified deployment; see release and activation. Verification alone does not unlock secrets or prove application readiness.

Next steps

Your application is now running in a verified enclave. Here's what to explore next: