# How CloddsBot Handles Credential Encryption: AES-256-GCM Implementation Guide

> Discover how CloddsBot secures trading credentials with AES-256-GCM encryption and scrypt key derivation. Learn about its implementation for robust security.

- Repository: [AL/CloddsBot](https://github.com/alsk1992/CloddsBot)
- Tags: how-to-guide
- Published: 2026-09-13

---

**CloddsBot protects trading credentials using AES-256-GCM encryption with scrypt key derivation, storing encrypted blobs in SQLite with automatic key rotation and comprehensive audit logging.**

Effective credential encryption is critical for any automated trading system handling sensitive API keys. The open-source CloddsBot repository (`alsk1992/CloddsBot`) implements a defense-in-depth approach to credential encryption, combining authenticated encryption, secure key derivation, and database-backed audit trails. This article examines the complete implementation from master key generation to runtime credential access.

## Encryption Architecture Overview

The credential encryption system in CloddsBot operates across two primary modules. The **Credentials Manager** ([`src/credentials/index.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/credentials/index.ts)) handles encryption/decryption operations and credential lifecycle management, while the **Secret Store** ([`src/trading/secrets.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/trading/secrets.ts)) manages database persistence, key rotation, and audit logging. Together they ensure that plaintext credentials never touch the disk.

## Master Key Management

CloddsBot relies on a single master encryption key supplied via the **`CLODDS_CREDENTIAL_KEY`** environment variable.

### Automatic Key Generation

If the environment variable is missing at startup, the core entry point in [`src/index.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/index.ts) auto-generates a cryptographically secure 32-byte hex key. The system stores this key in `process.env` for the current runtime and attempts to persist it to `~/.clodds/.env` for subsequent executions.

### Runtime Validation

When `CLODDS_CREDENTIAL_KEY` is absent, the Credentials Manager logs a warning and disables encryption operations. This fail-safe mechanism prevents accidental storage of plaintext credentials by causing credential-dependent operations to fail fast.

## AES-256-GCM Encryption Implementation

The encryption workflow in [`src/credentials/index.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/credentials/index.ts) follows industry best practices for authenticated encryption.

### Key Derivation and Cipher Initialization

For each encryption operation, the system generates a random **16-byte salt** and **12-byte IV**. It derives a 256-bit encryption key using `crypto.scryptSync(masterKey, salt, 32)`, then initializes the cipher with `crypto.createCipheriv('aes-256-gcm', ...)`.

### Payload Structure

The resulting encrypted payload uses a versioned format prefixed with `v2`. The final stored string concatenates four components separated by colons: the version marker (`v2`), the hexadecimal salt, the hexadecimal IV, the authentication tag, and the ciphertext. This format enables forward compatibility and algorithm agility.

## Legacy Decryption Support

The `decrypt` function in [`src/credentials/index.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/credentials/index.ts) detects legacy credentials by checking for the version prefix. Credentials stored without the `v2` marker trigger the legacy decryption path using AES-256-CBC, ensuring seamless migration from earlier versions without breaking existing user data.

## Database Storage Schema

Encrypted credentials reside in the `secrets` table created by `createSecretStore` in [`src/trading/secrets.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/trading/secrets.ts). The table stores credentials as JSON strings under the `encrypted_data` column, linked to user identifiers and provider names (e.g., "binance").

## Credential Access Flow

The Credentials Manager exposes two primary methods for credential handling.

### Storing Credentials

The `setCredentials` method accepts a user ID, provider name, and plain credential object. It serializes the object to JSON, encrypts it using the `encrypt` function, and persists the blob via `db.createTradingCredentials` or `db.updateTradingCredentials`.

### Retrieving Credentials

The `getCredentials` method queries the database for the encrypted blob, invokes `decrypt` to recover the plaintext JSON, parses it into a typed object, and returns it. If decryption fails due to key mismatches or corruption, the method logs the error and returns `null`.

## Master Key Rotation

The Secret Store provides a `rotateKey(newMasterKey)` method implemented in [`src/trading/secrets.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/trading/secrets.ts). This function iterates through every row in the secrets table, decrypts each credential with the current master key, re-encrypts it with the new key, and updates the database in-place. After processing all rows, it updates the in-memory master key reference and logs the rotation event.

## Security Controls and Audit Logging

Every write, read, delete, and rotation operation generates an audit entry in the `secrets_audit` table. These entries enable administrators to trace credential access patterns, detect unauthorized retrieval attempts, and verify key rotation completion.

## Practical Implementation Examples

The following examples demonstrate working with the credential encryption system.

Storing trading credentials:

```typescript
import { createCredentialsManager } from './credentials';
import { Database } from './db';

const db = new Database();
const credMgr = createCredentialsManager(db);

await credMgr.setCredentials(
  'user-123',
  'binance',
  { apiKey: 'my-api-key', secretKey: 'my-secret' }
);

```

Retrieving decrypted credentials:

```typescript
const binanceCreds = await credMgr.getCredentials<BinanceCredentials>(
  'user-123',
  'binance'
);
if (binanceCreds) {
  // Use decrypted credentials for API calls
}

```

Rotating the master encryption key:

```typescript
import { createSecretStore } from './trading/secrets';

const db = new Database();
const oldKey = process.env.CLODDS_CREDENTIAL_KEY!;
const newKey = 'new-hex-encoded-32-byte-key-string-here';

const secretStore = await createSecretStore(db, oldKey);
await secretStore.rotateKey(newKey);
process.env.CLODDS_CREDENTIAL_KEY = newKey;

```

## Summary

- CloddsBot uses **AES-256-GCM** authenticated encryption with **scrypt** key derivation for all credential storage.
- The master key derives from the **`CLODDS_CREDENTIAL_KEY`** environment variable, with automatic generation and persistence if missing.
- Encrypted credentials follow a **versioned format** (`v2:salt:iv:tag:ciphertext`) supporting legacy AES-256-CBC fallback.
- The **Credentials Manager** ([`src/credentials/index.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/credentials/index.ts)) and **Secret Store** ([`src/trading/secrets.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/trading/secrets.ts)) handle encryption operations and database persistence.
- Built-in **key rotation** capability decrypts and re-encrypts all credentials without service interruption.
- Comprehensive **audit logging** in `secrets_audit` tracks every access and modification.

## Frequently Asked Questions

### What encryption algorithm does CloddsBot use?

CloddsBot implements **AES-256-GCM** (Galois/Counter Mode) for authenticated encryption. This provides both confidentiality and integrity verification through built-in authentication tags. The system derives keys using **scrypt** with a random 16-byte salt to resist brute-force attacks.

### How does CloddsBot handle missing encryption keys?

If `CLODDS_CREDENTIAL_KEY` is not set at startup, the system auto-generates a secure 32-byte hex key in [`src/index.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/index.ts) and attempts to save it to `~/.clodds/.env`. During runtime, if the key remains unavailable, the Credentials Manager disables encryption and fails credential operations to prevent plaintext storage.

### Can I rotate the encryption key without losing existing credentials?

Yes. The `rotateKey` method in [`src/trading/secrets.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/trading/secrets.ts) iterates through all stored secrets, decrypts them with the current master key, re-encrypts with the new key, and updates the database atomically. This operation maintains full data integrity while updating the encryption key.

### Does CloddsBot support migrating from older encryption formats?

Yes. The decryption logic in [`src/credentials/index.ts`](https://github.com/alsk1992/CloddsBot/blob/main/src/credentials/index.ts) automatically detects legacy AES-256-CBC encrypted credentials (version 1) by the absence of the `v2` prefix and falls back to the legacy decryption path, ensuring seamless backward compatibility.