Skip to main content

Overview

ArgentOS stores API keys, service credentials, and authentication tokens using AES-256-GCM encryption. Secrets are encrypted before they hit disk or database — the system never stores plaintext credentials in any persistent location. The encryption architecture has three layers:
  1. Master key — Stored in the OS keychain (macOS Keychain, Linux secret-service, Windows Credential Vault)
  2. Encryption engine — AES-256-GCM with random IVs and authentication tags
  3. Storage backends — JSON files (legacy) and PostgreSQL tables (current)

Encryption Format

All encrypted values use a self-describing format:
Example:
The version prefix (enc:v1) enables future format upgrades without breaking existing encrypted values.

AES-256-GCM

The system uses AES-256-GCM (Galois/Counter Mode), which provides both confidentiality and authenticity:
  • 256-bit key — Derived from the master key stored in the OS keychain
  • 12-byte random IV — Generated fresh for every encryption operation using crypto.randomBytes()
  • Authentication tag — GCM produces a tag that detects any tampering with the ciphertext
  • No padding needed — GCM is a stream cipher mode, so no PKCS7 padding is required

OS Keychain Integration

The 256-bit master key is stored in the operating system’s native credential store: The master key is generated once on first use and stored under the service name argentos. It never appears in configuration files, environment variables, or logs.

Key Generation

On first encryption operation, if no master key exists in the keychain:
1

Generate random bytes

Generate 32 random bytes using crypto.randomBytes(32)
2

Store in keychain

Store in the OS keychain under the argentos service
3

Cache in memory

Cache in memory for the duration of the process

Key Retrieval

On subsequent operations:
  1. Check in-memory cache
  2. If not cached, read from OS keychain
  3. Cache for process lifetime

Backward Compatibility

The decrypt function accepts both encrypted and plaintext values:
This enables gradual migration. Existing plaintext values in config files and databases continue to work. They are re-encrypted with AES-256-GCM when next written.

PostgreSQL Secret Store

When running with PostgreSQL backend (dual-write or postgres mode), secrets are stored in two PG tables:

Service Keys Table

Stores API keys and service credentials:
Key fields:

Auth Credentials Table

Stores authentication profiles (OAuth tokens, API keys with metadata):
The encrypted_payload field contains a JSON object encrypted with AES-256-GCM. This payload includes the actual credential data (API keys, OAuth tokens, refresh tokens) along with provider-specific metadata.

Access Control

Service keys support fine-grained access control:
  • allowed_roles — Only agents with matching roles can use the key
  • allowed_agents — Only specific agent IDs can use the key
  • allowed_teams — Only agents in specific teams can use the key
  • deny_all — Emergency kill switch to revoke all access
When all access control arrays are empty, the key is accessible to all agents (open access).

CRUD Operations

Service Keys

Auth Credentials

Migration from JSON

For installations migrating from JSON-file storage to PostgreSQL, Phoenix provides a one-shot migration function:
The migration:
  1. Reads the JSON files
  2. Decrypts any already-encrypted values (using the same master key)
  3. Re-encrypts for PG storage
  4. Upserts into the PostgreSQL tables
  5. Reports migration counts
Existing PG entries are updated (not duplicated) via ON CONFLICT ... DO UPDATE.

Key Rotation

To rotate the master key:
1

Export all secrets

They are decrypted in memory during export
2

Delete the old master key from the OS keychain

3

Re-encrypt all secrets

A new master key is auto-generated
4

Update all storage backends

Currently, key rotation is a manual process. The system does not support automatic key rotation.

Security Properties

Key Files