Trust and Classification

CUST/OS handles tactical data and runs operator-authored code on operator devices. Both are sensitive, and both demand a security model that goes beyond trusting the APK signer. This page explains the layered approach.

Threat model

What the security model defends against:

  1. Accidents -- a poorly written skill that does the wrong thing on the wrong inputs.
  2. Bug exploitation -- a script that hits an unexpected edge case in the host runtime.
  3. Malicious skills -- an operator unknowingly running a script written by an attacker.
  4. LLM hallucination -- the agent calling a destructive tool with bad arguments because the model misunderstood.
  5. Inference exfiltration -- a cloud provider seeing data it shouldn't.
  6. Audit tampering -- someone trying to hide what the agent did.

What the security model does not defend against:

  • A determined adversary with root access on the device.
  • Cryptographic attacks against TLS connections.
  • Vulnerabilities in the host application.
  • The operating system being compromised before CUST/OS starts.

Defense in depth

No single layer is sufficient. The model has seven independent layers, each covering a different attack surface. A weakness in any one layer does not cascade -- the others continue to hold.

Layer 1: Sandboxing

Skills run in a restricted execution environment with controlled access to device APIs. The sandbox enforces:

  • API allowlist -- scripts can only access a curated set of host APIs. Everything else is invisible.
  • Operation blocklist -- dangerous operations (process execution, file deletion, raw network access) are blocked regardless of what APIs are available.
  • Filesystem scoping -- file access is restricted to the CUST/OS data directory. Scripts cannot read or write outside their allowed paths.
  • Execution limits -- each script invocation has a maximum number of operations it can perform before being terminated. This prevents runaway scripts from consuming device resources.
  • Concurrency limits -- only a fixed number of scripts can execute simultaneously.

This is the foundational layer. Every other defense assumes the sandbox holds.

Layer 2: Approval gates

Tools declare an impact level that reflects the severity of what they do:

Level Requires approval Examples
Read-only No Querying positions, measuring distances
Informational No Logging, writing memory facts
Procedural No Placing a single marker
Significant Yes Multi-item changes, file writes, creating automations
Strategic Yes Comms broadcasts, mission-package distribution, beacon activation
Lethal Yes Reserved for actions with irreversible kinetic consequences

When the agent wants to call a tool at Significant impact or higher, the reasoning loop pauses and presents the operator with the tool name, arguments, impact level, and rationale. The operator can:

  • Approve -- let it proceed.
  • Deny -- block the action.
  • Modify -- edit the arguments before approving (useful for correcting coordinates or callsigns the model may have hallucinated).

Approval is the last line of defense against LLM mistakes. It stops the model from accidentally placing a marker at the wrong coordinates or sending a message to the wrong recipient.

Layer 3: Pre/post hooks

Hooks are configurable rules that override the default impact-level gate. They allow operators and administrators to express policy that travels separately from skill code:

  • Allow -- bypass the approval gate for a specific tool (e.g., always allow read-only lookups).
  • Deny -- block a tool entirely (e.g., deny all placement tools during EMCON).
  • Require approval -- force the gate even on a low-impact tool (e.g., require approval for any tool when reasoning at a remote tier).

Hooks can target specific tools by name pattern and specific provider tiers. The same skill set can run on two devices with different operational rules just by changing the hook configuration on each.

Layer 4: Immutable audit log

Every consequential action is recorded to a tamper-resistant log:

  • Every operator message and agent response.
  • Every tool invocation with arguments and result status.
  • Every approval decision with the operator's choice.
  • Every LLM call with provider, model, and latency.
  • Every delegation to another agent or device.
  • Every security violation (sandbox breach, classification block).

The log is append-only. Routine application code paths cannot modify or delete existing entries. This ensures that after-action review has a complete, unaltered record of everything the agent did and every decision the operator made.

The log does not provide cryptographic tamper-evidence -- someone with physical access to the device could delete the file. For cryptographic guarantees, layer external attestation on top.

Layer 5: Classification boundaries

Providers are tagged with a classification level (unclassified, CUI, secret, top secret). The runtime enforces a simple rule: data is never sent to a provider below the operator's configured classification ceiling.

Concretely:

  • An operator working at the secret level can use unclassified, CUI, and secret providers.
  • An operator working at the unclassified level cannot use a secret provider, even if it is online.
  • Cloud providers without an explicit classification default to unclassified (fail-safe).

This prevents tactical data from accidentally flowing through a provider that isn't cleared to handle it. It is a runtime control, not a policy substitute -- operational PKI and access controls still apply.

Layer 6: Secret storage

API keys and credentials are stored in an encrypted store on the device, separate from the configuration file. Scripts cannot access the credential store. Pulling the configuration file off the device yields no secrets.

This was a deliberate design decision: a previous version of the runtime exposed the configuration to scripts, and that path was closed specifically to prevent indirect credential access.

Layer 7: Skill trust levels — WIP

The architecture reserves space for cryptographically signed skills: a signature verifier class exists, signature metadata can be attached to a skill, and security.requirePki is a declared configuration knob intended to reject unsigned skills.

In this release the verification path is not yet wired into the skill loader. Every skill loads regardless of the requirePki setting. Two trust levels (verified for signed, community for unsigned) are defined in the data model but not enforced at load time. Treat skill signing as part of the security architecture's intent — production deployments that need hard provenance today should rely on device-level controls (MDM-pushed skill directories, verified boot, file integrity monitoring) until the verification path closes.

How the layers compose

For a single tool call by the agent:

  1. Hooks evaluate first. If a rule matches, it overrides everything else (allow, deny, or escalate).
  2. If no hook matched, the approval gate checks the tool's impact level. High-impact tools pause for operator confirmation.
  3. If approved, the sandbox enforces API, method, filesystem, and execution limits during script execution.
  4. After execution, the audit log records what happened, immutably.
  5. Throughout, the classification boundary ensures data only flows to cleared providers, and the secret store keeps credentials out of reach.

Every layer fails closed. An unknown tool defaults to requiring approval. An unknown API defaults to blocked. An unknown classification defaults to the most restrictive level. There is no path where an uncertain condition becomes "allow".

See also