Trust and Classification
CUST/OS runs Lua skills and sends context to configured model providers. This page describes the controls on those operations, what they cover, and which checks are still in development.
Threat model
The controls address these risks:
- Accidents -- a poorly written skill that does the wrong thing on the wrong inputs.
- Bug exploitation -- a script that hits an unexpected edge case in the host runtime.
- Malicious skills -- an operator unknowingly running a script written by an attacker.
- LLM hallucination -- the agent calling a destructive tool with bad arguments because the model misunderstood.
- Inference exfiltration -- a cloud provider seeing data it shouldn't.
- 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
The design separates script restrictions, action approvals, provider routing, and audit records. These controls depend on correct configuration and a functioning host environment. The seventh layer, skill signature verification, is not yet enforced.
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 gives the operator a chance to check arguments before an action runs. Review coordinates, recipients, and other values in the request. Lower-impact tools can run without a prompt unless a hook requires one.
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: Local audit log
The local audit log records these event types:
- Operator messages and agent responses.
- Tool invocations with arguments and result status.
- Approval decisions with the operator's choice.
- LLM calls with provider, model, and latency.
- Delegations to another agent or device.
- Security events such as sandbox violations and classification blocks.
SQLite triggers reject updates and deletes to audit entries through ordinary database operations. The Audit panel and exports let reviewers inspect the recorded events.
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 declare a classification level (unclassified, CUI, secret, top secret). The router's check allows a request only when the provider's level is at least the configured current level.
Concretely:
- With the current level set to
SECRET, this check allowsSECRETandTOP_SECRETproviders and excludesUNCLASSIFIEDandCUIproviders. - With the current level set to
UNCLASSIFIED, this check alone does not exclude any declared level. Other routing restrictions still apply. - Cloud providers without an explicit classification default to
UNCLASSIFIED.
This is a configured data-flow check. Declaring a level does not establish a provider's accreditation or grant an operator access to it; deployment access controls and handling rules still apply.
Layer 6: Secret storage
Provider API keys entered through CUST/OS are stored in Android EncryptedSharedPreferences, backed by Android Keystore. Configuration refers to keys by provider name. Lua scripts have no binding for reading the credential store.
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.
The skill loader does not yet call the signature verifier. The requirePki setting currently does not reject unsigned skills. The data model defines verified and community trust levels, but the loader does not enforce them. Deployments that need to verify skill provenance must currently do so through their device management and file integrity controls.
How the layers compose
For a single tool call by the agent:
- Hooks evaluate first. If a rule matches, it overrides everything else (allow, deny, or escalate).
- If no hook matched, the approval gate checks the tool's impact level. High-impact tools pause for operator confirmation.
- If approved, the sandbox enforces API, method, filesystem, and execution limits during script execution.
- After execution, the audit log records the result.
- Separately, the classification boundary filters model providers, and the secret store supplies credentials to the provider adapters.
Defaults differ by control. For example, the router parses an unrecognized classification as UNCLASSIFIED, while the skill loader currently accepts unsigned skills. Review each control's behavior for the deployment instead of assuming a single fallback policy applies throughout.
See also
- Architecture overview -- where security fits in the larger system
- The ReAct loop -- how the approval gate integrates with the reasoning loop
- Tiers and priority -- how security modes restrict provider access
- How skills are loaded and shared -- the runtime sandbox model for skills