mono/packages/ui/docs/security.md
2026-02-08 15:09:32 +01:00

42 lines
2.4 KiB
Markdown

# Security Improvement Plan
## 1. Secrets Management (Critical)
**Issue**: [`Profile.tsx`](../src/pages/Profile.tsx) currently fetches and exposes API keys (OpenAI, Google, etc.) to the client browser.
**Goal**: Never send raw API keys to the client unless explicitly requested for a "Settings" view context, and even then, mask them.
### A. Client Side (`Profile.tsx`)
- [ ] **Remove** all code that fetches `_api_key` columns from `profiles` in [`Profile.tsx`](../src/pages/Profile.tsx).
- [ ] **Remove** Input fields for API keys in the main Profile view in [`Profile.tsx`](../src/pages/Profile.tsx).
- [ ] **Create** a new "Provider Settings" page (or modal) protected by re-auth or strict checks (Target: `src/pages/ProviderSettings.tsx`).
- [ ] Use `/api/me/secrets` (Server Proxy) to manage keys, never direct DB Updates for secrets.
### B. Server Side
- [ ] Ensure `user_secrets` table has RLS `auth.uid() = user_id`.
- [ ] Ensure no public endpoints (like `/api/profile/:id`) return columns from `user_secrets` in [`ServingProduct`](../server/src/products/serving/index.ts).
---
## 2. Authorization & ACL
**Goal**: Secure multi-user collaboration and Organization access.
### A. Shared Pages
- [ ] Implement `page_collaborators` RLS.
- [ ] **Verify**: A user cannot edit a page they are only a 'viewer' on.
- [ ] **Verify**: Listing pages returns both owned and shared pages in [`PageManager.tsx`](../src/components/PageManager.tsx).
### B. Organization Impersonation
- [ ] **Middleware**: Implement `OrganizationMiddleware` in `server/src`.
- [ ] **Logic**: If `X-Org-Slug` header is present:
1. Check if `auth.uid()` is an Admin/Member of that Org.
2. If yes, scope all queries to that Organization's `collection_id` or Context.
3. (Advanced) Allow "Impersonation" where an Admin acts as a specific user. This requires a signed Token exchange or a Server-Side "Sudo" mode. **Decision**: For now, stick to Role-Based Access (Admin reads all Org data) rather than direct User Impersonation to avoid audit confusion.
---
## 3. General Hardening
- [ ] **404 Handling**: In [`Post.tsx`](../src/pages/Post.tsx), ensure 404s do not redirect blindly.
- [ ] If permission denied (Private post), show "Unauthorized" (403).
- [ ] If missing, show "Not Found" (404).
- [ ] **Rate Limiting**: Ensure `/api/feed` and `/api/search` have basic rate limiting (using `hono-rate-limiter` or Redis) to prevent scraping.