summaryrefslogtreecommitdiff
path: root/THREAT_MODEL.md
diff options
context:
space:
mode:
authorLevi Durfee <levi.durfee@gmail.com>2026-01-08 10:40:44 -0500
committerLevi Durfee <levi.durfee@gmail.com>2026-01-08 10:45:52 -0500
commitc4c26a1b1348dc8d3a0a6ecce3a031d212edf6b1 (patch)
tree4013dcca8e8fcd9de2ec87e335979b0f59807dd3 /THREAT_MODEL.md
parent7633745f3e0517298a6337adb8a21a327e265701 (diff)
Add threat model
Diffstat (limited to 'THREAT_MODEL.md')
-rw-r--r--THREAT_MODEL.md164
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.