docs+fix: le modèle de sécurité local-first, et le retrait de linkTo qui le brisait
La règle d'accès est « qui a la référence ET la clé lit » — jamais « qui a la référence lit ». Il n'y a pas de tiers dans cette phrase : le moteur ne vérifie une permission qu'à l'ÉCRITURE, jamais à la lecture. Le contenu est chiffré, la clé EST le droit. C'est ce que veut dire local-first ici : il n'y a personne à qui demander, donc la possession est tout le mécanisme. Ce que cette règle achète, et qui n'était consigné nulle part : une référence n'accordant rien, **elle n'est pas récursive**. Un document largement diffusé peut pointer vers un document restreint — la référence dit qu'il existe, la clé dit qui le lit. D'où la confidentialité COMPOSABLE : un sommaire diffusé qui renvoie à des chapitres restreints, un événement public qui renvoie à sa liste de participants. L'auteur diffuse un document et décide encore, document référencé par document référencé, qui reçoit la clé. `linkTo` détruisait cette construction. Il rendait la CLÉ là où un appelant demande une référence, transformant la règle en « qui a la référence lit » — pour ce document et pour tout ce qu'il MENTIONNE. Ajouté et retiré le même jour. Documenté en §0, avant tout le reste, avec la raison pour laquelle un agent perd ce point avec constance : les réflexes client-serveur fournissent la moitié manquante sans qu'on s'en aperçoive — quelque part un serveur vérifierait, un lien serait un identifiant inoffensif, « Bob a-t-il le droit ? » aurait une réponse. Aucun des trois n'est vrai ici, et du code écrit là-dessus n'échoue pas : il accorde en silence. Rien ne passe au rouge. Renommé au passage : `publishRepoLink`/`isPublished` → `recordInPublicStore`/ `isInPublicStore`. Ces méthodes n'ont pas de pendant amont et « publier » ne désigne rien de précis ici. 171 tests unitaires, e2e 42/42 en 3,6 min.
This commit is contained in:
@@ -837,7 +837,7 @@ const identity = new IdentityStore(
|
||||
];
|
||||
setCurrentUser("owner-O");
|
||||
getCaps().open("did:ng:o:protdoc", "protected");
|
||||
const link = getCaps().publishRepoLink("did:ng:o:pubdoc");
|
||||
const link = getCaps().recordInPublicStore("did:ng:o:pubdoc");
|
||||
const ownerView = [...(libUseShape(null, null) as Iterable<any>)].map((i) => i.v);
|
||||
// A stranger holds nothing — including the PUBLISHED document, until the repo
|
||||
// link reaches them (§5: whoever has the URL reads the content).
|
||||
@@ -871,7 +871,7 @@ const identity = new IdentityStore(
|
||||
setCurrentUser(ownerId);
|
||||
const doc = await storeRegistry.createEntityDoc(ownerId, "public");
|
||||
const ownerInbox = await storeRegistry.openDocumentInbox(doc);
|
||||
const link = storeRegistry.linkTo(doc); // the repo link the owner circulates
|
||||
const link = getCaps().capFor(doc)!; // out-of-band: the harness plays 'the owner sent it'
|
||||
|
||||
setCurrentUser(depositorId);
|
||||
getCaps().learn(link);
|
||||
|
||||
Reference in New Issue
Block a user