Skip to main content
Per-command approval is the default. For a routine operation, your customer can instead sign a standing pre-approval that covers future matching template runs on one install. They choose the scope and validity window, and whether output still needs review. For commands created through the support-request flow, Step 5 of the /support/<token> approval UI offers pre-approval after output release. Your customer can skip it. Signing runs locally with their own key; the appliance checks the signed grant before using it.
Your customer signs a bounded grant locally. For each matching template run, the appliance checks the signing key, revocation and scope. CommandsOnly retains manual output release; FullyPreApprove also permits automatic output release after another check. An ineligible grant does not authorize the run; another grant may match, otherwise approval is manual.Your customer signs a bounded grant locally. For each matching template run, the appliance checks the signing key, revocation and scope. CommandsOnly retains manual output release; FullyPreApprove also permits automatic output release after another check. An ineligible grant does not authorize the run; another grant may match, otherwise approval is manual.Your customer signs a bounded grant locally. For each matching template run, the appliance checks the signing key, revocation and scope. CommandsOnly retains manual output release; FullyPreApprove also permits automatic output release after another check. An ineligible grant does not authorize the run; another grant may match, otherwise approval is manual.Your customer signs a bounded grant locally. For each matching template run, the appliance checks the signing key, revocation and scope. CommandsOnly retains manual output release; FullyPreApprove also permits automatic output release after another check. An ineligible grant does not authorize the run; another grant may match, otherwise approval is manual.
Your customer signs the scope; your control plane stores the grant. The appliance checks eligibility for each command and again for automatic output release. CommandsOnly keeps customer review of output. Arrows show approval decisions, not network traffic. Revocation changes later checks; it does not stop a running command.

What a pre-approval is

A pre-approval is an Ed25519-signed policy, stored by your control plane and checked by the appliance. It includes the target install, signer fingerprint, issue time, validity deadline, approval level and maximum-run setting. A template-specific policy also includes the exact template ID, version and content hash, plus any customer variable constraints. Editing the template does not widen an existing grant. Where the UI offers a broader scope, it signs a permissions allow-list that the appliance compares with the template’s declared permissions. That comparison is consent to the declared scope; it does not create a separate set of per-command cloud credentials. The scope picker initially selects 30 days and 25 runs. The deadline is checked when the grant is used. The current runtime does not advance the used-run counter, so do not rely on the maximum-run setting to limit execution. Use the validity deadline and revocation controls instead. Your customer stores their private signing key in AWS SSM Parameter Store (SecureString), Google Cloud Secret Manager in the appliance’s project, or a Kubernetes Secret. They separately place the public key where the appliance controller can read it. The signing script reads the private key locally; the browser and your control plane receive the signed policy, not the private key. The public key and signer fingerprint are not secrets.

Approval levels

CommandsOnly removes per-command review while keeping customer control over output release. FullyPreApprove also permits output release without per-run customer review, so your customer should review the template and its output before choosing it. Choosing no pre-approval remains the UI’s default.

Granting a pre-approval

Step 5 follows the regular support-request approval and output-release flow:
1

Pick a scope

Your customer chooses this template or an available broader scope, the approval level, validity window and maximum-run setting. Template-specific grants can add variable constraints. The current GCP support UI offers template-specific grants; it does not offer the broader scope choice.
2

Set up signing keypair (one-time per appliance)

If no signing key is visible, the UI renders local key-generation and storage commands for AWS, GCP or Kubernetes. Your customer stores the private key in their own secret store and places the public key where the controller reads it, using their own cloud credentials. The UI polls for the public key before proceeding. A key already set up for per-command approval is reused.
3

Render the install + sign snippets

The UI shows the policy’s canonical bytes and a downloadable signing script. Your customer reviews the scope, then runs the script on a trusted host with read access to their signing-key store. The script fetches the private key, checks its fingerprint, prompts for confirmation and signs the canonical policy locally with OpenSSL.
4

Submit the signed policy

The script POSTs the signed policy directly to the support endpoint. Your control plane stores it; the UI polls for the submission to appear. The appliance verifies the grant when deciding whether to auto-approve a command. A stored grant alone does not prove that runtime verification will succeed.
Later template runs are eligible only while a grant covers them. If no grant covers the run, approval remains manual. A failed template-grant signature or canonical-byte check can reject command approval rather than silently treating that grant as valid. Pre-approval does not guarantee that your customer receives no per-run notifications.

Variable constraints

Template-specific grants can add full-string regex constraints on submitted variable values. For example:
The appliance checks both the template author’s constraints and the customer’s signed constraints. A missing variable, malformed pattern or mismatch makes that template grant ineligible. Another valid grant can still cover the command; otherwise it needs manual approval. These constraints are signed approval conditions, not a replacement for reviewing the template’s behavior or its runtime permissions.

Listing active pre-approvals

