Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
42a4ade
feat: add Tinfoil as a second enclave deployment target
koenvanderveen Sep 15, 2026
212c17d
chore: drop the duplicated tinfoil release workflows
koenvanderveen Sep 15, 2026
be86401
refactor: group attestation and evidence into packages
koenvanderveen Sep 15, 2026
f42a02f
refactor: move tee_token into evidence/
koenvanderveen Sep 15, 2026
1418100
docs: split the enclave deployment docs by concern
koenvanderveen Sep 16, 2026
00b2084
docs: split the attestation guarantees by deployment target
koenvanderveen Sep 16, 2026
fed35a1
feat: bind the enclave's runtime facts into its Confidential Space token
koenvanderveen Sep 16, 2026
b1b9126
feat: attest the enclave's runtime facts on Tinfoil too
koenvanderveen Sep 16, 2026
97d5621
fix: read the pushed image digest reliably in tinfoil-release
koenvanderveen Sep 16, 2026
e5d100e
docs: drop the offline row from the target comparison
koenvanderveen Sep 16, 2026
1c32550
docs: drop the tinfoil online-requirement weakness paragraph
koenvanderveen Sep 16, 2026
3a071ad
docs: frame the freshness gap as revocation, and list the todo
koenvanderveen Sep 16, 2026
d4c751a
docs: replace the undefined phrase "workload channel"
koenvanderveen Sep 16, 2026
9828fe6
docs: rewrite security.md section 6 with the write-doc rules
koenvanderveen Sep 16, 2026
77997cc
docs: rewrite security.md section 6 again, with the updated rules
koenvanderveen Sep 16, 2026
abd16cc
docs: name the replay limitation as current, with its assumptions
koenvanderveen Sep 16, 2026
146832d
feat: an appraisal policy must pin the image digest and data owners
koenvanderveen Sep 16, 2026
86641d6
feat: require expected_email on an appraisal policy too
koenvanderveen Sep 16, 2026
ed2c47b
docs: move the appraisal rules into 6.0
koenvanderveen Sep 16, 2026
b3a448f
docs: fix the order of the Tinfoil steps, and write the joins
koenvanderveen Sep 16, 2026
59d6dea
docs: correct why Tinfoil needs a different binding
koenvanderveen Sep 16, 2026
9bfd201
feat: a double-blind eval demo on a Tinfoil enclave
Sep 18, 2026
dc7121e
fix: make the double-blind eval demo run on a live Tinfoil enclave
Sep 18, 2026
a5a5d9b
feat: signed job receipts for Tinfoil enclaves, logged on Rekor
koenvanderveen Sep 23, 2026
17d2045
chore: pin syft-enclave v0.1.15 image in the Tinfoil configs and demo
koenvanderveen Sep 23, 2026
17f5a2c
fix: ship the error when a receipt cannot be signed, and wait for the…
koenvanderveen Sep 23, 2026
4969200
chore: pin syft-enclave v0.1.17, released as v0.1.17 and v0.1.18
koenvanderveen Sep 23, 2026
186c2bf
fix: deliver job results and their receipt together
koenvanderveen Sep 24, 2026
3e22aed
chore: pin syft-enclave v0.1.19, released as v0.1.19 and v0.1.20
koenvanderveen Sep 24, 2026
cc943be
feat: receipts as in-toto statements, with claims written by the job
koenvanderveen Sep 25, 2026
ee74735
fix: hash only the adapter's own files in the eval job
koenvanderveen Sep 25, 2026
6f42552
chore: pin syft-enclave v0.1.21, released as v0.1.21 and v0.1.22
koenvanderveen Sep 25, 2026
f046ee2
feat: bind the run key to a Tinfoil report in every receipt
koenvanderveen Sep 29, 2026
443735b
docs: say once where Tinfoil configs live and are released from
koenvanderveen Sep 29, 2026
eb953d5
chore: rename double-blind-eval notebooks folder to double-blind-eval…
koenvanderveen Sep 29, 2026
69d1127
feat: name the base weights by their modelwrap root hash in the receipt
koenvanderveen Sep 29, 2026
ec03708
Merge origin/dev into koen/tinfoil-deployment
koenvanderveen Sep 29, 2026
f771c6c
test: resolve the syft_bg temp dir so paths match on macOS
koenvanderveen Sep 29, 2026
7425fd3
docs: tidy the attestation endpoint docs added in the dev merge
koenvanderveen Sep 29, 2026
165591a
docs: say how to reach the enclave's HTTP endpoints on each target
koenvanderveen Sep 29, 2026
3a160de
Merge remote-tracking branch 'origin/koen/tinfoil-dbe-demo' into koen…
koenvanderveen Sep 29, 2026
2ccab86
feat: request the eval job's logs, released only if it fails
koenvanderveen Sep 29, 2026
709ac58
Merge origin/koen/tinfoil-dbe-receipts into koen/tinfoil-deployment
koenvanderveen Sep 29, 2026
e8fd856
fix: check receipt approvals against the submission that ran
koenvanderveen Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ test_suite_output.log
*ailuminate_prompts.csv
*safety_prompts*.csv
!notebooks/enclave/gemma/data/safety_prompts*.csv
# double-blind-eval-w-receipts notebooks: prompts come from OpenMined/double-blind-eval-bench
# and the adapter from HuggingFace, so nothing canonical is checked in here.
*dbe_prompts*.csv
dbe-adapter/
notebooks/e2e/sales_mock.csv
notebooks/e2e/sales_private.csv
notebooks/e2e/readme.mdpackages/syft-bg/docs/sync-service.md
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

