Skip to content

Security guidelines

OpenQuok's Service key rules, RLS guidance, rate limiting, and SSR state-management safety.

2 min read

Connect your agent today

Draft from chat, review in your calendar, and publish only what you approve.

Start for $0

Rules (non-negotiable)

  1. NEVER use the service client in client-side code.
  2. NEVER expose SUPABASE_SECRET_KEYto the client. It grants elevated, RLS-bypassing access and must only live in backend env vars. See Supabase.
  3. Use RLS policies for data access control.
  4. Always use the appropriate client for the context:
    • Browser Client: Public data only
    • RLS Client: Authenticated user data
    • Service Client: Admin operations
  5. 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!
Search documentation
Find a docs page
Discord Support