Oracle Omen assumes a hostile environment. Tools are untrusted. All capabilities must be explicit and verified.
- Zero Trust by Default: No capability is granted unless explicitly given
- Capability-Based Security: All actions require specific capabilities
- Sandboxed Execution: Tools can run in WASM with strict limits
- Audit Everything: Every capability check is logged
- Deterministic Verification: All actions must be replay-identical
Tools may:
- Attempt file access without capability
- Attempt network access without capability
- Attempt privilege escalation
- Consume excessive resources
- Return malformed output
| Threat | Mitigation |
|---|---|
| Unauthorized file access | Capability check before execution |
| Resource exhaustion | Fuel limits, memory limits, timeouts |
| Malformed output | Response normalization and validation |
| Privilege escalation | Immutable capability set |
| Non-determinism | Tool declaration, replay verification |
Capabilities use domain:action:scope format:
fs:read:/tmp # Read files in /tmp
network:http:get # HTTP GET requests
process:exec:/bin/grep # Execute grep
env:read:PATH # Read PATH variable
// Before any tool execution
for required_capability in tool.required_capabilities() {
if !granted_capabilities.has(required_capability) {
log_capability_denied(tool, required_capability);
return Err(CapacityError::Denied);
}
}Capabilities are granted from:
- Configuration file
- Policy engine evaluation
- Explicit CLI arguments
Capabilities are never auto-granted.
| Resource | Default Limit | Maximum |
|---|---|---|
| Fuel | 1,000,000 instructions | 10,000,000 |
| Memory | 1 MB (16 pages) | 64 MB |
| Table size | 1024 elements | 4096 elements |
| Output | 1 MB | 10 MB |
Only whitelisted host functions are available:
oracle.log- Write to agent logoracle.hash- Compute BLAKE3 hash
No filesystem, network, or process access.
Each WASM instruction consumes fuel. When fuel runs out:
- Execution terminates
- Event is logged
- Tool returns error
All patches must be signed using Ed25519:
pub struct SignedPatch {
pub patch: Patch,
pub signature: Signature, // 64 bytes
pub signer: SignerId, // 32 bytes public key
}Patches must pass three gates:
- Test Gate - All tests must pass
- Audit Gate - Policy and safety checks
- Approval Gate - Authorized signature required
Patches are scanned for:
- Prompt injection attempts
- Unsafe Rust patterns
- System command execution
- Transmute usage
- Raw pointer usage
Each event hashes:
- Its own payload
- Previous event hash
event_hash = hash(payload || prev_event_hash)
On replay:
if event.payload_hash != hash(event.payload) {
return Err(EventLogError::HashMismatch);
}- Static policies - From configuration
- Dynamic policies - From policy engine
- Runtime policies - Capability checks
1. Static policy check (fastest)
2. Dynamic policy evaluation
3. Runtime capability check (most specific)
Non-determinism is a security concern because:
- Cannot verify what happened
- Cannot reproduce bugs
- Cannot audit decisions
- No system time - use injected logical time
- No unseeded randomness - use seeded RNG
- Stable serialization - BTreeMap, sorted keys
- No floating point in consensus - integer math only
See FAILURE_MODES.md
- All capability checks logged
- No capabilities granted by default
- WASM limits enforced
- Patch signatures verified
- Prompt injection detection enabled
- Determinism tests passing
- Replay identity verified
- No unsafe code in critical paths
- Resource limits enforced
- Audit log append-only