137 changes: 137 additions & 0 deletions notebooks/enclave/double-blind-eval-w-receipts/SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Running the double-blind eval demo

A benchmark owner and a model owner each upload half of an evaluation into a Tinfoil enclave. Both
approve the job, the enclave runs it, and only the benchmark owner reads the results. The two
notebooks in this folder are the two parties; everything else on this page is the operator's job,
done once before either notebook is opened.

## What you need

Three Google accounts: one for the enclave, one per party. The enclave reaches Drive with a token
you register as a Tinfoil secret, and each party authenticates through Colab.

You also need the `tinfoil` CLI and an admin API key from the Tinfoil dashboard under **Settings →
API Keys → Admin keys**. Log in once with `tinfoil login --api-key admin_...` and check it with
`just tinfoil-whoami`. Deploying needs that key; publishing a release does not.

Run every `just` command below from `packages/syft-enclave/`.

## 1. Reset both parties' state

Wipe each data owner's SyftBox before you deploy, not after. The enclave caches its peers' Drive
folders when it boots, so clearing them afterwards leaves it peered with folders that no longer
exist.

```bash
just delete-syftbox benchmark_owner@openmined.org ../../credentials/token_benchmark_owner.json
just delete-syftbox model_owner@openmined.org ../../credentials/token_model_owner.json
```

Without a token file to hand, each notebook has a commented cell under Step 0 that calls
`delete_syftbox()` from Colab instead.

The enclave needs no reset: Tinfoil Containers have no persistent disk, and the enclave wipes its
own state on every boot.

## 2. Deploy the published release

