diff options
| author | Levi Durfee <levi.durfee@gmail.com> | 2026-01-08 10:40:44 -0500 |
|---|---|---|
| committer | Levi Durfee <levi.durfee@gmail.com> | 2026-01-08 10:45:52 -0500 |
| commit | c4c26a1b1348dc8d3a0a6ecce3a031d212edf6b1 (patch) | |
| tree | 4013dcca8e8fcd9de2ec87e335979b0f59807dd3 /THREAT_MODEL.md | |
| parent | 7633745f3e0517298a6337adb8a21a327e265701 (diff) | |
Add threat model
Diffstat (limited to 'THREAT_MODEL.md')
| -rw-r--r-- | THREAT_MODEL.md | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md new file mode 100644 index 0000000..336191e --- /dev/null +++ b/THREAT_MODEL.md @@ -0,0 +1,164 @@ +# Threat Model + +## Summary + +`goaes` is a CLI tool for encrypting files at rest before storage using an AEAD scheme (e.g., AES-256-GCM). The intended users are the author and other CLI-savvy technical users. The key material is provided via a base64-encoded value from an environment variable. + +This threat model focuses on offline compromise scenarios (stolen encrypted files) and does not attempt to defend against a compromised runtime environment. + +## Goals + +### Security goals + +- **Confidentiality:** An attacker who obtains encrypted files should not be able to recover plaintext without the secret key. +- **Integrity:** Any modification to ciphertext should be detected at decryption time (fail closed). +- **Practical usability:** The tool should remain simple to use for technical users and not require complex operational dependencies. + +### Non-goals + +- **Multi-user key sharing / access control** +- **Compliance alignment** (e.g., FIPS, SOC 2, HIPAA) +- **Key rotation / crypto-erasure** as a first-class feature (not a current priority) + +## System overview + +### Primary workflow + +1. User supplies a base64-encoded secret via environment variable (the "KEK" or master key). +2. `goaes` encrypts file content and writes an encrypted output file. +3. `goaes` decrypts files given the same environment-supplied key. + +### Data stored alongside ciphertext + +- File format version identifier (cleartext) +- Salt (cleartext) if used for key derivation / domain separation / format evolution + +Note: cleartext metadata is permitted as it does not reveal the key or plaintext. + +## Assets + +- **Plaintext file contents** (primary asset) +- **Encryption key material** (base64 env var secret; decoded bytes in memory during runtime) +- **Integrity of decrypted output** (avoid silent corruption or malleability) + +## Trust boundaries + +- **Trusted:** Local machine *only insofar as* it is not compromised at runtime. +- **Untrusted:** Storage locations where ciphertext may reside (cloud object storage, backups, shared filesystems), and any party who can read encrypted files. + +## Adversaries (in scope) + +1. **Offline file thief** + - Obtains encrypted files (e.g., stolen laptop disk image, copied backup set, exfiltrated object storage bucket data). + - Has unlimited time to attempt offline attacks. + +2. **Curious cloud/storage provider** + - Can read stored ciphertext and associated metadata. + +3. **Malicious insider with file access** + - Has access to encrypted files via shared storage, backups, or internal systems. + - Does **not** have authorized access to the environment variable secret. + +## Adversaries (explicitly out of scope) + +If an attacker can obtain the environment variable secret, the primary confidentiality guarantee is already lost. Therefore the following are out of scope: + +- **Compromised host / root attacker** +- **Memory scraping / debugger attachment** +- **Process inspection (e.g., reading `/proc`, environment, shell history)** +- **Malware with user-level access capable of reading env vars** +- **Keylogging / clipboard capture used to obtain the secret** +- **Any attacker who can read the secret from CI logs, shell config, or secrets management mistakes** + +This is a deliberate scoping decision: `goaes` is not attempting to be a complete endpoint hardening solution. + +## Assumptions + +- Cryptographic primitives are implemented correctly by Go’s standard library. +- AES-256-GCM (or equivalent AEAD) is used correctly: + - Unique nonce per encryption under the same key + - Authentication failures cause decryption to fail closed +- The environment-supplied secret is high entropy: + - Prefer **32 random bytes** (256 bits) encoded as base64 + - Not a human-memorable password + +If the secret is not high entropy, offline guessing becomes viable and a password KDF would be required. + +## Key management model + +### Current model + +- Single secret (provided via environment variable) used to encrypt/decrypt files. + +### Design intent + +- The security of `goaes` depends primarily on **keeping this secret unknown to attackers** and **ensuring it has sufficient entropy**. + +### KDF position (current) + +- Not required if the environment secret is truly random high-entropy key material. +- If users ever supply human-chosen secrets, the project should add an explicit "passphrase mode" using a memory-hard KDF (Argon2id). + +## Threats and mitigations + +### T1: Offline brute force / guessing + +**Threat:** Attacker steals encrypted files and attempts to guess the key. +**Mitigation:** Use a high-entropy secret (32 random bytes). +**Notes:** A KDF is not necessary for truly random keys, but becomes necessary for human-chosen secrets. + +### T2: Ciphertext tampering / corruption + +**Threat:** Attacker modifies ciphertext to cause malicious or silent changes to plaintext. +**Mitigation:** Use AEAD (AES-GCM) and fail closed on authentication error. + +### T3: Nonce reuse under the same key + +**Threat:** Reusing a nonce with AES-GCM under the same key can catastrophically weaken confidentiality and integrity. +**Mitigation:** Ensure nonce uniqueness per encryption operation (cryptographically random nonces or a robust deterministic strategy). Treat nonce generation as a critical security requirement. + +### T4: Metadata manipulation (version/salt) + +**Threat:** Attacker edits metadata to influence parsing or key derivation logic. +**Mitigation:** Authenticate relevant metadata by binding it into AEAD (AAD). At minimum, authenticate the version field and any salt/parameters that affect keying. + +### T5: Key disclosure via operational mistakes + +**Threat:** Secret leaks through shell history, logs, CI output, process inspection, or misconfigured environment handling. + +**Mitigation (operational guidance):** +- Do not pass secrets via CLI args (they show in process lists and shell history). +- Avoid logging the secret or decoded bytes. +- Encourage secret injection via a secrets manager or `.env` with correct permissions. +- Prefer per-host secrets and limit reuse where feasible. + +(These mitigations reduce risk but do not change the out-of-scope boundary: if the secret is exposed, confidentiality is lost.) + +## Security requirements (implementation checklist) + +- Use AEAD encryption (AES-256-GCM or equivalent). +- Enforce: + - Nonce uniqueness per encryption under the same key + - Authentication check on decrypt (fail closed) +- File format includes: + - Magic bytes + version + - Nonce + - Ciphertext (including auth tag) + - Optional salt (cleartext), if used +- Bind into AAD: + - Version + - Salt (and any future KDF params) +- Zero/overwrite sensitive buffers where practical (best-effort; Go does not guarantee). +- Provide a deterministic test vector suite to prevent accidental format/crypto regressions. + +## Open design decisions (explicit) + +- **Passphrase mode:** Not currently supported. If added, it must be explicit and use Argon2id with published parameters. +- **Key rotation / crypto-erasure:** Not currently a priority. If implemented later, it will likely require a KEK/DEK envelope scheme with header metadata and versioned key slots. +- **Threat boundary:** The tool does not attempt to protect against runtime compromise or secret exfiltration from the host environment. + +## "Secure by default" guidance for users + +- Generate the secret as **32 random bytes**, then base64 encode it. +- Store it in a secure secret store or protected env file; do not paste it into shell history. +- Treat encrypted files as safe to store in untrusted locations, but treat the secret as highly sensitive. |
