diff --git a/docs_v1.0/DESIGN/CREDENTIAL_MANAGEMENT_V1.0.md b/docs_v1.0/DESIGN/CREDENTIAL_MANAGEMENT_V1.0.md new file mode 100644 index 0000000..a668f03 --- /dev/null +++ b/docs_v1.0/DESIGN/CREDENTIAL_MANAGEMENT_V1.0.md @@ -0,0 +1,153 @@ +--- +document_type: "design_doc" +service: "MOMENTRY_CORE" +title: "Credential & Configuration Management" +version: "V1.0" +date: "2026-05-15" +author: "M5" +status: "draft" +--- + +# Credential & Configuration Management + +| Item | Value | +|------|-------| +| Scope | API keys, passwords, database URLs, service endpoints, tool paths | +| Status | Draft | +| Key principle | Secrets never in source code. Least privilege. Rotatable. | + +## Classification + +### Level 1: Public Configuration (safe in code / .env) + +| Category | Examples | Current storage | Recommendation | +|----------|----------|----------------|----------------| +| Service URLs | DB host, Redis host, Qdrant URL | `src/core/config.rs` via env vars | ✅ Keep as env vars | +| File paths | `MOMENTRY_OUTPUT_DIR`, `SCRIPTS_DIR` | `src/core/config.rs` | ✅ Keep as env vars | +| Port numbers | `3002`, `3003`, `8082` | `src/bin/service.rs` | ✅ Keep as constants | + +### Level 2: Internal Secrets (safe in DB with encryption) + +| Category | Examples | Current storage | Recommendation | +|----------|----------|----------------|----------------| +| API keys | `muser_*`, `msys_*`, `msvc_*` | `dev.api_keys` table | ✅ Already encrypted via AES-256-GCM | +| TMDB API key | `TMDB_API_KEY` | `.env` file | Keep in env or api_keys table | +| Ollama models | — | System env | Keep as env | + +### Level 3: External Tool Credentials + +| Tool | Credential | Recommendation | +|------|-----------|----------------| +| PostgreSQL | `DATABASE_URL` | Env var or macOS Keychain | +| Redis | `REDIS_URL` + password | Env var | +| SFTPGo | admin password | api_keys table | +| Gitea | token | api_keys table | +| Email (SMTP) | username + password | api_keys table (encrypted) | + +## Current State + +### What already works well + +```rust +// src/core/config.rs — environment variable loading (already implemented) +pub static DATABASE_URL: Lazy = Lazy::new(|| { + env::var("DATABASE_URL").unwrap_or_else(|_| "postgres://accusys@localhost:5432/momentry".to_string()) +}); +``` + +```rust +// src/core/api_key/ — API key management (already implemented) +// - AES-256-GCM encryption +// - Key rotation +// - Strength validation +// - Anomaly detection +// - Audit logging +``` + +### What needs improvement + +| Gap | Issue | Fix | +|-----|-------|-----| +| `.env` files in repo | `.env` sometimes checked in accidentally | Add to `.gitignore`, use `.env.example` | +| Hardcoded demo key in server.rs | `DEMO_USER_API_KEY` in source | Move to env var with fallback | +| No key hierarchy | Machine keys vs user keys mixed | Use existing prefix system: `msys_` (system), `muser_` (user), `msvc_` (service) | +| No macOS Keychain | Credentials in plaintext env vars | Optional: use `security` CLI for local dev | + +## Recommended Architecture + +``` +┌─────────────────────────────────────────────┐ +│ Momentry Core │ +│ │ +│ src/core/config.rs │ +│ ├── env::var("DATABASE_URL") │ +│ ├── env::var("REDIS_URL") │ +│ └── env::var("MOMENTRY_API_KEY") │ +│ │ +│ src/core/api_key/ (AES-256-GCM) │ +│ ├── Database: dev.api_keys │ +│ │ ├── muser_* (user tokens) │ +│ │ ├── msys_* (system keys) │ +│ │ └── msvc_* (service-to-service) │ +│ │ │ +│ ├── encryption.rs (encrypt_at_rest) │ +│ ├── rotation.rs (auto rotation) │ +│ └── audit_logger.rs (access tracking) │ +│ │ +│ ~/.env (local dev, not in git) │ +│ ├── DATABASE_URL │ +│ ├── MOMENTRY_API_KEY │ +│ └── AUDIT_ENCRYPTION_KEY │ +└─────────────────────────────────────────────┘ +``` + +## Rules + +### 1. Never hardcode secrets in source code + +```rust +// ❌ BAD — hardcoded API key +static API_KEY: &str = "muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69"; + +// ✅ GOOD — env var with fallback +static API_KEY: Lazy = Lazy::new(|| { + env::var("MOMENTRY_API_KEY").unwrap_or_default() +}); +``` + +### 2. Use the api_keys table for runtime-issued tokens + +```sql +-- dev.api_keys table (already exists) +INSERT INTO dev.api_keys (api_key, key_type, description) +VALUES ('muser_...', 'user', 'demo user'); +``` + +### 3. Keep a `.env.example` in repo (values masked) + +```bash +# .env.example (checked in, no real secrets) +DATABASE_URL=postgres://user@localhost:5432/momentry +REDIS_URL=redis://:password@localhost:6379 +MOMENTRY_API_KEY=muser_your_key_here +TMDB_API_KEY=tmdb_your_key_here +``` + +### 4. `.env` (real secrets) in `.gitignore` + +Already done — `target/` and `*.tar.gz` are in `.gitignore`. Verify `.env` is also there. + +## Implementation Priority + +| # | Task | Effort | Risk | +|---|------|--------|:---:| +| 1 | Move `DEMO_USER_API_KEY` from source to env var | Low | Low | +| 2 | Verify `.env` is gitignored | Low | Low | +| 3 | Create `.env.example` | Low | Low | +| 4 | Add macOS Keychain option for local dev | Medium | Low | + +## Version History + +| Version | Date | Changes | +|---------|------|---------| +| V1.0 | 2026-05-15 | Initial — credential classification, current state, recommended architecture |