@nacre.work/core 0.0.0 → 0.2.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.
Files changed (89) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +9 -0
  3. package/dist/audit.d.ts +41 -0
  4. package/dist/audit.d.ts.map +1 -0
  5. package/dist/audit.js +18 -0
  6. package/dist/audit.js.map +1 -0
  7. package/dist/authz/cache.d.ts +20 -0
  8. package/dist/authz/cache.d.ts.map +1 -1
  9. package/dist/authz/cache.js +29 -0
  10. package/dist/authz/cache.js.map +1 -1
  11. package/dist/authz/filter.d.ts +54 -3
  12. package/dist/authz/filter.d.ts.map +1 -1
  13. package/dist/authz/filter.js +45 -9
  14. package/dist/authz/filter.js.map +1 -1
  15. package/dist/authz/index.d.ts +3 -3
  16. package/dist/authz/index.d.ts.map +1 -1
  17. package/dist/authz/index.js +2 -2
  18. package/dist/authz/index.js.map +1 -1
  19. package/dist/config.d.ts +55 -1
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +245 -7
  22. package/dist/config.js.map +1 -1
  23. package/dist/db/client.d.ts +39 -0
  24. package/dist/db/client.d.ts.map +1 -1
  25. package/dist/db/client.js +82 -0
  26. package/dist/db/client.js.map +1 -1
  27. package/dist/db/migrate.d.ts.map +1 -1
  28. package/dist/db/migrate.js +49 -0
  29. package/dist/db/migrate.js.map +1 -1
  30. package/dist/index.d.ts +21 -3
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +12 -3
  33. package/dist/index.js.map +1 -1
  34. package/dist/lifecycle.d.ts +57 -0
  35. package/dist/lifecycle.d.ts.map +1 -0
  36. package/dist/lifecycle.js +84 -0
  37. package/dist/lifecycle.js.map +1 -0
  38. package/dist/logging.d.ts +46 -0
  39. package/dist/logging.d.ts.map +1 -0
  40. package/dist/logging.js +110 -0
  41. package/dist/logging.js.map +1 -0
  42. package/dist/metadata.d.ts +50 -0
  43. package/dist/metadata.d.ts.map +1 -0
  44. package/dist/metadata.js +127 -0
  45. package/dist/metadata.js.map +1 -0
  46. package/dist/metrics.d.ts +19 -1
  47. package/dist/metrics.d.ts.map +1 -1
  48. package/dist/metrics.js +84 -2
  49. package/dist/metrics.js.map +1 -1
  50. package/dist/migrations/0008_authenticating_lookup.sql +124 -0
  51. package/dist/migrations/0009_refresh_tokens.sql +73 -0
  52. package/dist/migrations/0010_definer_search_path.sql +22 -0
  53. package/dist/migrations/0011_sweep_lease.sql +36 -0
  54. package/dist/migrations/0012_prune.sql +118 -0
  55. package/dist/migrations/0013_reindex.sql +65 -0
  56. package/dist/migrations/0014_retired_collections.sql +68 -0
  57. package/dist/oauth.d.ts +45 -0
  58. package/dist/oauth.d.ts.map +1 -0
  59. package/dist/oauth.js +53 -0
  60. package/dist/oauth.js.map +1 -0
  61. package/dist/observability.d.ts.map +1 -1
  62. package/dist/observability.js +100 -13
  63. package/dist/observability.js.map +1 -1
  64. package/dist/passwords.d.ts +37 -0
  65. package/dist/passwords.d.ts.map +1 -0
  66. package/dist/passwords.js +234 -0
  67. package/dist/passwords.js.map +1 -0
  68. package/dist/redis.d.ts +46 -0
  69. package/dist/redis.d.ts.map +1 -0
  70. package/dist/redis.js +234 -0
  71. package/dist/redis.js.map +1 -0
  72. package/dist/reindex.d.ts +87 -0
  73. package/dist/reindex.d.ts.map +1 -0
  74. package/dist/reindex.js +97 -0
  75. package/dist/reindex.js.map +1 -0
  76. package/dist/s3.d.ts +111 -0
  77. package/dist/s3.d.ts.map +1 -0
  78. package/dist/s3.js +242 -0
  79. package/dist/s3.js.map +1 -0
  80. package/dist/tsconfig.tsbuildinfo +1 -1
  81. package/dist/vector/query.d.ts +49 -4
  82. package/dist/vector/query.d.ts.map +1 -1
  83. package/dist/vector/query.js +43 -10
  84. package/dist/vector/query.js.map +1 -1
  85. package/dist/vector/search.d.ts +175 -4
  86. package/dist/vector/search.d.ts.map +1 -1
  87. package/dist/vector/search.js +320 -7
  88. package/dist/vector/search.js.map +1 -1
  89. package/package.json +26 -8
