Docs/Security & Infrastructure

Vault & Security

Edit on GitHub

Overview

Auxiora takes a vault-first approach to credentials: every secret is encrypted at rest with AES-256-GCM, derived from a master password through memory-hard key derivation. There are no .env files, no plaintext tokens on disk. By default every trust domain starts at level 0 (no autonomous action), so nothing happens without your explicit approval. Secrets are never included in AI model context -- the runtime retrieves them at the moment they are needed and zeros the memory immediately after.

Encrypted Vault

How It Works

When you create the vault, Auxiora generates a random 32-byte salt and derives an encryption key from your master password using Argon2id (64 MB memory cost, 3 iterations, 1 parallelism lane). This makes brute-force attacks prohibitively expensive even on GPU clusters.

Each credential is encrypted with AES-256-GCM using a fresh 12-byte initialization vector and a 16-byte authentication tag. On decryption, the authentication tag is verified before any plaintext is returned -- tampered ciphertext is rejected outright. After every cryptographic operation, key material is wiped from memory using secure buffer zeroing (zeroBuffer).

Master password
      |
      v
  Argon2id (64 MB, 3 iterations) + salt  -->  256-bit key
      |
      v
  AES-256-GCM encrypt/decrypt  -->  ciphertext + auth tag + IV
      |
      v
  zeroBuffer(key)  -->  key material wiped from memory

CLI Commands

CommandDescription
auxiora vault add <NAME>Add or update a credential (prompts for value securely)
auxiora vault listList stored credential names (never prints values)
auxiora vault statusShow which credentials are configured vs missing
auxiora vault remove <NAME>Remove a credential from the vault
auxiora vault get <NAME>Print a credential value to stdout (for scripting)

Required Secrets

SecretPurposeWhen Needed
ANTHROPIC_API_KEYAnthropic Claude API accessWhen using Anthropic as a provider
OPENAI_API_KEYOpenAI API accessWhen using OpenAI as a provider
GOOGLE_AI_API_KEYGoogle Gemini API accessWhen using Google as a provider
DISCORD_BOT_TOKENDiscord bot authenticationWhen Discord channel is enabled
TELEGRAM_BOT_TOKENTelegram bot authenticationWhen Telegram channel is enabled
SLACK_BOT_TOKENSlack bot OAuth tokenWhen Slack channel is enabled
SLACK_APP_TOKENSlack app-level token (Socket Mode)When Slack channel is enabled
GITHUB_TOKENGitHub personal access tokenWhen GitHub connector is enabled
ELEVENLABS_API_KEYElevenLabs TTS APIWhen using ElevenLabs voice synthesis

Vault File Locations

The vault is stored as a single encrypted JSON file. Its location follows platform conventions:

PlatformPath
macOS~/Library/Application Support/auxiora/vault.enc
Linux~/.config/auxiora/vault.enc
Windows%APPDATA%\auxiora\vault.enc

The vault file is created with 0600 permissions on Unix systems (owner read/write only).

Sealed Auto-Unseal

The Problem

When Auxiora restarts (crash, update, reboot), the vault stays locked and all channels go dead until someone manually enters the vault password. For unattended deployments (systemd service, Docker, headless server), this means downtime until you are back at the keyboard.

The AUXIORA_VAULT_PASSWORD env var works but stores the password in plaintext on disk. Sealed mode solves this.

How It Works

Sealed mode encrypts your vault password with a machine-derived key so the vault can auto-unlock on restart without a plaintext password on disk.

One-time seal:
  Machine fingerprint: SHA-256(hostname + platform + machine-id)
  Seal key:            Argon2id(PIN || "", fingerprint_as_salt, 8 MB, 1 iter)
  seal.enc:            AES-256-GCM(vault_password, seal_key)

Every restart:
  Reconstruct fingerprint → derive seal key → decrypt vault password → unlock vault
  • Machine-bound -- Moving seal.enc to another machine fails because the fingerprint is different.
  • Optional PIN -- Adds defense-in-depth. Even on the same machine, an attacker needs the PIN.
  • PIN-less mode -- For headless/Docker deployments, PIN can be omitted (machine binding alone).
  • Graceful fallback -- If decryption fails, falls back to password prompt or AUXIORA_VAULT_PASSWORD.

CLI Commands

CommandDescription
auxiora vault sealEnable sealed auto-unseal (prompts for vault password + optional PIN)
auxiora vault unsealDisable sealed auto-unseal (deletes seal file)
# Enable auto-unseal with a PIN
auxiora vault seal
# Enter vault password: ********
# Enter PIN (optional): 1234

# Enable auto-unseal without a PIN (machine-binding only)
auxiora vault seal --no-pin

# Disable auto-unseal
auxiora vault unseal

Start with Auto-Unseal

When seal.enc exists, auxiora start automatically attempts to unseal the vault before falling back to a password prompt:

# Auto-unseal without PIN
auxiora start

# Auto-unseal with PIN
auxiora start --seal-pin 1234

# Or via environment variable
AUXIORA_SEAL_PIN=1234 auxiora start

Dashboard

The auto-unseal toggle is available under Settings > Security. You can enable or disable sealed mode and see whether a PIN is required.

Security Properties

PropertyDetails
EncryptionAES-256-GCM (same as vault)
Key derivationArgon2id with lighter params (8 MB, 1 iteration) -- fingerprint adds sufficient entropy
Machine bindingSHA-256 of hostname + platform + /etc/machine-id (Linux), IOPlatformUUID (macOS), or hostname+homedir (fallback)
Seal file permissions0600 on Unix (owner read/write only)
Memory safetySeal key and recovered password are zeroed immediately after use

