Caution is backed by Y Combinator. Learn more.

All posts

Running proprietary software on confidential data

TL;DR

A customer wants to use proprietary software without exposing its confidential data to the vendor. The vendor wants to provide that software without distributing its source code or binary.

You can meet both requirements by running the software inside a hardware-isolated enclave and restricting where it can send customer data. The customer can verify those restrictions without seeing the proprietary implementation.

View the demo code

  1. The confidentiality gap in ordinary software delivery
  2. Verify the safeguards without exposing the software
  3. What each side needs to trust
  4. Where the software meets the data
  5. Verify the jail without inspecting the program
  6. Pin the binary without distributing it
  7. What the customer checks
  8. Only the customer can query this instance
  9. From proof of concept to production
  10. A reusable pattern on Caution

The confidentiality gap in ordinary software delivery

When a company sends data to a software vendor for processing, the vendor usually has the technical ability to read it, even when that data is encrypted in transit and at rest. The application needs plaintext to do its work, and the operator of a conventional server can inspect that data in memory while it is in use. Access policies, audits and legal agreements constrain what the vendor is allowed to do. They do not remove that technical access, which can lead to deliberate misuse or accidental exposure.

Running the software on the customer’s infrastructure reverses the problem. The customer keeps its data, but now holds a copy of the vendor’s intellectual property in the form of a compiled binary. Withholding the source code does not prevent reverse engineering. The compiled binary can still be copied, disassembled and decompiled. It may not reveal the original source exactly, but it still gives the customer an implementation to study and reverse engineer.

Imagine a company selling a flight simulator. Its model is the product: years of tuning, and the thing its competitors would most like to copy. Its customer is a rocket startup whose vehicle designs are commercially sensitive. The startup wants the simulator without giving the vendor access to its designs. The vendor wants to sell access without distributing its implementation.

Both companies want the collaboration to work. Neither needs access to the other’s intellectual property or data, but conventional hosting exposes either the customer’s data to the vendor or the vendor’s implementation to the customer. The usual compromise is to rely on contracts to restrict how that access is used.

Those agreed confidentiality boundaries can also be enforced in the system itself. The following demo shows how, using a flight simulator hosted on Caution.

Verify the safeguards without exposing the software

Verifiable compute can sound as though it requires every part of an application to be open source. If the customer must inspect and rebuild the code that handles its data, proprietary software appears to be ruled out.

The alternative is to make the confinement layer verifiable while keeping the program’s business logic confidential. This layer is the code that restricts how the program accesses data and communicates. Caution makes this straightforward to deploy without building custom enclave infrastructure.

In our flight simulator example, the public confinement layer is a small Caution app called the broker, which passes customer requests to the simulator and returns the results. Because its code is public, the customer can check whether it saves request contents, writes them into logs, or sends them anywhere other than the intended processing path. That review includes how results are returned: through the customer’s encrypted connection, not to the vendor.

The broker also starts the proprietary binary inside a jail, so the program can process the customer’s input but cannot send it anywhere except back through the broker.

These restrictions are part of the public code and configuration that the customer reviews and rebuilds. Attestation then checks that this reviewed image is the one running inside the enclave. The customer is checking the code that enforces the restrictions, rather than accepting the vendor’s assurance that the program runs in a jail.

The private layer is the vendor’s simulator. Its source code and executable remain private, while the customer can inspect and verify the restrictions around it. Both companies still rely on the enclave platform, operating system and confinement code doing their jobs.

What each side needs to trust

The customer needs answers to three different questions:

  1. Does the confinement deserve trust? That requires reviewing the broker, its jail and the deployment configuration to check that the program has no external network access or writable disk, and that results return only through the customer’s encrypted connection.
  2. Are the reviewed safeguards actually running? That requires reproducing the enclave image and checking hardware-signed attestation against the expected measurements.
  3. Who is allowed to use the simulator? That requires authorization, separate from attestation.

The vendor’s main question is whether the customer can obtain the binary. The vendor verifies the enclave before uploading, so the binary is encrypted to the reviewed broker and decrypted only inside the enclave. The broker offers no way to read it back, and the customer can only send requests to the simulator.

The vendor’s host is outside the trust boundary. It can relay, delay or drop traffic, and it can stop the enclave. Under the enclave and transport security assumptions, it cannot read the protected payloads, modify them undetected or inspect enclave memory. Traffic metadata remains visible.

Where the software meets the data

The enclave runs on the vendor’s cloud, but hardware isolation keeps the surrounding host out of its memory. Both companies verify the enclave before sending anything confidential to it.

The vendor uploads its binary through STEVE, Caution’s attested, end-to-end encrypted transport. The customer sends its designs through the same kind of protected connection and receives the results that way. STEVE binds the encrypted session to the enclave’s verified identity, rather than merely encrypting traffic to a server the vendor controls.

The simulator and the designs meet in plaintext inside the enclave. The broker sends the results only to the customer, over an encrypted connection. The customer never receives a copy of the simulator. Outside the enclave, the host relays only ciphertext.

The enclave image, broker, jail and configuration are verifiable. Only the simulator binary is opaque: its hash is pinned, but its implementation remains private.

Verify the jail without inspecting the program

