@nacre.work/core 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,63 @@
|
|
|
1
1
|
# @nacre.work/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The data model, the permission resolver and the shared types behind
|
|
4
|
+
[Nacre](https://nacre.work) — a self-hosted knowledge index with fine-grained
|
|
5
|
+
access control.
|
|
6
|
+
|
|
7
|
+
**Most people do not install this.** Applications install
|
|
8
|
+
[`@nacre.work/sdk`](https://www.npmjs.com/package/@nacre.work/sdk), people run
|
|
9
|
+
[`@nacre.work/cli`](https://www.npmjs.com/package/@nacre.work/cli), and
|
|
10
|
+
operators run the container. This package is here because the API, the MCP
|
|
11
|
+
server and the worker all depend on it — and because a commercial module has to
|
|
12
|
+
resolve **the host's copy** of it, which needs it on the registry.
|
|
13
|
+
|
|
14
|
+
## What is in it
|
|
15
|
+
|
|
16
|
+
The permission resolver and its reference implementation, the schema and its
|
|
17
|
+
forward-only migrations, the Qdrant filter builder, the BM25 producer both sides
|
|
18
|
+
of search share, configuration loading, the extension registry, and the types
|
|
19
|
+
everything else is written against.
|
|
20
|
+
|
|
21
|
+
## The part worth knowing before depending on it
|
|
22
|
+
|
|
23
|
+
Six invariants hold across every consumer, and breaking one is a security
|
|
24
|
+
incident rather than a bug:
|
|
25
|
+
|
|
26
|
+
1. **The organization comes from the token** — never from a body, path or header.
|
|
27
|
+
2. **Access filtering is a pre-filter, never a post-filter.** The filter goes
|
|
28
|
+
inside the index traversal, so `top_k` returns k *permitted* results.
|
|
29
|
+
3. **A failure to evaluate permissions denies access.** There is no
|
|
30
|
+
"couldn't compute it, let it through" path.
|
|
31
|
+
4. **"No permission" and "no such object" are indistinguishable** — `404`, never
|
|
32
|
+
`403`, including the wording.
|
|
33
|
+
5. **A deleted document is never returned**, including before collection.
|
|
34
|
+
6. **`write` does not imply `read`.** `admin` implies both. This is the opposite
|
|
35
|
+
of most permission systems and is not a thing to fix.
|
|
36
|
+
|
|
37
|
+
## Extension points
|
|
38
|
+
|
|
39
|
+
A commercial module registers into these from its module body while
|
|
40
|
+
`loadModules` is running:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
registerAuthProvider(provider)
|
|
44
|
+
registerAuthzResolver(resolver)
|
|
45
|
+
registerAuditSink(sink)
|
|
46
|
+
registerIngestGate(gate)
|
|
47
|
+
mountAdminRoutes(...routes)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The registry is module-level state, so it belongs to whichever *copy* of this
|
|
51
|
+
package was loaded. A module that resolves a second copy registers into a
|
|
52
|
+
registry the host never reads — which is why every module declares this as a
|
|
53
|
+
**peer** dependency rather than an ordinary one.
|
|
54
|
+
|
|
55
|
+
## Versioning
|
|
56
|
+
|
|
57
|
+
`0.x`, and the packages ship together referencing each other by exact version.
|
|
58
|
+
A minor bump can move an interface; the
|
|
59
|
+
[extension contract](https://github.com/nacre-work/nacre/blob/main/docs/extensions.md)
|
|
60
|
+
says which parts are load-bearing for a module author.
|
|
61
|
+
|
|
62
|
+
Apache 2.0. The permission model in full:
|
|
63
|
+
[github.com/nacre-work/nacre](https://github.com/nacre-work/nacre/blob/main/docs/authz.md).
|