package/dist/config.d.ts CHANGED
@@ -17,7 +17,18 @@
17
17
  export interface Config {
18
18
  readonly env: 'development' | 'production';
19
19
  readonly canonicalUrl: string;
20
- readonly logLevel: string;
20
+ /**
21
+ * The identity provider in front of this installation, if there is one.
22
+ *
23
+ * Optional and empty by default, because a self-hosted Nacre usually has no
24
+ * OAuth authorization server at all: sign-in is email and password, and an
25
+ * agent presents a service account key. Named here only so the RFC 9728
26
+ * discovery document can point a client at the right place when a deployment
27
+ * *does* have one — see packages/core/oauth.ts for why pointing it at
28
+ * ourselves would be worse than leaving it out.
29
+ */
30
+ readonly oauthAuthorizationServer: string;
31
+ readonly logLevel: 'debug' | 'info' | 'warn' | 'error';
21
32
  readonly logFormat: 'json' | 'text';
22
33
  readonly pgUrl: string;
23
34
  readonly pgPoolMax: number;
@@ -31,9 +42,11 @@ export interface Config {
31
42
  readonly parserEndpoint: string;
32
43
  readonly rerankerEndpoint: string | undefined;
33
44
  readonly rerankerEnabled: boolean;
45
+ readonly rerankCandidates: number;
34
46
  readonly jwtIssuer: string;
35
47
  readonly jwtAudience: string;
36
48
  readonly accessTokenTtl: number;
49
+ readonly refreshTokenTtl: number;
37
50
  readonly aclCacheTtl: number;
38
51
  readonly aclPropagationSla: number;
39
52
  readonly aclTagHashBytes: number;
@@ -59,10 +72,51 @@ export interface Config {
59
72
  readonly indexMaxAttempts: number;
60
73
  readonly rateSearchPerMin: number;
61
74
  readonly rateIngestPerHour: number;
75
+ readonly rateLoginPer15Min: number;
76
+ readonly rateLoginSourcePer15Min: number;
77
+ readonly trustProxy: number;
78
+ readonly metricsToken: string | undefined;
62
79
  readonly maxDocumentBytes: number;
63
80
  readonly auditRetentionDays: number;
64
81
  readonly auditQueryText: boolean;
82
+ /** The reindex rollback window: how long a superseded collection survives. */
83
+ readonly collectionRetentionDays: number;
84
+ /** How long a presigned link to a document's bytes stays valid. */
85
+ readonly presignTtl: number;
86
+ /**
87
+ * Object storage, or `undefined` when a deployment has none.
88
+ *
89
+ * Absent is a supported configuration and not a degraded one: document bytes
90
+ * then live in `documents.source_ref`, which is what every deployment did
91
+ * before this existed. What is *not* supported is half of it — see the
92
+ * cross-field check, and the reason it is a check rather than a set of
93
+ * independent optionals.
94
+ */
95
+ readonly s3: {
96
+ readonly endpoint: string;
97
+ readonly bucket: string;
98
+ readonly region: string;
99
+ readonly accessKey: string;
100
+ readonly secretKey: string;
101
+ readonly forcePathStyle: boolean;
102
+ } | undefined;
103
+ }
104
+ /**
105
+ * The keys a token may be verified against, and the one it is signed with.
106
+ *
107
+ * Here rather than in each process because `api` and `mcp` verify with the same
108
+ * secret and must never disagree about which keys are current. Two copies of
109
+ * this function are two chances for a rotation to reach one and not the other,
110
+ * which produces 401s on part of the traffic and not the rest — the hardest
111
+ * failure of the set to read from outside.
112
+ */
113
+ export interface JwtKeys {
114
+ /** Everything issued from now on is signed with this. */
115
+ readonly key: Uint8Array;
116
+ /** Accepted on verification, never used to sign. Empty outside a rotation. */
117
+ readonly alsoAccept: readonly Uint8Array[];
65
118
  }
119
+ export declare function loadJwtKeys(env?: NodeJS.ProcessEnv): JwtKeys;
66
120
  export declare class ConfigError extends Error {
67
121
  readonly problems: readonly string[];
68
122
  constructor(problems: readonly string[]);
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,CAAA;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;IAEnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IACzC,QAAQ,CAAC,aAAa,EAAE,YAAY,GAAG,QAAQ,CAAA;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IAEzB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IAEjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAE/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IAExB;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAE3B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IAEjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IAEjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;CACjC;AAED,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;gBAExB,QAAQ,EAAE,SAAS,MAAM,EAAE;CAQxC;AAED,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;AA8DvD,wBAAgB,UAAU,CAAC,GAAG,GAAE,GAAiB,GAAG,MAAM,CAoFzD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -14,6 +14,45 @@
14
14
  * obviously right value — and never fine for anything naming a host or
15
15
  * carrying a credential.
16
16
  */
17
+ export function loadJwtKeys(env = process.env) {
18
+ // Development uses a symmetric secret. Production is meant to load an Ed25519
19
+ // key through NACRE_JWT_PRIVATE_KEY_REF; until that lands, refusing is the
20
+ // honest behaviour — a hardcoded fallback here would be a signing key anyone
21
+ // reading the source can forge tokens with.
22
+ const secret = env.NACRE_JWT_SECRET;
23
+ if (secret === undefined || secret.length < 32) {
24
+ throw new ConfigError([
25
+ 'NACRE_JWT_SECRET is not set, or is shorter than 32 bytes. ' +
26
+ 'Asymmetric keys through NACRE_JWT_PRIVATE_KEY_REF are not implemented yet; ' +
27
+ 'until they are, this is required and there is no default.',
28
+ ]);
29
+ }
30
+ const previous = env.NACRE_JWT_SECRET_PREVIOUS;
31
+ if (previous === undefined || previous === '') {
32
+ return { key: new TextEncoder().encode(secret), alsoAccept: [] };
33
+ }
34
+ if (previous.length < 32) {
35
+ throw new ConfigError([
36
+ 'NACRE_JWT_SECRET_PREVIOUS is set but shorter than 32 bytes. It holds the ' +
37
+ 'key being rotated out, so it is held to the same floor as the one ' +
38
+ 'replacing it. Unset it to finish the rotation.',
39
+ ]);
40
+ }
41
+ if (previous === secret) {
42
+ // Refused rather than deduplicated. Setting both to the same value is what
43
+ // an operator does when they mean to rotate and copy the wrong line, and
44
+ // it leaves an installation that believes it has rotated and has not.
45
+ throw new ConfigError([
46
+ 'NACRE_JWT_SECRET_PREVIOUS is the same value as NACRE_JWT_SECRET. That is ' +
47
+ 'not a rotation: it accepts one key twice. Set NACRE_JWT_SECRET to the ' +
48
+ 'new key and NACRE_JWT_SECRET_PREVIOUS to the one it replaces.',
49
+ ]);
50
+ }
51
+ return {
52
+ key: new TextEncoder().encode(secret),
53
+ alsoAccept: [new TextEncoder().encode(previous)],
54
+ };
55
+ }
17
56
  export class ConfigError extends Error {
18
57
  problems;
19
58
  constructor(problems) {
@@ -42,6 +81,23 @@ class Reader {
42
81
  const value = this.env[key]?.trim();
43
82
  return value === undefined || value === '' ? undefined : value;
44
83
  }
84
+ /**
85
+ * An optional secret with a floor on its length.
86
+ *
87
+ * Unset is fine and means the feature is off. Set to something short is not:
88
+ * a short token reads as protection and is a moment's guessing, which is
89
+ * worse than no token because it stops anyone looking again.
90
+ */
91
+ secret(key, minLength) {
92
+ const value = this.optional(key);
93
+ if (value === undefined)
94
+ return undefined;
95
+ if (value.length < minLength) {
96
+ this.problems.push(`${key} must be at least ${minLength} characters, or unset`);
97
+ return undefined;
98
+ }
99
+ return value;
100
+ }
45
101
  /** A default is allowed here: a tunable has an obviously right value. */
46
102
  number(key, fallback, { min = 1, max = Number.MAX_SAFE_INTEGER } = {}) {
47
103
  const raw = this.env[key]?.trim();
@@ -85,11 +141,79 @@ class Reader {
85
141
  return raw;
86
142
  }
87
143
  }
144
+ /** The protocol, or an empty string when the value does not parse at all. */
145
+ function safeProtocol(url) {
146
+ try {
147
+ return new URL(url).protocol;
148
+ }
149
+ catch {
150
+ return '';
151
+ }
152
+ }
153
+ /**
154
+ * The object-storage block, present only when a deployment configured one.
155
+ *
156
+ * Written as a group because it *is* one. Six independent optionals would
157
+ * accept an endpoint with no credential, or a credential with no bucket, and
158
+ * every one of those parses — the failure arrives later, as an ingest that
159
+ * cannot store bytes, on a deployment whose configuration looked accepted.
160
+ *
161
+ * `NACRE_S3_*` spent its whole life in `docs/config.md` and in the `full`
162
+ * Compose profile without `loadConfig` mentioning it once, so a wrong endpoint
163
+ * or a missing key was silent while MinIO sat there talking to nobody. That is
164
+ * the specific failure this shape exists to make impossible.
165
+ */
166
+ function s3From(r, env) {
167
+ const keys = [
168
+ 'NACRE_S3_ENDPOINT',
169
+ 'NACRE_S3_BUCKET',
170
+ 'NACRE_S3_ACCESS_KEY',
171
+ 'NACRE_S3_SECRET_KEY',
172
+ ];
173
+ const present = keys.filter((k) => (env[k] ?? '').trim() !== '');
174
+ if (present.length === 0)
175
+ return undefined;
176
+ if (present.length < keys.length) {
177
+ const missing = keys.filter((k) => !present.includes(k));
178
+ r.problems.push(`object storage is half configured: ${present.join(', ')} set, ` +
179
+ `${missing.join(', ')} missing. Set all four to store document bytes in ` +
180
+ 'object storage, or none to keep them in Postgres. There is no partial ' +
181
+ 'mode — the endpoint without the credential is a deployment that accepts ' +
182
+ 'documents and cannot store them.');
183
+ return undefined;
184
+ }
185
+ // `r.url` only asks whether `new URL` parses, and `minio:9000` does — it
186
+ // reads as the scheme `minio:` with the path `9000`, with an empty host. That
187
+ // would start, and then every request would be built against a URL with
188
+ // nowhere to send it. A missing `http://` is the likeliest thing to be wrong
189
+ // in this variable, so it is the one thing worth checking twice.
190
+ const endpoint = r.url('NACRE_S3_ENDPOINT');
191
+ if (endpoint !== '' && !/^https?:$/.test(safeProtocol(endpoint))) {
192
+ r.problems.push(`NACRE_S3_ENDPOINT must be an http or https URL, and is ${JSON.stringify(endpoint)}. ` +
193
+ 'A bare host and port parses as a URL — the host ends up empty and every ' +
194
+ 'request goes nowhere.');
195
+ }
196
+ return {
197
+ endpoint,
198
+ bucket: r.required('NACRE_S3_BUCKET'),
199
+ // A default is fine here and nowhere else in this block: the region names
200
+ // no host and carries no credential, MinIO ignores it entirely, and it is
201
+ // signed into every request so it has to be *something*.
202
+ region: r.optional('NACRE_S3_REGION') ?? 'us-east-1',
203
+ accessKey: r.required('NACRE_S3_ACCESS_KEY'),
204
+ secretKey: r.required('NACRE_S3_SECRET_KEY'),
205
+ // True by default because the default deployment is self-hosted: MinIO, or
206
+ // an endpoint reached by a name that is not a wildcard DNS entry. AWS
207
+ // proper is the case that has to say so.
208
+ forcePathStyle: r.boolean('NACRE_S3_FORCE_PATH_STYLE', true),
209
+ };
210
+ }
88
211
  export function loadConfig(env = process.env) {
89
212
  const r = new Reader(env);
90
213
  const config = {
91
214
  env: r.oneOf('NACRE_ENV', ['development', 'production'], 'development'),
92
215
  canonicalUrl: r.url('NACRE_CANONICAL_URL'),
216
+ oauthAuthorizationServer: r.url('NACRE_OAUTH_AUTHORIZATION_SERVER', { required: false }),
93
217
  logLevel: r.oneOf('NACRE_LOG_LEVEL', ['debug', 'info', 'warn', 'error'], 'info'),
94
218
  logFormat: r.oneOf('NACRE_LOG_FORMAT', ['json', 'text'], 'json'),
95
219
  pgUrl: r.required('NACRE_PG_URL'),
@@ -106,12 +230,21 @@ export function loadConfig(env = process.env) {
106
230
  // False, and it was true. `minimal` has no reranker by definition — the
107
231
  // profile exists to run on a laptop without a GPU — so a default of true
108
232
  // meant the documented starting profile refused to boot until the operator
109
- // turned off a feature they had not asked for. It is also not implemented
110
- // on the search path yet, so the refusal bought nothing at all.
233
+ // turned off a feature they had not asked for.
111
234
  rerankerEnabled: r.boolean('NACRE_RERANKER_ENABLED', false),
235
+ // The candidate set a cross-encoder reorders. 50 is what
236
+ // docs/architecture.md specifies. The maximum is bounded because every
237
+ // candidate is a row hydrated from Postgres and a text sent to the model:
238
+ // this is the one tunable here that trades latency for quality directly,
239
+ // and there is a value at which a search stops answering in time.
240
+ rerankCandidates: r.number('NACRE_RERANK_CANDIDATES', 50, { min: 1, max: 500 }),
112
241
  jwtIssuer: r.required('NACRE_JWT_ISSUER'),
113
242
  jwtAudience: r.required('NACRE_JWT_AUDIENCE'),
114
243
  accessTokenTtl: r.number('NACRE_ACCESS_TOKEN_TTL', 900, { min: 60, max: 86_400 }),
244
+ // 30 days. The upper bound is a year rather than unbounded: a refresh token
245
+ // is the credential a stolen laptop still holds, and "never expires" is a
246
+ // choice nobody makes deliberately.
247
+ refreshTokenTtl: r.number('NACRE_REFRESH_TOKEN_TTL', 2_592_000, { min: 300, max: 31_536_000 }),
115
248
  aclCacheTtl: r.number('NACRE_ACL_CACHE_TTL', 60, { min: 0, max: 3600 }),
116
249
  aclPropagationSla: r.number('NACRE_ACL_PROPAGATION_SLA', 60, { min: 1, max: 3600 }),
117
250
  gcGrace: r.number('NACRE_GC_GRACE', 3600, { min: 0, max: 2_592_000 }),
@@ -124,9 +257,75 @@ export function loadConfig(env = process.env) {
124
257
  aclTagHashBytes: r.number('NACRE_ACL_TAG_HASH_BYTES', 8, { min: 4, max: 32 }),
125
258
  rateSearchPerMin: r.number('NACRE_RATE_SEARCH_PER_MIN', 60, { min: 1 }),
126
259
  rateIngestPerHour: r.number('NACRE_RATE_INGEST_PER_HOUR', 600, { min: 1 }),
260
+ // Ten attempts per quarter hour, counted per email address. Low enough that
261
+ // guessing is not a strategy, high enough that someone who genuinely cannot
262
+ // remember which password they used is not locked out for the afternoon.
263
+ rateLoginPer15Min: r.number('NACRE_RATE_LOGIN_PER_15MIN', 10, { min: 1, max: 1000 }),
264
+ // The same window, counted per client instead of per address, because the
265
+ // per-address limit does not bound the attack people actually run: one
266
+ // password against ten thousand addresses never repeats a key. Six times
267
+ // looser, because a whole office behind one NAT is one source here and the
268
+ // job of this limit is to stop a directory being ground down, not to make
269
+ // shared egress unusable.
270
+ rateLoginSourcePer15Min: r.number('NACRE_RATE_LOGIN_SOURCE_PER_15MIN', 60, {
271
+ min: 1,
272
+ max: 10_000,
273
+ }),
274
+ // How many proxies sit in front of this process. Zero — the default — means
275
+ // X-Forwarded-For is ignored entirely and the socket address is the client.
276
+ //
277
+ // Neither default is safe, which is why this is configuration rather than a
278
+ // guess. Trusting the header unconditionally keys the limit above on a
279
+ // string the attacker picks, which is worse than having no limit: a fresh
280
+ // value per request costs a Redis round trip and accomplishes nothing.
281
+ // Ignoring it unconditionally means that behind an ingress every request
282
+ // carries the proxy's address, so one bad client rate-limits everybody.
283
+ trustProxy: r.number('NACRE_TRUST_PROXY', 0, { min: 0, max: 8 }),
284
+ // Optional, and off by default. Requiring a token would break every
285
+ // existing scrape config for a product people self-host, and the default is
286
+ // right for the deployment this is designed around — the port is on an
287
+ // internal network. It stops being right the moment somebody puts the API
288
+ // behind a public ingress without carving /metrics out, so the operator who
289
+ // knows they are in that situation has a way to say so.
290
+ //
291
+ // A minimum length, because a two-character scrape token is worse than none
292
+ // — it reads as protection and is a moment's guessing.
293
+ metricsToken: r.secret('NACRE_METRICS_TOKEN', 16),
127
294
  maxDocumentBytes: r.number('NACRE_MAX_DOCUMENT_BYTES', 52_428_800, { min: 1024 }),
128
- auditRetentionDays: r.number('NACRE_AUDIT_RETENTION_DAYS', 400, { min: 1 }),
295
+ // The floor is 30 and it is not a tunable. Retention is now enforced —
296
+ // `prune_audit_events` deletes past this horizon — and the database refuses
297
+ // anything shorter, because below a month "retention" stops meaning
298
+ // retention and becomes a way to make recent events go away, which is the
299
+ // thing the append-only grant exists to prevent. Refused here rather than
300
+ // raised hourly by the worker: a value the deployment can never act on
301
+ // should stop the deployment, not fill a log.
302
+ auditRetentionDays: r.number('NACRE_AUDIT_RETENTION_DAYS', 400, { min: 30 }),
129
303
  auditQueryText: r.boolean('NACRE_AUDIT_QUERY_TEXT', false),
304
+ // How long a superseded collection survives a model migration.
305
+ //
306
+ // It is a rollback window and nothing else. The cheap rollback in
307
+ // `rollback-layer-reindex.md` is "move the pointer back", which works for
308
+ // exactly as long as the collection it points back to still exists; past
309
+ // this horizon that option is gone and a rollback means reindexing.
310
+ //
311
+ // The floor is 1 rather than 0 because a collection deleted the instant the
312
+ // pointer moved would make a migration irreversible at the moment it is
313
+ // most likely to be found wrong. Setting it high costs disk: each retained
314
+ // collection is a full copy of the organization's vectors.
315
+ collectionRetentionDays: r.number('NACRE_COLLECTION_RETENTION_DAYS', 7, { min: 1 }),
316
+ // How long a `source_url` outlives the permission check that minted it.
317
+ //
318
+ // A presigned URL is a bearer capability: whoever holds it fetches that
319
+ // object without a Nacre credential, and a revocation inside the window
320
+ // does not reach it. So the ceiling is a week — SigV4's own maximum, and
321
+ // already far longer than any reason to hand one out — and the floor is a
322
+ // minute, because a link that expires while the client is still following
323
+ // the redirect is a link that never worked.
324
+ presignTtl: r.number('NACRE_PRESIGN_TTL', 900, { min: 60, max: 604_800 }),
325
+ // All of it or none of it — see the cross-field check below. Read here so
326
+ // that a malformed endpoint is a startup problem like any other; whether
327
+ // the *set* is coherent is a question no per-variable check can answer.
328
+ s3: s3From(r, env),
130
329
  };
131
330
  // Cross-field checks. Each one is a combination that parses fine and is
132
331
  // wrong, which is exactly the class a per-variable check cannot catch.
@@ -135,12 +334,51 @@ export function loadConfig(env = process.env) {
135
334
  'Turning reranking on is worth more than any chunking tuning, and it ' +
136
335
  'needs somewhere to send the request — the full profile provides one.');
137
336
  }
337
+ // ─── settings that would silently do nothing ───
338
+ //
339
+ // Eight variables were validated here and read nowhere. Most of those are
340
+ // quality-of-life and are documented as unimplemented; these two are not,
341
+ // because ignoring them changes something an operator is relying on.
342
+ //
343
+ // Refusing at startup rather than warning: an operator who sets these has
344
+ // made a decision about isolation or about collision probability, and a
345
+ // process that starts anyway has silently overruled them. `docs/config.md`
346
+ // already says a silent default is how a deployment talks to nothing and
347
+ // reports success — this is the same failure with a value supplied.
348
+ if (config.vectorTenancy !== 'collection') {
349
+ r.problems.push('NACRE_VECTOR_TENANCY=shared is not implemented. Every collection is named ' +
350
+ 'per organization (org_{slug}) and there is no code path that shares one, ' +
351
+ 'so accepting this would give you a single-collection deployment that ' +
352
+ 'believes it is isolated. Use `collection`, which is the default.');
353
+ }
354
+ if (config.aclTagHashBytes !== 8) {
355
+ r.problems.push('NACRE_ACL_TAG_HASH_BYTES is not implemented: the tag width is fixed at 8 ' +
356
+ 'bytes in the code that writes and matches tags. Setting it changes the ' +
357
+ 'collision probability you think you have and nothing else. Leave it at 8.');
358
+ }
359
+ if (config.refreshTokenTtl <= config.accessTokenTtl) {
360
+ r.problems.push('NACRE_REFRESH_TOKEN_TTL is not longer than NACRE_ACCESS_TOKEN_TTL. A refresh ' +
361
+ 'token that expires no later than the access token it renews cannot renew ' +
362
+ 'anything, so every session would end at the first refresh.');
363
+ }
138
364
  if (config.aclCacheTtl > config.aclPropagationSla) {
139
- // The cache would still be serving a revoked grant after the SLA has
140
- // passed, and nacre_acl_propagation_lag_seconds would report compliance.
365
+ // Kept, and the reason it is kept has changed.
366
+ //
367
+ // It used to say a longer TTL would serve a revoked grant past the SLA.
368
+ // That is not true of the cache that now runs: the key carries
369
+ // `organizations.groups_version`, which triggers bump on every change to
370
+ // groups, group_members and grants, so a revoked grant is never served —
371
+ // the next request composes a different key. The TTL bounds memory.
372
+ //
373
+ // What it still catches is an operator who believes otherwise. Setting this
374
+ // above the SLA is what someone does when they have read it as "how long a
375
+ // stale permission may live", and a deployment configured on that belief
376
+ // has a misunderstanding worth interrupting at boot rather than a setting
377
+ // worth honouring.
141
378
  r.problems.push(`NACRE_ACL_CACHE_TTL (${config.aclCacheTtl}) is longer than ` +
142
- `NACRE_ACL_PROPAGATION_SLA (${config.aclPropagationSla}); a revoked grant ` +
143
- 'would still be served after the SLA it promises.');
379
+ `NACRE_ACL_PROPAGATION_SLA (${config.aclPropagationSla}). The cache is keyed ` +
380
+ 'on the permission epoch, so this does not delay a revocation — but a value ' +
381
+ 'above the SLA usually means it was read as though it did.');
144
382
  }
145
383
  if (config.env === 'production' && config.canonicalUrl.startsWith('http://')) {
146
384
  // The canonical URL is the OAuth issuer and goes into every token ever
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"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"}
@@ -34,5 +34,44 @@ export interface WithOrgOptions {
34
34
  */
35
35
  readonly role?: string;
36
36
  }
37
+ /**
38
+ * Run a lookup that resolves a credential, which cannot be scoped to an
39
+ * organization because the credential is what says which organization it is.
40
+ *
41
+ * `app.authenticating` opens a second row-level security policy on
42
+ * `service_accounts` for the length of the transaction — see migration 0008.
43
+ * Without it the query raises `unrecognized configuration parameter` on any
44
+ * connection that is subject to row-level security, which is every connection
45
+ * a deployment following `docs/config.md` will make.
46
+ *
47
+ * **This is the one path in the system that reads across tenants, and it must
48
+ * stay the only one.** Two things keep it narrow, and both are load-bearing:
49
+ * the flag is `SET LOCAL`, so it cannot outlive the transaction or come back
50
+ * on a pooled connection, and the policy it opens is `FOR SELECT`, so this
51
+ * cannot write a row into an organization it has not identified yet.
52
+ *
53
+ * Read the credential and nothing else. Anything joined from tenant data here
54
+ * is a cross-tenant read with the guard rail switched off.
55
+ */
56
+ export declare function whileAuthenticating<T>(pool: Pool, fn: (client: PoolClient) => Promise<T>, options?: WithOrgOptions): Promise<T>;
57
+ /**
58
+ * Run a query that legitimately spans every tenant, under the role the schema
59
+ * gives BYPASSRLS.
60
+ *
61
+ * The worker's queue is the only thing that needs this: claiming the next
62
+ * document to index means looking at all of them, which is what a queue is.
63
+ * `0001_init.sql` has said "background worker jobs run under a separate role
64
+ * with BYPASSRLS" since the beginning and no migration created that role until
65
+ * 0008, so these queries ran with no organization set and raised
66
+ * `unrecognized configuration parameter` on any connection subject to
67
+ * row-level security — every connection a deployment following
68
+ * `docs/config.md` makes. Indexing stopped entirely, and the Compose stack
69
+ * never showed it because `POSTGRES_USER` connects as a superuser.
70
+ *
71
+ * **This turns the second line of defence off.** Every query run inside it
72
+ * names `org_id` explicitly, because with row-level security bypassed that is
73
+ * the only line left.
74
+ */
75
+ export declare function acrossOrganizations<T>(pool: Pool, fn: (client: PoolClient) => Promise<T>, role?: string): Promise<T>;
37
76
  export declare function withOrg<T>(pool: Pool, orgId: string, fn: (client: PoolClient) => Promise<T>, options?: WithOrgOptions): Promise<T>;
38
77
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,IAAI,CAAA;AAE1C,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAEnD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAsB,OAAO,CAAC,CAAC,EAC7B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC,CA0BZ"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,IAAI,CAAA;AAE1C,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAEnD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,IAAI,SAAiB,GACpB,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAED,wBAAsB,OAAO,CAAC,CAAC,EAC7B,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,EACtC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC,CA0BZ"}
package/dist/db/client.js CHANGED
@@ -2,6 +2,88 @@ import { Pool } from 'pg';
2
2
  export function createPool(options) {
3
3
  return new Pool({ connectionString: options.connectionString, max: options.max ?? 20 });
4
4
  }
5
+ /**
6
+ * Run a lookup that resolves a credential, which cannot be scoped to an
7
+ * organization because the credential is what says which organization it is.
8
+ *
9
+ * `app.authenticating` opens a second row-level security policy on
10
+ * `service_accounts` for the length of the transaction — see migration 0008.
11
+ * Without it the query raises `unrecognized configuration parameter` on any
12
+ * connection that is subject to row-level security, which is every connection
13
+ * a deployment following `docs/config.md` will make.
14
+ *
15
+ * **This is the one path in the system that reads across tenants, and it must
16
+ * stay the only one.** Two things keep it narrow, and both are load-bearing:
17
+ * the flag is `SET LOCAL`, so it cannot outlive the transaction or come back
18
+ * on a pooled connection, and the policy it opens is `FOR SELECT`, so this
19
+ * cannot write a row into an organization it has not identified yet.
20
+ *
21
+ * Read the credential and nothing else. Anything joined from tenant data here
22
+ * is a cross-tenant read with the guard rail switched off.
23
+ */
24
+ export async function whileAuthenticating(pool, fn, options = {}) {
25
+ const client = await pool.connect();
26
+ try {
27
+ await client.query('BEGIN');
28
+ if (options.role !== undefined) {
29
+ if (!/^[a-z_][a-z0-9_]*$/i.test(options.role)) {
30
+ throw new Error(`refusing to set an unrecognizable role name: ${options.role}`);
31
+ }
32
+ await client.query(`SET LOCAL ROLE ${options.role}`);
33
+ }
34
+ // `true` is the local flag: it goes away with the transaction, so a pooled
35
+ // connection cannot hand it to the next caller.
36
+ await client.query('SELECT set_config($1, $2, true)', ['app.authenticating', 'on']);
37
+ const result = await fn(client);
38
+ await client.query('COMMIT');
39
+ return result;
40
+ }
41
+ catch (cause) {
42
+ await client.query('ROLLBACK').catch(() => { });
43
+ throw cause;
44
+ }
45
+ finally {
46
+ client.release();
47
+ }
48
+ }
49
+ /**
50
+ * Run a query that legitimately spans every tenant, under the role the schema
51
+ * gives BYPASSRLS.
52
+ *
53
+ * The worker's queue is the only thing that needs this: claiming the next
54
+ * document to index means looking at all of them, which is what a queue is.
55
+ * `0001_init.sql` has said "background worker jobs run under a separate role
56
+ * with BYPASSRLS" since the beginning and no migration created that role until
57
+ * 0008, so these queries ran with no organization set and raised
58
+ * `unrecognized configuration parameter` on any connection subject to
59
+ * row-level security — every connection a deployment following
60
+ * `docs/config.md` makes. Indexing stopped entirely, and the Compose stack
61
+ * never showed it because `POSTGRES_USER` connects as a superuser.
62
+ *
63
+ * **This turns the second line of defence off.** Every query run inside it
64
+ * names `org_id` explicitly, because with row-level security bypassed that is
65
+ * the only line left.
66
+ */
67
+ export async function acrossOrganizations(pool, fn, role = 'nacre_worker') {
68
+ const client = await pool.connect();
69
+ try {
70
+ await client.query('BEGIN');
71
+ if (!/^[a-z_][a-z0-9_]*$/i.test(role)) {
72
+ throw new Error(`refusing to set an unrecognizable role name: ${role}`);
73
+ }
74
+ await client.query(`SET LOCAL ROLE ${role}`);
75
+ const result = await fn(client);
76
+ await client.query('COMMIT');
77
+ return result;
78
+ }
79
+ catch (cause) {
80
+ await client.query('ROLLBACK').catch(() => { });
81
+ throw cause;
82
+ }
83
+ finally {
84
+ client.release();
85
+ }
86
+ }
5
87
  export async function withOrg(pool, orgId, fn, options = {}) {
6
88
  const client = await pool.connect();
7
89
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../db/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,IAAI,CAAA;AAO1C,MAAM,UAAU,UAAU,CAAC,OAAkB;IAC3C,OAAO,IAAI,IAAI,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAA;AACzF,CAAC;AAiCD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAU,EACV,KAAa,EACb,EAAsC,EACtC,UAA0B,EAAE;IAE5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC3B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,uEAAuE;YACvE,+DAA+D;YAC/D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9C,MAAM,IAAI,KAAK,CAAC,gDAAgD,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;YACjF,CAAC;YACD,MAAM,MAAM,CAAC,KAAK,CAAC,kBAAkB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QACtD,CAAC;QACD,MAAM,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAA;QACjF,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,CAAA;QAC/B,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC5B,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACxC,2EAA2E;YAC3E,0EAA0E;YAC1E,iEAAiE;QACnE,CAAC,CAAC,CAAA;QACF,MAAM,KAAK,CAAA;IACb,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAA;IAClB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../db/client.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../db/migrate.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAuB,GAAG,SAAS,SAAS,EAAE,CAyBjF;AAeD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,OAAO,CAC3B,gBAAgB,EAAE,MAAM,EACxB,UAAU,GAAE,SAAS,SAAS,EAAqB,GAClD,OAAO,CAAC,aAAa,CAAC,CAmDxB"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../db/migrate.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAuB,GAAG,SAAS,SAAS,EAAE,CAyBjF;AAeD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,OAAO,CAC3B,gBAAgB,EAAE,MAAM,EACxB,UAAU,GAAE,SAAS,SAAS,EAAqB,GAClD,OAAO,CAAC,aAAa,CAAC,CA4FxB"}