<!-- source: https://deepwiki.com/qhkm/zeptoclaw/6.6-encryption-and-key-management -->

# Encryption and Key Management

- src/cache/response_cache.rs
- src/cli/secrets.rs
- src/cli/update.rs
- src/security/encryption.rs
- src/security/mod.rs
- src/security/mount.rs
- src/security/pairing.rs
- src/security/path.rs

## Purpose and Scope

This document covers ZeptoClaw's encryption infrastructure for protecting sensitive configuration values, OAuth tokens, and device pairing credentials. It explains the master key derivation process using Argon2id, the `ENC[...]` envelope format, and the device pairing mechanism with brute-force protection.

ZeptoClaw prioritizes security-at-rest by ensuring that no plaintext API keys or session tokens are stored on disk without an explicit decryption step.

## System Overview

ZeptoClaw encrypts sensitive data at rest using a symmetric key derived from a master passphrase. The system supports three primary protected data types:

1. Config file secrets — API keys and passwords stored as ENC[...] values in config.json . src/security/encryption.rs 3-13
2. OAuth tokens — Managed by provider-specific logic (e.g., Anthropic, Google) and stored in encrypted formats. src/security/encryption.rs 14
3. Paired Devices — SHA-256 hashes of bearer tokens for external device access, stored at ~/.zeptoclaw/security/paired_devices.json . src/security/pairing.rs 1-9

### Encryption Stack

Title: Encryption Data Flow

```

```

Sources: [src/security/encryption.rs48-104](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/encryption.rs#L48-L104) [src/security/pairing.rs165-179](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/pairing.rs#L165-L179)

## Master Key Derivation

The system resolves a `SecretEncryption` instance via `resolve_master_key(interactive: bool)`. [src/security/encryption.rs14](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/encryption.rs#L14-L14)

### Resolution Priority

1. ZEPTOCLAW_MASTER_KEY Environment Variable : If set, this is used as the passphrase to derive the key. src/security/encryption.rs 59
2. Interactive Prompt : If interactive is true and a terminal is present, the user is prompted via rpassword during CLI operations. src/cli/secrets.rs 152-153

### Argon2id Parameters

ZeptoClaw uses OWASP-recommended parameters for the Argon2id Key Derivation Function:

- m_cost : 65536 KiB (64 MiB)
- t_cost : 3 iterations
- p_cost : 1 (parallelism)
- Output : 32 bytes

Sources: [src/security/encryption.rs176-180](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/encryption.rs#L176-L180) [src/cli/secrets.rs146-164](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/secrets.rs#L146-L164)

## ENC[...] Envelope Format

Encrypted values are stored as strings in the format: `ENC[1:salt_b64:nonce_b64:ciphertext_b64]`. [src/security/encryption.rs7-13](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/encryption.rs#L7-L13)

- Version (1) : Currently the only supported version. src/security/encryption.rs 34
- Salt : 16-byte random salt used by Argon2id to derive the specific key for this envelope. src/security/encryption.rs 28
- Nonce : 24-byte random nonce required for XChaCha20. src/security/encryption.rs 31
- Ciphertext : The encrypted data + 16-byte Poly1305 authentication tag. src/security/encryption.rs 13

### Implementation in SecretEncryption

The `SecretEncryption` struct handles the transformation:

- encrypt(&self, plaintext: &str) -> Result<String> : Generates fresh salt/nonce for every call. src/security/encryption.rs 83-104
- decrypt(&self, encrypted: &str) -> Result<String> : Parses the envelope and verifies the tag. src/security/encryption.rs 112-167
- is_encrypted(value: &str) -> bool : Checks for the ENC<FileRef file-url="https://github.com/qhkm/zeptoclaw/blob/2c743d31/ prefix. [src/security/encryption.rs#L71-L73" min=71 max=73 file-path="` prefix. [src/security/encryption.rs">Hii

Sources: [src/security/encryption.rs37-167](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/encryption.rs#L37-L167)

## Device Pairing and Token Validation

The `PairingManager` handles secure device onboarding using a two-step process: exchanging a short-lived code for a persistent bearer token. [src/security/pairing.rs67-75](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/pairing.rs#L67-L75)

### Pairing Flow

1. Code Generation : generate_pairing_code() creates a 6-digit code valid for 5 minutes. src/security/pairing.rs 114-122
2. Completion : complete_pairing(code, device_name, identifier) validates the code and generates a UUID v4 bearer token. src/security/pairing.rs 129-183
3. Hashing : Only the SHA-256 hash of the bearer token is stored in paired_devices.json . src/security/pairing.rs 18-24

### Security Protections

- Constant-Time Comparison : Both pairing codes and bearer tokens are compared using the subtle crate to prevent timing side-channel attacks. src/security/pairing.rs 148-150 src/security/pairing.rs 207-209
- Brute-Force Lockout : Failed attempts are tracked per identifier. After max_attempts , the identifier is locked out for a configurable duration. src/security/pairing.rs 61-65 src/security/pairing.rs 233-247

Title: Pairing Manager Code Entities

```

```

Sources: [src/security/pairing.rs26-75](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/pairing.rs#L26-L75) [src/security/mod.rs16](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/mod.rs#L16-L16)

## CLI Secret Management

The `zeptoclaw secrets` command provides utilities for managing the encryption lifecycle. [src/cli/secrets.rs1-20](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/secrets.rs#L1-L20)

### secrets encrypt

Recursively walks the `config.json` object. For every field identified as a secret via `is_secret_field(key)`, if the value is plaintext, it is encrypted into an `ENC[...]` envelope. [src/cli/secrets.rs27-65](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/secrets.rs#L27-L65)

### secrets decrypt

Reverses the process, converting all `ENC[...]` values back to plaintext for manual editing. [src/cli/secrets.rs82-128](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/secrets.rs#L82-L128)

### secrets rotate

Performs a key rotation:

1. Loads the current master key.
2. Decrypts all secrets into memory. src/cli/secrets.rs 146-148
3. Prompts for a new master passphrase. src/cli/secrets.rs 151-161
4. Re-encrypts all values using the new key. src/cli/secrets.rs 163-166
5. Writes the updated config.json .

Sources: [src/cli/secrets.rs14-173](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/cli/secrets.rs#L14-L173)

## Path and Mount Security

Encryption is supplemented by filesystem-level security to prevent credential leakage through malicious tools.

- Path Validation : validate_path_in_workspace ensures that tool operations do not escape defined workspace boundaries via directory traversal or symlink attacks. src/security/path.rs 39-130
- Mount Protection : validate_extra_mounts checks runtime container mounts against a blocklist of sensitive paths (e.g., .ssh , .aws , .env ). src/security/mount.rs 12-27 src/security/mount.rs 165-215

Sources: [src/security/path.rs11-37](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/path.rs#L11-L37) [src/security/mount.rs1-44](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/security/mount.rs#L1-L44)