The enclave protects the workload from its host. It does not, by itself, protect the customer’s data from the program processing it. The broker therefore starts the simulator inside a jail.

In the demo, that means an isolated network namespace, an empty filesystem, an unprivileged user and a system-call filter. The program cannot open an outbound network connection or a host-facing vsock connection. It has no writable disk, and its standard input, output and error streams are redirected to /dev/null. If a required confinement step fails, the broker refuses to start it.

The program’s intended communication path is a socket handed to it by the broker. The broker forwards authorized customer requests over that socket and returns the answers through the customer’s encrypted connection. The deployment exposes only the STEVE-fronted broker port, not the simulator’s internal port, and permits no outbound network access.

Why the enclave also needs a jail

The enclave protects the workload from the host. The jail restricts what the proprietary program can do with the customer’s data. Both are needed because the program must read that data to process it.

Pin the binary without distributing it

The vendor puts the simulator’s SHA-256 hash in caution.hcl, alongside the hash of the customer’s authentication token. Both are passed to the broker as arguments, so they are part of the measured image. The proprietary binary is kept out of the enclave image that the customer rebuilds.

After verifying the enclave, the vendor uploads the binary. The broker hashes the uploaded bytes and compares the result with the configured pin. A mismatch is rejected. On a match, it copies the bytes into a sealed in-memory file and executes that file inside the jail. The seals prevent the checked executable from being changed between validation and execution.

The hash identifies the approved executable; it does not describe or validate its behavior. It prevents a different binary from being loaded under the same reviewed configuration. A software update requires a new pin and a deployment the customer must approve again.

For demonstration purposes, the repository includes a sample simulator. A real vendor would keep its implementation in a separate, private repository and supply only the hash to the shared configuration.

What the customer checks

The customer reviews the broker’s upload handling, authorization, request relay and jail, together with the build recipe and deployment configuration. It checks the binary pin, confirms that the token hash is its own, and checks that there is no development-mode bypass, outbound network access or exposed simulator port.

The deployment configuration makes several of those choices explicit:

enclave "default" {
  network {
    http {
      port = 8080
      e2e_encryption {
        mode = "steve"             # encrypted to the enclave
      }
    }
    # no egress block: no outbound calls
  }

  unit "default" {
    command = "/usr/bin/broker"    # no --dev: always jailed
    args = [
      "--payload-sha256",      "<simulator hash>",
      "--client-token-sha256", "<customer token hash>",
      "--listen",              "127.0.0.1:8080",
    ]
  }
}

The customer then runs caution verify. The verification workflow rebuilds the enclave image from the deployment revision and compares the expected measurements with signed evidence from the live enclave. The customer does not need the simulator to reproduce this image because it is loaded later, under the broker’s hash check.

The demo client uses the verified measurements for its STEVE connection. That ties the review to the destination receiving the data. If a deployment changes those measurements, the client refuses to connect until the customer approves the new version.

Only the customer can query this instance

Before deployment, the customer generates a random authentication token and gives the vendor only its hash. The vendor pins that hash in the configuration, and the customer verifies it before connecting.

Every simulator request carries the token inside STEVE’s encryption. The broker checks it and removes it before forwarding the request. The simulator never sees the credential, and the vendor cannot obtain it from host traffic or from the pinned hash.

The vendor can upload the approved binary, but without the customer’s token it cannot query this running instance. Operating the software does not require access to the customer’s designs or results.

From proof of concept to production

In conventional hosting, the vendor can inspect the customer’s plaintext data directly. Here, the enclave protects that data from the host, and the jail restricts where the simulator can send it. Some indirect leakage remains: the host can observe response sizes and timing, and a malicious simulator could deliberately use them to reveal information. The broker could reduce that exposure by padding responses and returning them on a fixed schedule. Those additional controls are not implemented in this demo.

The demo’s jail is deliberately small and readable. It uses the enclave’s Linux kernel and a system-call denylist. For production, we would harden and review that boundary, considering an additional isolation layer such as gVisor and a narrower system-call allowlist. Enclave hardware, firmware and attestation roots remain part of the trust assumptions.

The aim is to preserve the confidentiality of the implementation and the data used to run it. It does not hide everything that can be learned from the simulator’s intended outputs, or establish that its simulations are accurate.

A reusable pattern on Caution

The same arrangement can be adapted to proprietary models, pricing engines and scoring systems: one company supplies software it cannot distribute, and another supplies data it cannot disclose to the operator.

The broker is an ordinary Caution app: a Containerfile describes its build, caution.hcl declares its configuration, and a Git push deploys it. Caution handles enclave provisioning and deployment, supplies the attestation and verification workflow, and provides STEVE for encrypted communication with the verified enclave.

The workload-specific part is the broker’s confinement and authorization policy. Companies can adapt that layer and their proprietary program to a new use case without building a separate enclave platform or transport protocol.

Explore the broker implementation and follow the vendor and customer workflows in demo-conf-processing.

The customer needs to see the code that enforces the confidentiality boundary, not necessarily the implementation running inside it. The vendor keeps its software, the customer keeps its data, and both can check how their agreement is enforced.

If you’re considering this pattern for your own software, talk to our team about your confidentiality requirements and deployment constraints.