Aller au contenu
Tous les articles
4 min de lecture

Votre espace de travail est une frontière de sécurité.

Pourquoi les contrôles d'appartenance appartiennent à chaque lecture et écriture, et pourquoi une URL de tâche ne doit jamais donner accès.

l'équipe supastack

Dérivez l'appartenance côté serveur

Un ID d'enregistrement identifie quelque chose ; il ne prouve pas qui peut le lire. supastack délimite les enregistrements utilisateur par workspaceId. Le serveur résout l'espace de travail de l'utilisateur authentifié et inclut ce périmètre lors de la lecture ou de la modification d'un enregistrement.

Ne traitez pas un ID d'espace envoyé par le navigateur comme une preuve d'appartenance. Le navigateur peut demander une action, mais le contexte serveur de confiance doit établir de qui il s'agit. Cette règle doit valoir pour le statut de tâche, la configuration fournisseur sauvegardée, les enregistrements d'usage et chaque ressource appartenant au produit. Les layouts et composants peuvent filtrer ce qui s'affiche, mais le rendu n'est pas une autorisation — le contrôle appartient à l'endroit où l'enregistrement est réellement lu ou écrit.

Tout le reste de cet article découle de cette règle : l'appartenance se dérive, elle ne se demande jamais. À l'instant où un workspaceId envoyé par le client est pris pour argent comptant quelque part, tous les autres contrôles deviennent de la décoration. L'article sur l'authentification couvre comment la session elle-même est établie en amont de cette frontière.

L'appartenance fait partie de la frontière

Le périmètre répond à quel espace un enregistrement appartient ; l'appartenance répond si cet utilisateur appartient à cet espace. Résolvez les deux côté serveur. supastack modélise des espaces personnels et d'organisation avec les rôles owner, admin et member — le guide des espaces de travail documente le modèle.

Les rôles ajoutent un second axe : un membre peut lire ce que seul un admin peut modifier. Gardez les deux contrôles distincts — « appartient à cet espace » et « peut effectuer cette action » — pour qu'une rétrogradation ou un retrait prenne effet à la même frontière que tout le reste. Invitations et retraits font partie du même cycle de vie, pas une réflexion d'admin après coup.

Les changements d'appartenance doivent aussi prendre effet immédiatement. La prochaine requête d'un membre retiré doit échouer à la frontière, pas quand un jeton en cache arrive à expiration — une raison de plus pour que le contrôle vive là où les enregistrements sont lus, plutôt que dans un identifiant émis plus tôt.

Testez les requêtes qui doivent échouer

Un test qui laisse un propriétaire récupérer un enregistrement prouve le chemin nominal. Il ne prouve pas l'isolation. Associez-le à un second espace demandant le même enregistrement, une requête anonyme et une écriture tentant de substituer un autre propriétaire.

Affirmez le comportement externe autant que le résultat persisté. Une requête rejetée ne doit pas muter les données d'un autre espace, et une réponse d'erreur ne doit pas fuiter de secrets ni de détails bruts de base. Ces contrôles rendent la frontière révisable quand l'implémentation change.

  • Un second espace demande le même ID d'enregistrement — rejeté.
  • Une requête anonyme frappe le même endpoint — rejetée.
  • Un membre retiré de l'espace réessaie — rejeté.
  • Une écriture nomme un autre propriétaire ou espace — rejetée, sans rien muter.
  • Les réponses d'erreur restent génériques — pas de secrets, pas de détails de schéma.

Portez la règle dans votre produit

Quand vous ajoutez une nouvelle table produit, décidez de son appartenance avant de construire l'écran. Incluez workspaceId dans son modèle de persistance, résolvez l'espace via la frontière serveur existante et utilisez ce contexte dans les opérations de liste comme de détail.

Les workers en arrière-plan demandent le même soin. Une tâche en file doit porter assez de contexte de confiance pour charger le bon enregistrement, tandis que les identifiants fournisseur restent sur le serveur. Un job planifié qui charge des lignes par simple ID reste à l'intérieur de la frontière. Une règle d'appartenance cohérente est plus facile à maintenir qu'une collection d'exceptions par route.

La surface API appartient à la même frontière. Les clés API d'espace et les webhooks sortants signés portent avec eux le périmètre de l'espace — une clé ne doit jamais devenir un moyen de lire à travers les tenants, et une charge de webhook ne doit jamais transporter les enregistrements d'un voisin. Le guide du module API couvre la forme de cette surface.

Questions fréquentes sur l'isolation des espaces

