Concepts
Core architectural concepts behind MayFly's zero-disk secrets management, hardware inode isolation, and execution model.
1. Zero-Disk Secrets Lifecycle
The fundamental promise of MayFly is that decrypted plaintext secrets never touch physical storage media.
sequenceDiagram
autonumber
actor Dev as Developer
participant MF as MayFly (mf run)
participant Vault as Vault (~/.mayfly/vault.enc)
participant RAM as Volatile RAM Buffer
participant App as Target App (Node / Python / Go)
participant Disk as Local SSD / Filesystem
Dev->>MF: mf npm run dev
MF->>Vault: Read AES-256-GCM ciphertext + 15B AAD
MF->>RAM: Derive Key (PBKDF2 600,000 rounds) & Decrypt in Memory
MF->>App: Spawn process via os/exec (Env injected directly in RAM)
Note over Disk: Zero plaintext .env files written to disk
App->>Dev: App executes normally (reads process.env)
App-->>MF: Process Exits (SIGINT / Exit Code)
MF->>RAM: Zero memory buffers (runtime.KeepAlive)
MF->>Vault: Append SHA-256 event hash to audit log┌─────────────────────────┐
│ ~/.mayfly/vault.enc │ <--- Encrypted at rest (AES-256-GCM + 600k PBKDF2 iterations)
└────────────┬────────────┘
│ 1. Master password provided via low-level termios echo suppression
▼
┌─────────────────────────┐
│ MayFly Process RAM │ <--- Decrypted strictly into volatile memory byte slices
└────────────┬────────────┘
│ 2. Direct os/exec environment block injection
▼
┌─────────────────────────┐
│ Target Child Process │ <--- Child reads process.env / os.Environ() directly
└────────────┬────────────┘
│ 3. Child exits or receives SIGINT
▼
┌─────────────────────────┐
│ Memory Pages Zeroed │ <--- Buffers overwritten with zero-bytes (runtime.KeepAlive)
└─────────────────────────┘Even if an attacker runs a disk-scanning script, inspects filesystem swap caches, or reads Git status after execution, no unencrypted credential files exist.
2. Inode Project Binding
Traditional tools often bind configurations to folder names (e.g. my-app). If you have two repositories with identical names in different directories (e.g. /home/user/work/api vs /home/user/personal/api), path collisions can cause accidental secret cross-contamination.
MayFly eliminates this by resolving the filesystem device ID (st_dev) and inode number (st_ino):
- Hardware Identifier: Inode numbers are unique 64-bit hardware identifiers assigned by the physical filesystem driver.
- Symlink & Rename Resilient: Symlinks and directory renames preserve the same underlying physical inode.
- Cross-Contamination Protection: Secrets registered for Project A cannot be decrypted or mapped to Project B even if directories share the same name.
3. Direct Host Execution (os/exec)
Instead of passing shell strings through /bin/sh -c, MayFly uses the Go standard library os/exec.CommandContext primitive:
- Argument Preservation: Arguments are passed as an exact string array without shell re-tokenization or unwanted glob expansion.
- History Protection: Sensitive command arguments never appear in
~/.bash_history,~/.zsh_history, or fish history. - Signal Forwarding: Operating system signals like
SIGINT(Ctrl+C),SIGTERM, andSIGHUPare passed directly to the child process without intermediate shell trapping. - PTY Transparency: Terminal standard input, standard output, and standard error file descriptors are piped transparently to preserve full ANSI colors and interactive prompts.
4. Volatile Memory Safety & Auto-Lock
To protect secrets held in volatile workstation RAM against memory scanning:
- Buffer Zeroing: Decrypted password byte slices and credentials are systematically overwritten with zero-bytes upon locking or process exit.
- Compiler Dead-Store Preservation: Zeroing routines invoke
runtime.KeepAlive()to guarantee that Go compiler optimizations cannot elide the memory-clearing loops. - Idle Auto-Lock Timer: When running in interactive TUI mode, an internal inactivity timer automatically locks the vault and zeroes all decrypted state after 15 minutes of idle time.
5. Tamper-Evident Hash Chain
Every operation (vault initialization, key updates, secret injections, leak scans) creates an immutable audit entry linked by SHA-256 hashes:
Hash[N] = SHA256(Hash[N-1] + ":" + Timestamp + ":" + Action + ":" + Data)If any entry in ~/.mayfly/audit.log is modified, deleted, or truncated, mf audit verify will detect the broken cryptographic link immediately.
Next Steps
- Security Model & Cryptography: PBKDF2 parameters, AES-256-GCM AEAD, and container layout.
- In-Memory Injection Architecture: Process spawning and memory lifecycle.
- CLI Reference: Guide to all MayFly CLI commands.