Defensive baseline for the whole codebase. Anything marked MUST is non-negotiable; the rest are strong defaults.
- MUST never log secrets: tokens, passwords, API keys, full JWTs, OAuth refresh tokens, cookies. Enforced by code review;
goseccatches obvious cases. - All secrets come from environment variables.
.env.exampledocuments them;.envis.gitignore'd. - OAuth tokens stored in the DB are encrypted with AES-256-GCM (
pkg/crypto). Encryption keys live inENCRYPTION_KEYenv var, not in the DB. - Key rotation: plan for it — tokens should be re-encryptable with a new key without downtime.
- JWT access tokens (HMAC-SHA256, 15-minute expiry) — see api-design.md.
- Refresh tokens stored as SHA-256 hashes in Redis (7-day TTL) + PostgreSQL
refresh_tokensbackup. - Logout MUST invalidate the refresh token (delete from Redis).
- Platform-modifying operations restricted to
owner/adminroles (RBAC inpkg/domain/roles.go).
- Validate every external input with
go-playground/validator/v10at the handler boundary. - Convert validation errors to HTTP 400 with field-level
details. - Never trust
channel_id,business_id, or other identifiers from the LLM — resolve via the token-lookup fallback pattern (GetDecryptedTokeninservices/api/internal/service/integration.go).
- MUST use parameterized queries. For PostgreSQL:
pgx+squirrel(the builder handles placeholders automatically). - MUST never build SQL with
fmt.Sprintf. No exceptions. - MongoDB: pass BSON documents, not string-concat queries.
- React escapes by default; don't call
dangerouslySetInnerHTMLunless the content is vetted (LLM output is not vetted). - CSRF tokens for state-changing operations that use cookie-based auth (not needed for pure Bearer-token APIs, but if session cookies are ever added, this matters).
Three layers, each with its own purpose:
- API middleware (Redis,
services/api/internal/middleware/ratelimit.go) — per-IP + per-endpoint, guards against brute-force and noisy clients. - LLM Router (Redis,
pkg/llm/ratelimit.go) — per-user, per-tier (requests/min, tokens/min, tokens/month, daily spend cap). - Platform agents — each respects the upstream platform's limits (VK quotas, Telegram
429 retry_afterwith backoff queue).
- HTTPS only in production. HTTP → HTTPS redirect at the load balancer / nginx.
- CORS: explicit allowlist of origins (
services/api/internal/middleware/cors.go); never*in production.
- Sensitive actions append to
audit_logs(PostgreSQL, append-only). - Events to log: login, token refresh, logout, integration connect/disconnect, role change, admin operations.
- Fields:
user_id,action,resource,detailsJSONB,created_at. - MUST not include raw secrets in
details.
- Russian 152-ФЗ (personal data law) — user data is stored within scope; no export outside approved regions.
- Structured logs include a correlation ID per request (
X-Request-ID) so events can be traced without containing sensitive payloads.
- Every secret is in env vars (not in code, not in version control).
- OAuth tokens encrypted with AES-256-GCM.
- Rate limiting enabled (Redis) on all public endpoints.
- CORS allowlist configured (not
*). - HTTPS enforced.
- Input validation on every endpoint.
- SQL injection audit (
grep 'Sprintf.*SELECT'returns nothing meaningful). - Audit logs firing for sensitive actions.
- Connection pools for every stateful dependency (PostgreSQL, MongoDB, Redis).
- Cache expensive queries in Redis (5–60 min TTL depending on volatility).
- Paginate list endpoints (default 20, max 100) — see api-design.md.
- Indexes on every frequently-queried field. Review
migrations/postgres/*.sqlwhen adding a new query pattern. - Stream large responses: SSE for chat, chunked transfer for file downloads.
- Next.js
Imagecomponent for all images — automatic optimization. - Route-level code splitting:
dynamic(() => import(...), { ssr: false })for heavy client-only components. - Debounce search inputs (300 ms).
- Virtualize long lists (
react-windowor equivalent). - Check bundle size with
pnpm build; investigate any single chunk > 250 KB gzipped.
| Metric | Target |
|---|---|
| API latency (p95, excluding external calls) | < 500 ms |
| LLM response (p95) | < 10 s |
| Sync time per platform (target, excl. external moderation) | < 30 s |
| Uptime | > 99.5% |