Security guidelines
OpenQuok's Service key rules, RLS guidance, rate limiting, and SSR state-management safety.
Connect your agent today
Draft from chat, review in your calendar, and publish only what you approve.
Rules (non-negotiable)
- NEVER use the service client in client-side code.
- NEVER expose SUPABASE_SECRET_KEYto the client. It grants elevated, RLS-bypassing access and must only live in backend env vars. See Supabase.
- Use RLS policies for data access control.
- Always use the appropriate client for the context:
- Browser Client: Public data only
- RLS Client: Authenticated user data
- Service Client: Admin operations
- Configure rate limiting in backend/middlewares/rateLimit.ts and backend/config/GlobalConfig.ts (docs: /docs/configuration-backend/rate-limiting).
Channel credentials at rest
Connected channels store provider credentials in public.integrations.token (and refresh_token when needed) so the API and publish workers can call platforms. HTTP list/connect/public mappers must omit those columns.
For credentials-in-app channels (for example Dev.to), the pasted API key is reversible on the server — hashing cannot replace it. Document storage honestly in the channel setup guide (see Dev.to — How OpenQuok stores the API key).
Shipped mitigations: strip tokens from API responses; revoke authenticated column privileges on token / refresh_token (service_role keeps access); AES-GCM encrypt those columns at rest when INTEGRATIONS_TOKEN_ENCRYPTION_KEY or SECURITY_SECRET is set (decrypt in the repository for publish / refresh / trigger / mention paths).SSR state management security
- NEVER import or use authenticationRepository in any +page.server.ts or +layout.server.ts files.
- NEVER mutate shared state (singletons with mutable state) in server load functions.
- ALWAYS set export const ssr = false; for protected routes (user-specific data).
- ONLY enable SSR (export const ssr = true;) for public routes that don’t use shared mutable state.
- If you need auth info in SSR routes, use cookies/request context instead of shared state.
// ✅ SAFE: Use cookies for server-side auth
export const ssr = true;
export async function load({ cookies }) {
const accessToken = cookies.get('access_token');
// Use token to fetch user data per-request
}
// ❌ UNSAFE: Never do this in server code
import { authenticationRepository } from '$lib/user-auth/index';
await authenticationRepository.checkAuth(); // Shared state - security risk! Related Section(s)
Docker Compose (self-host) — security
Local/private-network defaults, env exposure, ports, and what not to do on a public host
Dev.to API key storage
Honest docs for credentials-in-app channel secrets
RBAC (roles & permissions)
How roles/permissions are loaded and enforced in the backend
Developer Guidelines
Back to the developer guidelines hub