docs: credential management design — classification, current state, recommended architecture
This commit is contained in:
153
docs_v1.0/DESIGN/CREDENTIAL_MANAGEMENT_V1.0.md
Normal file
153
docs_v1.0/DESIGN/CREDENTIAL_MANAGEMENT_V1.0.md
Normal file
@@ -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<String> = 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<String> = 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 |
|
||||
Reference in New Issue
Block a user