To inspect the stored grants for an appliance:
This read-only command reports template-specific and permissions-scoped grants, their validity deadline, approval level, signer fingerprint, and recorded run counts. Pass --json for JSON output. The current listing action requires an appliance ID; it has no customer-name option. The status is computed from the stored deadline and counter. An active row does not verify the live signing key or revocation record, and the counter currently does not advance. Compare the signer fingerprint with your customer’s authorized key record; listing it does not establish authorization by itself.

Verifying a pre-approval is actually active

Inspect a recent command’s recorded approval source:
An automatic pre-approval decision records BuyerSignedPreApproval:<fingerprint-prefix>. This identifies the decision recorded for that command; it does not establish that the grant will cover the next one. A manual approval records its own signer label. If runs unexpectedly need manual approval, check the grant’s deadline, exact template version and content hash, variable constraints, current signing-key fingerprint, and revocation state. The UI’s setup poll helps detect a missing key but does not replace these runtime checks. A command audit can inspect its recorded signatures, but its commandApproval check is not a test of whether a standing grant is currently eligible.

Revoking a pre-approval

Start with the support UI’s shared-key removal when your customer needs to stop future pre-approved runs. Confirm that its command names the public key used during signing setup, and review its impact on all grants signed by that key. Revocation changes later approval checks. It does not cancel a command already executing, undo side effects, or withdraw output already released. Your customer runs the cloud command with their own credentials; the controller must successfully observe the change.

Remove the shared signing key

Have your customer open the support UI’s terminal revocation snippet and compare its key location with the public-key location used during signing setup. Run it only when the store, key name, region or project, and namespace identify the key currently trusted by this install. If they differ, contact Tensor9 support before relying on the snippet. This affects all grants signed by that current key, even when the snippet is opened from one template’s request, and can affect per-command approval checks using the same key. Once the controller observes the removal, those grants no longer pass its key check. Use the exact path, region or project, and namespace from the customer’s approval UI. These are the native command shapes for that confirmed public-key location:
Verify that the controller observes the missing or changed key. Deletion is not a durable revocation record for every old grant: placing the same key back can make an otherwise valid grant eligible again. To rotate, set up a fresh keypair and have your customer sign new grants. Keep the historical public key and authorization record for audit without making that old key the current trusted key again.

Revoke one grant

Targeted revocation uses a valid, readable JSON record for one grant in the store the appliance reads. The current targeted CLI renderer requires a customer API key and control-plane metadata, but does not write the record. Its backend and path limitations mean its output is not a verified targeted-revocation procedure for every supported appliance backend. Contact Tensor9 support before relying on a targeted procedure. Until that procedure is verified for the customer’s install, use the shared-key removal above with its broader impact understood. Deleting a revocation record does not revoke a grant. Missing, unreadable, blank or malformed records are treated as not revoked; malformed records produce a warning. Removing or invalidating a record can make a still-valid grant eligible again if its signer still matches the current public key and the other checks pass. When the controller observes a valid record, it stops using that grant. A different valid grant may still cover the same command. These records are unsigned and controlled by write access to the customer’s store. Keep the record in place while the grant could otherwise remain valid. Do not construct a path or wire format from this article.

Lost-key recovery

The customer can retrieve a stored private key from another trusted workstation if they still have the required AWS IAM, GCP IAM or Kubernetes RBAC access. Loss of one workstation therefore need not mean loss of the stored key. Deletion of the stored private key, suspected exfiltration or compromised store access requires a different response. There is no Tensor9 private-key escrow. From a trusted environment, remove or replace the currently trusted public key, confirm the controller observes it, then set up a fresh keypair and sign replacement grants. Keep any targeted revocation records and historical public-key authorization records. Replacing a key does not undo commands or output already released.

Supported appliance backends

Do not infer that support for one flow establishes working command rendering for another.

Validity-mid-flight semantics

The appliance checks eligibility during command approval and checks it again for automatic output release. A FullyPreApprove grant that expires, is revoked or no longer matches the trusted key after execution may stop covering release. Output then needs manual approval unless another valid grant covers it. The waiting lifecycle is OutputApproving. Signature failure during output approval falls back to the manual output decision rather than rejecting the already executed command’s output outright. Refreshing a grant does not itself release held output; inspect the command’s current state and have your customer approve release when needed.

Trust properties

  • The customer holds the private signing key. Local signing sends the policy and signature to your control plane. It does not send the private key.
  • The appliance checks the currently trusted key. The signer fingerprint and signature must match it. Changing that key affects more than one grant.
  • The signed policy fixes consent. Template version, content hash and variable constraints cannot be widened without a new signature. Broader permission grants cover declared permissions; they do not grant new runtime cloud credentials.
  • Store access controls revocation. A valid record must be readable by the controller. No fixed propagation time or automatic cancellation of running commands is promised.
  • Audit identity needs an authorization record. Preserve the signed policy and the customer’s historical public-key authorization through rotation. A displayed fingerprint or current key alone does not prove who was authorized at an earlier date.