Seal File Format

The seal file (seal.enc) is stored alongside vault.enc:

{
  "version": 1,
  "fingerprintHash": "hex(SHA-256(fingerprint))",
  "pinRequired": true,
  "iv": "base64",
  "data": "base64",
  "tag": "base64",
  "salt": "base64"
}

The fingerprintHash field is used for quick mismatch detection (not used in key derivation -- the raw fingerprint is).

Audit Logging

How It Works

Every security-relevant action is recorded in a tamper-evident audit log. Each entry includes a SHA-256 hash computed over the entry data concatenated with the previous entry's hash, forming a hash chain. If any entry is modified, deleted, or inserted, the chain breaks and verification fails.

Entry 1:  hash = SHA-256(prevHash + data)    prevHash = 000...000 (genesis)
Entry 2:  hash = SHA-256(prevHash + data)    prevHash = Entry 1's hash
Entry 3:  hash = SHA-256(prevHash + data)    prevHash = Entry 2's hash
...

Sensitive fields (passwords, tokens, API keys) are automatically redacted before being written to the log. The audit log file is set to 0600 permissions on Unix.

What Gets Logged

The audit system tracks over 100 distinct event types, organized into categories:

  • Vault operations -- unlock, lock, add, remove, access, password changes, seal, unseal
  • Authentication -- login, logout, failed attempts, token refresh, JWT configuration
  • Pairing -- code generated, accepted, rejected, expired
  • Channel activity -- connected, disconnected, errors, messages sent/received
  • Trust changes -- level changed, promotions, demotions, permission denied, action gated
  • Behavior lifecycle -- created, updated, deleted, executed, paused, failed
  • Browser actions -- navigate, click, type, screenshot, script execution
  • Security events -- suspicious input, rate limiting, guardrail triggers
  • System events -- startup, shutdown, errors
  • Connector operations -- connected, disconnected, OAuth flows, action execution
  • Personality changes -- resets, feedback, preset applied, corrections, data exports

Viewing Audit Logs

# View recent audit entries
auxiora audit

# Verify the integrity of the hash chain
auxiora audit --verify

The verify command recomputes every hash in the chain and reports whether the log is intact or where tampering was detected.

Trust System

5 Autonomy Levels

LevelNameDescriptionExample
0NoneNo autonomous action (default)--
1InformNotify about opportunities"You have a meeting in 15 min"
2SuggestPropose actions for approval"Should I reply to this email?"
3Act & ReportExecute and notify afterwardSends the reply, tells you after
4Full AutonomyExecute silentlyHandles routine tasks without interruption

All domains default to level 0. Automatic promotion is supported (up to a ceiling of level 3) based on a track record of successful actions, with automatic demotion after repeated failures.

9 Trust Domains

DomainWhat It ControlsDefault Level
messagingSending messages on your behalf via channels0
filesReading, writing, and deleting local files0
webOutbound HTTP requests and browser automation0
shellExecuting shell commands0
financeFinancial transactions and payment actions0
calendarCreating, modifying, or deleting calendar events0
emailSending emails on your behalf0
integrationsActions through connected services (GitHub, Notion, etc.)0
systemSystem-level operations (daemon, updates, configuration)0

Configuring Trust

# Set messaging to "Suggest" (level 2)
auxiora trust set messaging 2

# Set calendar to "Act & Report" (level 3)
auxiora trust set calendar 3

# View all current trust levels
auxiora trust status

Trust levels can also be configured through the dashboard under Settings > Security.

Use Cases

  1. Conservative setup -- All domains stay at level 0 or 1 (inform only). The assistant observes and notifies but never acts. Best for first-time users or sensitive environments.

  2. Power user -- Messaging at level 3, calendar at level 3, files at level 2, shell at level 1. The assistant manages routine communications and scheduling autonomously but asks before touching files and only informs about shell opportunities.

  3. Full autonomy for a domain -- Set a specific domain (e.g., email) to level 4 when you trust the assistant's judgment for that area. The assistant handles email entirely on its own. All actions are still audit-logged, and automatic demotion kicks in if failures occur.

SSRF Protection

All outbound HTTP requests made by the browser control and research modules are validated against private IP ranges before the connection is established. This includes:

  • Private range blocking -- Requests to 10.x.x.x, 172.16-31.x.x, 192.168.x.x, 127.x.x.x, and IPv6 equivalents are rejected by default.
  • DNS rebinding protection -- DNS resolution is performed and the resolved IP is checked against private ranges, preventing DNS names that resolve to internal addresses.
  • Numeric IP normalization -- Hex, octal, and decimal IP encodings are normalized to dotted-decimal before validation, closing encoding-based bypasses.
  • Configurable allowlists -- Specific internal addresses can be explicitly allowed when needed (e.g., a local Home Assistant instance).

Content Safety

Auxiora includes a guardrails layer that provides:

  • PII detection -- Scans outbound messages for accidental inclusion of sensitive personal information (SSNs, credit card numbers, etc.) and blocks or warns before sending.
  • Prompt injection defense -- Incoming messages from channels are screened for prompt injection patterns before being passed to the AI model, reducing the risk of manipulation through untrusted input.

Both systems are configurable and can be tuned or disabled based on your threat model.


See also: AI Providers | CLI Reference | Getting Started