Encryption at Rest

All sensitive data stored in Postgres is encrypted using AES-256-GCM with the AUXOT_SECRET_KEY. This includes:

  • Cloud provider API keys (OpenAI, Anthropic)
  • MCP server credentials (tokens, passwords, OAuth secrets)
  • Worker registration secrets

Encryption happens at the application layer before data is written to the database. Each encrypted value uses a unique nonce, and the GCM authentication tag ensures tamper detection.

┌─────────────────────────────────┐
│  Plaintext: sk-proj-abc123...   │
│         ↓ AES-256-GCM          │
│  Ciphertext: <nonce>.<ct>.<tag> │
│         ↓ stored in Postgres    │
└─────────────────────────────────┘

If the database is compromised without the AUXOT_SECRET_KEY, encrypted fields are unreadable. The secret key itself should be stored in a secrets manager (Vault, AWS Secrets Manager, environment-level encryption) — never committed to version control.

Key Rotation

Treat AUXOT_SECRET_KEY as a high-impact secret. Changing it without re-encrypting stored data will make existing encrypted credentials unreadable. Plan rotation carefully and test the process in a staging environment first.

Authentication

User Passwords

User passwords are hashed before storage. Auxot uses Argon2id for new password hashes and still supports legacy bcrypt hashes for backward compatibility.

# Password requirements
# - Minimum 8 characters

JWT Tokens

After successful authentication, the server issues a JWT signed with AUXOT_SECRET_KEY:

  • Access tokens expire after 15 minutes.
  • Refresh tokens expire after 30 days.
  • Tokens are signed using HMAC-SHA256.

API keys used for programmatic access are stored as one-way hashes in the database. The plaintext key is shown once at creation time.

Worker Key Hashing

GPU and CLI workers authenticate with the router using worker keys. These keys are hashed using Argon2id before storage:

Algorithm: Argon2id
Memory:   64 MB
Iterations: 3
Parallelism: 4
Salt:     16 bytes (random per key)
Hash:     32 bytes

Argon2id is chosen over bcrypt for worker keys because it’s resistant to GPU-based brute-force attacks (the memory-hard property makes it expensive to parallelize on GPUs). When a worker connects and presents its key, the server runs Argon2id verification against the stored hash.

Key Generation

Worker keys are generated by Auxot from cryptographically secure randomness and shown once at creation time. Store them securely — only the Argon2id hash is persisted.

Network Architecture

Auxot’s network design follows a zero-inbound-ports principle for workers:

┌──────────────────────────────────────────────┐
│                 Your Network                 │
│                                              │
│  ┌─────────┐         ┌──────────────┐        │
│  │  GPU    │────────▶│              │        │
│  │  Worker │  HTTPS  │              │        │
│  └─────────┘         │              │        │
│                      │ auxot-server │◀── Users
│  ┌─────────┐         │              │        │
│  │  CLI    │────────▶│              │        │
│  │  Worker │  HTTPS  │              │        │
│  └─────────┘         └──────┬───────┘        │
│                             │                │
│                     ┌───────┴────────┐       │
│                     │                │       │
│                ┌────▼────┐      ┌────▼────┐  │
│                │ Postgres│      │  Redis  │  │
│                └─────────┘      └─────────┘  │
└──────────────────────────────────────────────┘

Key properties:

  • Workers connect outbound to the router. You never need to open inbound ports on machines running GPU or CLI workers. This is critical for on-premises deployments where GPU servers sit behind NAT or restrictive firewalls.
  • Long-lived connections. Workers maintain a persistent WebSocket connection to the router for receiving inference requests and sending heartbeats.
  • TLS everywhere. In production, all connections between workers and the router should use TLS (typically via your reverse proxy/load balancer).

No Cloud Dependencies

Auxot has zero external cloud dependencies in its runtime path:

  • No telemetry. The server does not phone home, report usage, or send any data to Auxot (the company) or any third party.
  • No license server. License validation is offline (Ed25519 signature verification against an embedded public key).
  • No model downloads at runtime. Models are pre-downloaded and loaded from disk.
  • No external auth. Authentication is self-contained (bcrypt + JWT). SSO/SAML (Enterprise tier) connects to your identity provider, not ours.

The only outbound connections Auxot makes are to cloud providers (OpenAI, Anthropic) when proxying inference requests — and only if you’ve configured cloud providers. If you run exclusively GPU and CLI workers, Auxot makes zero outbound connections.

Security Checklist

Before deploying to production:

  • Generate a strong AUXOT_SECRET_KEY (openssl rand -hex 32) and store it in a secrets manager
  • Enable TLS (direct or via reverse proxy)
  • Use a strong password for the admin account (minimum 8 characters)
  • Set AUXOT_BASE_URL to your public HTTPS URL
  • Restrict database access to the Auxot server only
  • Use network policies to limit worker egress to only the Auxot server
  • Enable Postgres SSL (sslmode=require in DATABASE_URL)
  • Review and rotate worker keys periodically
  • Set API key expiration dates for service accounts
  • Monitor server logs for failed authentication attempts