L'isolation multi-tenant soulève la même poignée de questions sur chaque projet. Voici celles qu'il vaut mieux trancher tôt.

  • Le périmètre au niveau applicatif suffit-il, ou faut-il la sécurité au niveau ligne ? — Un périmètre appliqué côté serveur sur chaque lecture et écriture couvre le modèle de menace de la plupart des SaaS. Le RLS en base ajoute de la défense en profondeur mais ne remplace pas les contrôles à la frontière — les workers et les clés API ont toujours besoin de la même règle.
  • Comment le partage entre espaces doit-il fonctionner ? — Modélisez-le explicitement — une invitation, une ligne d'appartenance — plutôt qu'en affaiblissant le périmètre. « Toute personne ayant le lien » doit être une fonctionnalité conçue avec ses propres contrôles, pas un accident.
  • Qu'est-ce qui casse en premier dans les apps multi-tenant ? — Les chemins de commodité : liens de reprise, outillage admin, workers qui chargent des enregistrements par simple ID. Auditez chaque chemin de code qui touche un enregistrement sans passer par le périmètre normal.
  • Comment ajouter un périmètre à une table existante ? — Ajoutez workspaceId, remplissez-le, appliquez-le dans les lectures et écritures, puis touchez à l'UI. Livrez d'abord les tests négatifs pour que la frontière soit prouvée plutôt que supposée.
  • Les actions serveur ont-elles besoin de contrôles si la page est protégée ? — Oui. Les gardes de page masquent des écrans ; elles n'autorisent pas les opérations. Chaque action résout la session et l'espace indépendamment.

Questions fréquentes

14 questions

Qu'est-ce que supastack ?

supastack est une fondation modulaire pour construire des produits SaaS avec IA. Elle réunit l'infrastructure commune pour que vous puissiez vous concentrer sur les fonctionnalités propres à votre produit.

Prend-il en charge le web et le mobile ?

Oui. supastack inclut des applications Next.js et Expo comme points de départ pour des expériences web et mobile.

Quelle authentification est incluse ?

Better Auth couvre e-mail/mot de passe, OTP et connexion sociale. Les espaces de travail personnels sont provisionnés avec le compte pour que les enregistrements restent délimités dès le premier jour.

Comment l'IA est-elle prise en charge ?

supastack inclut une IA multi-fournisseurs configurable, le suivi d'usage, des budgets, et la prise en charge chiffrée de vos propres clés (BYOK).

Comment les abonnements sont-ils gérés ?

Pour les produits construits sur le kit, la facturation Stripe, les abonnements et les droits d'accès forment la base de l'accès payant. Les secrets fournisseur restent côté serveur.

Où vit le code propre à mon produit ?

Les fonctionnalités propres au produit restent dans un codebase séparé, tandis que le produit configure et intègre les modules de la fondation supastack.

Comment fonctionne la tarification de supastack ?

Le kit est un achat unique avec mises à jour à vie : Un framework à 249 $ (prix de lancement temporaire — 100 $ de réduction par rapport au prix habituel de 349 $) ou Tous les frameworks (Next.js, iOS, Android) à 499 $ (prix de lancement temporaire — 100 $ de réduction par rapport au prix habituel de 599 $), plus 75 $ par siège développeur supplémentaire. Pas d'abonnement au kit. Le paiement sur ce site livre votre clé de licence par e-mail, avec accès au dépôt via invitation GitHub.

Comment les espaces de travail délimitent mes données ?

Les enregistrements appartenant aux utilisateurs sont délimités par workspaceId. Identité, droits d'accès, usage IA, événements de facturation et entrées d'audit restent dans le périmètre de l'espace personnel.

Comment fonctionnent les jobs en arrière-plan ?

Trigger.dev est le runtime de jobs explicite. Le contrat JobRunner ne promet que enqueue, status et cancel — la sémantique de workflow reste propre à Trigger.dev et explicite.

En quoi l'e-mail diffère-t-il de la prospection ?

L'e-mail transactionnel couvre les flux produit comme les avis de fin de tâche. La prospection à froid et les campagnes relèvent du produit, hors du module e-mail de ce kit.

Comment fonctionnent les achats sur mobile ?

Le mobile inclut les achats natifs et leur restauration via RevenueCat, avec un accès vérifié par votre serveur. Configurez les comptes des boutiques et terminez les tests sur appareil avant publication. La facturation web reste séparée.

Où vivent les clés des fournisseurs IA ?

Les identifiants BYOK sont chiffrés et restent côté serveur. Les clés sont masquées dans les journaux ; l'usage et les budgets restent visibles au niveau de l'espace de travail.

Quels moyens de paiement le checkout accepte-t-il ?

Le checkout hébergé par Stripe accepte les cartes et peut aussi proposer Alipay et WeChat Pay une fois ces portefeuilles activés sur le compte Stripe — pratique pour les acheteurs en Chine. Les autorisations de portefeuille se confirment de manière asynchrone : la page de licence se met à jour dès que le paiement est validé.

Puis-je obtenir un remboursement ?

Une fois que vous avez accès au dépôt, supastack vous appartient pour toujours et ne peut donc pas être remboursé. Mais rassurez-vous : vous obtenez le code source complet avec des mises à jour à vie pour créer et déployer un nombre illimité de produits pour vous ou vos clients. Vous ne pouvez simplement pas revendre le code ni redistribuer le dépôt sous forme de kit de démarrage ou de modèle.

FR