Skip to content

Threat model

This page lists the attacks untrust's hosted paths are built to withstand, who the attacker is in each case, and the control that stops them. It covers the parts of the service that make or record trust decisions: the key-release gate, CI evidence ingest, signed receipts and packs, organization API keys, collectors and the attestation verifiers. Each control below is enforced in the product and locked by a regression test.

The rule behind every row: deny by default, fail closed, and never read an unknown, a SKIP, an ERROR or absent evidence as a pass. The Security model explains the trust roots, signing and tenant isolation in prose; this page is the attacker's view.

Assets

Asset Why it matters
Secrets your key broker releases Released to the wrong workload, they decrypt your data.
Release decisions and the ledger They are the record of who got which key, and why.
Hardware evidence and its verdicts They decide whether a host is trusted at all.
CI evidence (build and IaC receipts) It shows what a pipeline checked before deploying.
Evidence packs Auditors and relying parties rely on them outside the console.
Organization API keys and CI bindings They authenticate uploads and API calls.

Attackers

  • A hostile or compromised host that controls the evidence it sends: certificates, reports, quotes and attestation documents.
  • A stolen or replayed credential: a leaked API key, or a CI token captured from a log.
  • A pipeline you don't trust: a fork, another branch, or another project on the same CI provider.
  • A member of another organization, or a member of yours without the right role or project.
  • A tampered artifact in transit or at rest: an edited pack, receipt or ledger entry.
  • A failing dependency: a vendor certificate service or collateral endpoint that is unreachable or returns errors.

Key-release gate

Your key broker asks untrust whether to release a secret. untrust re-verifies the workload's hardware evidence and records the decision.

Attack Control
Ask for a key with no evidence, or with evidence that has no verdicts Denied. A release needs verified evidence.
Release on a valid attestation certificate alone, without a measurement pin Denied. Every required policy must be present and passing: P-04 (attestation is fresh and fully verified) and P-09 (signed images pinned to a measurement) for all evidence, and P-05 (no debug TEEs) for CPU evidence. A policy no check covers counts as not passing.
Slip a SKIP or ERROR through as harmless Denied. Only the key-broker checks (*-KEY-01 and GPU-KBS-01) may be SKIP, because the broker's own policy is invisible to a verifier and the caller is the broker. Any other non-PASS result denies.
Present evidence from another platform Denied. A fleet accepts only its own platform's CPU evidence. A GPU fleet also accepts the CPU attestation of the host the GPU is bound to.
Replay someone else's evidence Denied. Evidence must be bound to the caller's nonce and wrap key.
Ask for an unknown or archived fleet Denied.
Crash a verifier, or wait for a vendor outage Denied. A verifier fault or missing vendor collateral is an ERROR, and an ERROR denies.
Get a key to a quarantined host Denied. On a fleet that requires identity approval, only approved hardware gets a key. A release to a host that is not in the identity register raises a detection.
Rewrite history after the fact Every decision is a hash-chained ledger entry. Repeating a request id returns the stored decision without moving the chain.

CI evidence ingest

A pipeline uploads receipts with a short-lived OIDC token from its CI provider. The token authenticates one CI binding. What it uploads is recorded as an authenticated submission, never as verified attestation.

Attack Control
Use a token from another repository, project, fork, branch or workflow Rejected. The issuer comes from a fixed list (GitHub Actions and GitLab.com), and the subject plus every pinned claim must match the binding exactly. Wildcard or empty conditions, and pull_request triggers, can't be registered.
Use a token minted for one binding at another binding in the same organization Rejected. The audience is derived per binding, urn:untrust:ci:<org>:<binding>.
Pick the signing key through the token header (jku, jwk, x5u) or use alg: none Rejected. Keys come only from the provider's fixed key URL; only RS256 is accepted; unsigned, oversized and duplicate-key tokens fail.
Replay a captured token The same token with the same payload returns the stored result; with a different payload it is refused. Token lifetimes are bounded.
Attach a build or IaC receipt to a different commit or run Rejected. For build and IaC evidence, the commit and run id must equal the token's.
Submit a kind of evidence the binding wasn't meant to send Refused and audited. A new binding accepts only build and iac evidence until an administrator widens it.
Use a CI token to read the console or change bindings Refused. A CI token works only at its binding's ingest endpoint.
Flood the ingest endpoint Throttled per binding (HTTP 429) and audited; one binding's flood can't starve another.
Leave half-stored evidence by breaking the audit write Ingest is atomic: if the audit write fails, nothing is stored.

Signed receipts and evidence packs

Attack Control
Steal the signing key from the service The private key stays in a cloud key management service (ECDSA P-256). Signing is a call to that service, so no key material exists in the untrust process.
Embed your own key in a receipt or pack so it verifies A signature counts only against a public key the verifier supplies. A receipt or pack whose embedded key differs from it is not treated as signed.
Upgrade an unsigned entry to "signed" later Not possible. Unsigned entries are labelled unsigned, and supplying a key later doesn't change that.
Edit a ledger entry and keep its signature The hash chain detects the edit independently of the signature.
Use a pack or receipt from one organization as another's Verification fails: each names the organization it belongs to.

You can run these checks yourself with the offline verifiers.

Organization API keys

Attack Control
Read keys from the database or logs Keys are stored only as a SHA-256 digest and shown once. The full key never appears in logs, the audit log or storage; only its prefix does.
Guess keys or time the comparison Keys are server-generated, start with untrust_ and carry a checksum. A bad checksum is refused before any lookup, and the digest is compared in constant time. Repeated failures from one address are throttled.
Use a key against another organization Rejected: a key works only in its own organization.
Use a key to create or manage other keys or members Refused: only a signed-in administrator manages keys.
Keep using a leaked key Revocation takes effect immediately, and keys expire. Each key carries one role, capped by its creator's role, and every action is attributed to it in the audit log. Leaked keys are easy to spot: the untrust_ prefix is matched by secret scanners such as gitleaks.

Attestation verifiers

Verifiers parse material a hostile host controls: certificates, COSE structures, keys and reports.

Attack Control
Send a crafted certificate, key or COSE document to crash the verifier Malformed input becomes a recorded issue or a rejection reason, never a crash and never a pass. This applies to AMD SEV-SNP, Intel TDX and SGX, TPM, AWS Nitro and GCE endorsement verification.
Leave a control unset so it isn't counted A host verdict allows only when every control is positively true; a missing value fails.
Self-sign evidence Evidence is verified against the hardware vendors' roots, never against keys it carries itself. See Trust roots.

Cloud key-release policies

When the console reports whether a cloud key release is bound to attestation, it reads the policy's values: the code-register pins and the release conditions.

  • Weak or missing attestation conditions count as not bound.
  • A policy it can't read counts as unknown, never as bound.

Collectors

Attack Control
Send a report as another host Each collector signs with its own key, enrolled on the host. A report is accepted only for the fleet that key enrolled into.
Extract the collector's key The private key is created on the host and never leaves it.
Pass off tampered hardware evidence The service verifies the bundle's signature and then appraises the hardware evidence against vendor roots. Evidence that fails is labelled unverified.

Out of scope

Some threats aren't things a deployment scanner or an evidence service can see:

  • timing and other side channels;
  • physical and microarchitectural attacks on the TEE;
  • attestation freshness checks inside your own application code;
  • input validation in your host-to-enclave protocol.

These need code review, runtime self-checks inside the TEE, or the hardware vendor's mitigations. See Limits.

To report a vulnerability in untrust, write to security@untrustsecurity.com. Please don't file it in a public issue tracker.