Skip to main content
Operations is a remote-execution surface running inside your customer’s own cloud account. This page documents the cryptography that makes it auditable: which keys exist, where they live, which transitions get signed, where signed evidence is preserved, and how anyone (you, your customer, an auditor) can verify the chain after the fact. Trust chain: customer pins their pub key to the appliance controller, the appliance controller signs every lifecycle transition with its own key, signed manifests mirror to the vendor control plane, anyone with the pinned pubkey can verify the chain after the fact.

The trust chain at a glance

Two Ed25519 keypairs anchor the system:
  • Your customer’s signing key, generated on your customer’s workstation when they first sign anything (a pre-approval, a release manifest). The private key lives in a local keychain on their workstation; the public key is pinned into the appliance controller’s secret store by a cloud-native write your customer runs in their own cloud account.
  • The appliance controller’s signing key, generated by the appliance controller the first time the install runs. The private key lives in the appliance controller’s secret store under your customer’s IAM (Tensor9 cannot read it). The public key is registered on the install record in your control plane so anyone can fetch it to verify signatures.
At every lifecycle transition that needs non-repudiation, the appliance controller signs canonical bytes with its key. The signed manifest is then mirrored to your control plane at sign time. Anyone with the appliance controller’s pinned pubkey can replay the verification later and prove what was signed, by whom, at what time.

What the three signatures prove

The lifecycle has three signature transitions. Each covers different bytes and proves a different fact. All three signatures are Ed25519 and live on the command’s audit record in your control plane. They survive the encrypt/decrypt cycle: the integrity signature is computed over the plaintext payload before encryption, then preserved alongside the ciphertext metadata. The integrity guarantee chains:
  1. The appliance controller signs the cmd record’s stdout / stderr (the small blob-payload strings).
  2. Inside each payload, a sha256=<hex> field binds the presigned URL to specific bytes.
  3. When the customer or vendor fetches the URL and re-computes the sha256, any byte-level tamper between the appliance controller’s upload and the read is detected (the release script exits non-zero on mismatch; you can do the same client-side).
The signatures compose: a customer disputing “you ran something I didn’t approve” has to either repudiate commandApproval (which is signed against their pinned pubkey) or repudiate the pinning step itself (which they did with their own cloud credentials). Neither is plausible without their key material.

Where keys live

Your customer’s signing key

Your customer owns and stores their own private signing key. The support-portal approval UI handles the setup on first approval (the Set up your signing keypair step) and renders the bash snippets your customer pastes into their own terminal. Today the approval UI supports two storage backends, matched to the appliance environment:
  • AWS appliances: private key in your customer’s AWS SSM Parameter Store as a SecureString (KMS-encrypted at rest).
  • Kubernetes appliances: private key as a Kubernetes Secret in the cluster namespace.
The approval UI refuses to advance the setup step on other appliance environments today (GCP, Azure, DigitalOcean, on-prem). Support for those is on the roadmap.

The appliance controller’s signing key

The customer-side key proves the human signed (“I, the customer, approved this”); the appliance controller’s key proves the bytes were produced inside the appliance (“this output came out of the box at this time, not from elsewhere”). A customer signature without an appliance controller signature would prove approval but not provenance, and the reverse would prove production but not consent, so the audit chain requires both.

How non-repudiation survives revocation

Pre-approval involves two distinct artifacts stored in two distinct places. They serve different purposes and have different deletion properties. Revocation removes future enforcement but does not erase the historical signature. If your customer later claims “I never signed that pre-approval,” you produce the signed manifest from your control plane, the Ed25519 signature verifies against the embedded signer pubkey (with the fingerprint recorded inline on the manifest, in case the key has since been rotated), and the dispute resolves cryptographically. The non-repudiation property holds because the manifest lives where the customer can’t unilaterally erase it: vendor-side infrastructure. If the manifest lived on the appliance controller vault instead, customer-side deletion would be both revocation AND history-rewrite, and a customer could plausibly claim they never signed anything that the appliance controller briefly acted on.

Key rotation

Customers rotate their signing key for a few reasons: retiring a workstation, suspected compromise of the laptop holding the key, an employee with access leaving, or routine rotation per their own security policy. The mechanics:
  1. Generate a fresh keypair on the new workstation. Your customer opens any support link; the approval UI’s Step 2 setup detects no pinned key and walks them through openssl genpkey followed by the put-parameter / create secret snippets to store the private key and pin the public key.
  2. Pin the new pub key to the appliance controller using the same cloud-native command pattern as the initial pin. Your customer can pin alongside the old key or replace it.
  3. Decide what happens to the old key:
    • Leave it pinned. Pre-approvals signed by the old key keep auto-approving until they expire. New approvals get signed by the new key.
    • Unpin it. Every pre-approval signed by the old key immediately fails verification. Auto-approval reverts to manual for all of them.
Historical verification stays intact either way: your control plane records the signer’s pubkey fingerprint at sign time, so signatures on past commands continue to verify against the recorded fingerprint, not against whatever is pinned now. tensor9 ops command audit verify walks each record using the recorded fingerprint.

What revocation does and doesn’t do

Three distinct operations get called “revocation” loosely. They have different effects. Across all three operations, revocation only blocks future enforcement; it does not rewrite history.

Independent verification

Both you and your customer can verify the full audit chain on a specific ops command:
The action:
  1. Pulls the command record from your control plane.
  2. Fetches the appliance controller’s signing pubkey (recorded at sign time, so later key rotation does not invalidate older signatures).
  3. Reconstructs the canonical signed-data for each of the three signatures and verifies them against that pubkey.
  4. Exits zero if all signatures verify; non-zero on any failure.
Output in the healthy case names every check with [OK] and prints the appliance controller’s signer fingerprint at the top. Failures appear as [FAIL] with a one-line reason. For compliance pipelines that need to fail on legacy unsigned records (commands authored before the signature chain was required), pass --strict. For programmatic use, pass --output json and read the per-check signer fingerprints + signed-payload digests so the chain can be archived independently. A customer disputing “you ran something I didn’t approve” doesn’t have to take your word. They run tensor9 ops command audit verify themselves and the Ed25519 signatures either hold or they don’t.