The Opservant agent enforces a defense-in-depth security model for all executor operations. Every task runs inside a sandboxed environment with declared permissions, resource limits, and cryptographic verification.

Security Architecture

S4E Platform
  |
  | (Signed command over mTLS)
  v
Opservant Agent
  |
  | (Verify signature)
  v
Permission Check
  |
  | (Match against manifest)
  v
Sandboxed Container
  |-- Network Policy (outbound-only, allowlist)
  |-- Filesystem Isolation (read-only root, ephemeral scratch)
  |-- Resource Limits (CPU, memory, timeout)
  |-- Secrets Injection (vault, no plaintext)
  v
Executor runs --> Result --> Audit Log

Command Signing

All commands sent from the S4E platform to Opservant agents are cryptographically signed using Ed25519 keys.

How It Works

  1. The platform signs the command payload with its private key.
  2. The agent verifies the signature using the platform's public key (embedded during registration).
  3. Commands with invalid or missing signatures are rejected and logged as security events.
{
  "command_id": "cmd-8821",
  "action": "execute",
  "executor": "port-scanner",
  "parameters": {"target_host": "10.0.1.5", "ports": [22, 80]},
  "timestamp": "2026-04-28T12:00:00Z",
  "signature": "base64-encoded-ed25519-signature"
}

Warning

If the agent's clock is more than 5 minutes out of sync with the platform, commands are rejected to prevent replay attacks. Ensure NTP is configured on agent hosts.

Sandboxing

Each executor runs inside an isolated environment. The level of isolation depends on the deployment mode.

Container Isolation (Docker / Kubernetes)

When the agent runs in Docker or Kubernetes, each executor task spawns in a separate container with:

  • No host network access --- Executor containers use an isolated network namespace.
  • Read-only root filesystem --- The container image is immutable.
  • Ephemeral scratch space --- A temporary writable volume at /tmp/opservant/scratch/ is available and destroyed after execution.
  • No privilege escalation --- no_new_privs and seccomp profiles are applied.

Process Isolation (systemd)

When running as a systemd service, executors run as forked processes with:

  • Dedicated user account (opservant-executor).
  • PrivateTmp=true and ProtectSystem=strict in the unit file.
  • seccomp filtering to block dangerous syscalls.

Permission Model

Executors must declare their required permissions in manifest.json. The agent grants only the declared permissions and denies everything else.

Network Permissions

{
  "permissions": {
    "network": {
      "outbound": true,
      "allowed_hosts": ["firewall.internal.example.com"],
      "allowed_ports": [443, 8443],
      "denied_hosts": ["*.external.com"]
    }
  }
}
Field Description
outbound Whether the executor can make outbound connections.
allowed_hosts Hostnames or IPs the executor may connect to.
allowed_ports TCP ports the executor may use.
denied_hosts Explicit deny list (takes precedence over allow).

Note

If allowed_hosts is not specified but outbound is true, the executor can connect to any host not on the denied_hosts list. For maximum security, always specify allowed_hosts.

Filesystem Permissions

{
  "permissions": {
    "filesystem": {
      "read": ["/etc/opservant/config.yaml", "/opt/data/"],
      "write": ["/tmp/opservant/scratch/"]
    }
  }
}
  • Paths outside the declared lists are inaccessible.
  • Write access to agent binaries, configuration, and system directories is never granted.

Secrets Permissions

{
  "permissions": {
    "secrets": ["firewall_api_key", "smtp_password"]
  }
}

Executors access secrets through the vault interface, never as plaintext environment variables or files.

Resource Limits

Every executor is constrained by resource limits defined in the manifest or agent configuration.

Resource Default Maximum Description
CPU 10% 50% Maximum CPU usage (percentage).
Memory 128 MB 512 MB Maximum resident memory.
Execution time 60s 3600s Maximum wall-clock time.
Disk (scratch) 100 MB 1 GB Ephemeral scratch space.
Network bandwidth 10 Mbps 100 Mbps Outbound bandwidth limit.

When a limit is exceeded:

  • Memory --- The executor process is killed (OOM).
  • CPU --- The executor is throttled (cgroup limits).
  • Time --- The executor is terminated and the task is marked as timeout.
  • Disk --- Write operations fail with ENOSPC.
# config.yaml override
resource_limits:
  default_timeout_seconds: 120
  max_memory_mb: 256
  max_cpu_percent: 25

Secrets Management

Vault Integration

The agent integrates with HashiCorp Vault, AWS Secrets Manager, or its built-in encrypted secrets store.

# config.yaml
secrets:
  provider: vault
  vault_address: https://vault.internal.example.com:8200
  vault_path: secret/data/opservant
  auth_method: approle
  role_id: "opservant-role"
  secret_id_file: /etc/opservant/vault-secret-id

Accessing Secrets in Executors

def execute(self, params: dict, context: dict) -> ExecutorResult:
    vault = context["vault"]
    api_key = vault.get_secret("firewall_api_key")
    # Use api_key securely

Warning

Never log, print, or include secrets in executor output. The agent runtime automatically redacts known secret patterns from logs, but explicit handling is the executor's responsibility.

Built-in Encrypted Store

For environments without a dedicated vault, the agent provides an AES-256-GCM encrypted local store:

opservant secrets set firewall_api_key "your-secret-value"
opservant secrets list

Secrets are stored in /etc/opservant/secrets.enc and decrypted only in memory during executor runtime.

Network Policies

Default Policy

By default, the agent operates in outbound-only mode:

  • No inbound connections are accepted (the agent initiates all connections to the platform).
  • Executor network access is denied unless explicitly declared.

Configuring Network Policies

# config.yaml
network:
  agent_to_platform:
    protocol: https
    host: api.s4e.io
    port: 443
  executor_defaults:
    outbound: false
    dns_allowed: true

Proxy Support

For environments that require HTTP proxies:

network:
  proxy:
    http: http://proxy.internal.example.com:3128
    https: http://proxy.internal.example.com:3128
    no_proxy: ["10.0.0.0/8", "172.16.0.0/12"]

Audit Logging

All security-relevant events are logged to an immutable audit trail:

  • Command received and signature verification result.
  • Permission checks (granted or denied).
  • Resource limit enforcement events.
  • Secret access events (which secret was accessed, by which executor).
  • Executor start, completion, and failure events.

See Logging & Audit for full audit logging configuration.

Security Checklist

Item Status
mTLS enabled for platform connection Required
Command signing verification enabled Default
Executor sandboxing active Default
Network policies configured Recommended
Secrets stored in vault Recommended
Resource limits set per executor Recommended
Audit logging enabled Default
Agent binary integrity verification Optional
NTP synchronized Required

Next Steps