docs: credential management design — classification, current state, recommended architecture

This commit is contained in:
Accusys
2026-05-15 12:22:56 +08:00
parent 9c47bb331f
commit 66658b1156

View 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 |