Two releases of [`OpenMined/syft-enclave-tinfoil`](https://github.com/OpenMined/syft-enclave-tinfoil)
are already published. They run the same image, and differ only in whether each job's outputs carry a
signed receipt:

| Release | Config | Receipts |
| --------- | ----------------------------- | -------- |
| `v0.1.21` | `tinfoil-config.yml` | off |
| `v0.1.22` | `tinfoil-config-receipts.yml` | on |

Deploy one of them as it stands. Skip to step 5 only if you changed the enclave image or its config.

```bash
just tinfoil-deploy v0.1.22 enclave@openmined.org
```

Both configs pin `benchmark_owner@openmined.org` and `model_owner@openmined.org` as
`SYFT_ENCLAVE_DATA_OWNERS`, which is what makes a job wait for two approvals instead of one. The
value is measured, so each party's attestation checks it against the release. Other parties need a
config with their emails, and so a new release.

## 3. Check the enclave is attesting

```bash
just tinfoil-attest syft-enclave.openmined.containers.tinfoil.dev
```

If it fails, run `just tinfoil-why` first — the control plane's `error_message` has named the cause
in every failure so far. [`docs/tinfoil_troubleshooting.md`](../../../packages/syft-enclave/docs/tinfoil_troubleshooting.md)
covers the rest.

## 4. Run the two notebooks

Open both in Colab, one per account:

- [`1. DO-benchmark-owner-dbe.ipynb`](1.%20DO-benchmark-owner-dbe.ipynb) — uploads the prompts,
submits the job, reads the results, and logs the receipt on Rekor
- [`2. DO-model-owner-dbe.ipynb`](2.%20DO-model-owner-dbe.ipynb) — uploads the adapter, approves the
job, sees no results

Set the same five constants in both, in the cell under **Setup**:

```python
ENCLAVE_EMAIL = "enclave@openmined.org"
BENCHMARK_OWNER_EMAIL = "benchmark_owner@openmined.org"
MODEL_OWNER_EMAIL = "model_owner@openmined.org"
TINFOIL_REPO = "OpenMined/syft-enclave-tinfoil"
TINFOIL_TAG = "v0.1.22"
IMAGE_DIGEST = "sha256:c0a492675e116429e2cc3241beaae84da8fb953a6980abdea4ee2df6cfc88fbc"
```

`TINFOIL_TAG` and `IMAGE_DIGEST` are what the parties check the enclave against, so they must match
the release you deployed. The digest above is the one both `v0.1.21` and `v0.1.22` pin; after a
republish, use the one `just tinfoil-build` printed.

Then run both notebooks top to bottom. They wait on each other four times, and a card in the
notebook says so each time. Cells that wait print a 🟠 line and tell you to re-run them.

The evaluation takes a little over two minutes, measured on a run against this release: the enclave
installs PyTorch, downloads the base model, and generates on two CPUs. A job is killed at 600
seconds, so there is room to spare.

## 5. Republish, after changing the image or config

Everything in `tinfoil/tinfoil-config.yml` is measured, so any edit to it — or to the enclave image
— needs a new release before it can be deployed.

```bash
just tinfoil-build v0.1.23 # build, push, pin the digest in both configs
just tinfoil-release v0.1.23 # receipts off
just tinfoil-release v0.1.24 tinfoil/tinfoil-config-receipts.yml # receipts on
just tinfoil-deploy v0.1.24 enclave@openmined.org
```

Each `tinfoil-release` opens a pull request on the config repo and waits until you merge it. Then it
publishes, which takes about a minute to compute the measurement. Keep the digest `tinfoil-build`
printed, and put it in both notebooks along with the tag you deployed.

A release is a signed GitHub release and a transparency-log entry, so it cannot be unpublished.
Number versions with that in mind. To go back to an earlier one without moving "latest":

```bash
just tinfoil-relaunch v0.1.21 --promote-release=false
```

## Giving the model a GPU

The demo runs TinyLlama-1.1B on CPU because `tinfoil-config.yml` sets `gpus: 0`. The model owner
notebook carries a commented `ADAPTER_REPO` line for the adapter the
[double-blind-eval](https://github.com/tinfoilsh/double-blind-eval) demo uses, which targets
gemma-4-31B-it and needs a GPU. Switching to it means raising `gpus:` in the config, which is a
config change, so follow step 5.

## Further reading

- [`docs/tinfoil_deployment.md`](../../../packages/syft-enclave/docs/tinfoil_deployment.md) — the
deployment mechanics in full
- [`docs/security.md`](../../../packages/syft-enclave/docs/security.md) §6 — what the attestation
proves
- [`OpenMined/double-blind-eval-bench`](https://github.com/OpenMined/double-blind-eval-bench) — the
prompt set the benchmark owner downloads
3 changes: 3 additions & 0 deletions packages/enclave-model-api-example/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ SYFT_ENCLAVE_DATA_OWNERS,\
SYFT_ENCLAVE_REQUIRE_TEE,\
SYFT_ENCLAVE_FRESH_STATE,\
SYFT_ENCLAVE_USE_ENCRYPTION,\
SYFT_ENCLAVE_ATTESTATION_PROVIDER,\
SYFT_ENCLAVE_TINFOIL_REPO,\
SYFT_ENCLAVE_TINFOIL_RELEASE_TAG,\
SYFT_DEFAULT_JOB_TIMEOUT_SECONDS,\
SYFT_BOOTSTRAP,\
SYFT_BOOTSTRAP_WIF_AUDIENCE,\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ def main() -> None:
poll_interval=settings.poll_interval,
require_tee=settings.require_tee,
fresh_state=settings.fresh_state,
attestation_provider=settings.attestation_provider,
settings=settings,
post_init=lambda: ensure_logs_dataset(client, inference.logs_dataset),
)
logger.info("EnclaveRunner ready — calling runner.run()")
Expand Down
Loading
Loading