@nacre.work/api 0.5.2 → 0.5.5

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/dist/main.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { configureLogging, collectDatabaseGauges, createMetrics, createPool, loadConfig, loadedExtensions, loadModules, logger, loadJwtKeys, keyFingerprint, protectedResourceMetadata, Redis, RedisCache, Registry, S3, VectorStore, pendingMigrations, withOrg, ConfigError, installGuards, onListenError, } from '@nacre.work/core';
2
2
  import { HttpEmbedder, NacreIngest, NacreSearchService, PostgresAudit, PostgresAuditReader, PostgresDocuments, PostgresGrants, PostgresJobs, PostgresLayers, PostgresReferenceQueries, PostgresReindex, PostgresWorkspaces, } from './adapters.js';
3
+ import { SignJWT } from 'jose';
3
4
  import { Idempotency } from './idempotency.js';
4
5
  import { Login } from './login.js';
6
+ import { PostgresOAuthAuthorizations, PostgresOAuthClients, PostgresOAuthConsents, PostgresOAuthRefreshTokens, } from './oauth-store.js';
5
7
  import { rerankerFor } from './rerank.js';
6
8
  import { RateLimiter } from './limits.js';
7
9
  import { PostgresGroups, PostgresUsers } from './principals.js';
@@ -188,9 +190,15 @@ async function main() {
188
190
  metrics: registry,
189
191
  resourceMetadata: protectedResourceMetadata({
190
192
  canonicalUrl: config.canonicalUrl,
191
- ...(config.oauthAuthorizationServer === ''
192
- ? {}
193
- : { authorizationServer: config.oauthAuthorizationServer }),
193
+ // An operator's identity provider wins. Failing that, **this
194
+ // installation** — which reverses the position this field held, and the
195
+ // reversal is the point rather than a slip: it was empty because pointing
196
+ // a client at a token endpoint that did not exist would have been a dead
197
+ // end one redirect further along, and the endpoint exists now. The
198
+ // argument was right; what it described changed.
199
+ authorizationServer: config.oauthAuthorizationServer === ''
200
+ ? config.canonicalUrl.replace(/\/+$/, '')
201
+ : config.oauthAuthorizationServer,
194
202
  }),
195
203
  // Only when there is a public half. A deployment on NACRE_JWT_SECRET serves
196
204
  // 404 here, because a shared secret has nothing publishable and an endpoint
@@ -250,6 +258,63 @@ async function main() {
250
258
  serviceAccounts: new PostgresServiceAccounts(pool, APP_ROLE),
251
259
  users: new PostgresUsers(pool, APP_ROLE),
252
260
  groups: new PostgresGroups(pool, APP_ROLE),
261
+ /**
262
+ * The authorization server.
263
+ *
264
+ * On by default, because the alternative for anyone connecting an agent is
265
+ * "make a service account by hand, copy its key, paste it into a config
266
+ * file" — which is the gap this closes. A deployment that would rather use
267
+ * its own identity provider names it in
268
+ * `NACRE_OAUTH_AUTHORIZATION_SERVER`, and then the discovery document
269
+ * points there and this flow is simply not the one clients take.
270
+ */
271
+ oauth: {
272
+ issuer: config.canonicalUrl.replace(/\/+$/, ''),
273
+ // The admin UI's consent screen. Same origin as the API in every
274
+ // deployment that puts an ingress in front; the Compose stack publishes
275
+ // the admin bundle separately, which is why this is a variable and not a
276
+ // path appended to the issuer.
277
+ consentUrl: config.consentUrl,
278
+ clients: new PostgresOAuthClients(pool, APP_ROLE),
279
+ authorizations: new PostgresOAuthAuthorizations(pool, APP_ROLE),
280
+ consents: new PostgresOAuthConsents(pool, APP_ROLE),
281
+ refreshTokens: new PostgresOAuthRefreshTokens(pool, APP_ROLE),
282
+ // The same lifetimes a person's own session uses. An application's
283
+ // connection is not a different kind of thing from a browser session —
284
+ // both are "this holder keeps working until somebody ends it" — so
285
+ // inventing a second pair of knobs would be two answers to one question.
286
+ refreshTtlSeconds: config.refreshTokenTtl,
287
+ accessTtlSeconds: config.accessTokenTtl,
288
+ /**
289
+ * A token for the **agent**, never for the person who approved it.
290
+ *
291
+ * `principal_type: 'service_account'` and `sub` is the account — the same
292
+ * claims a service account key resolves to, so everything downstream
293
+ * treats this exactly as it treats one and there is no second notion of
294
+ * what an agent is. `role` is `member` because a service account has no
295
+ * organization-wide role: everything it reaches, it reaches by grant.
296
+ */
297
+ mint: async (approved) => {
298
+ const ttl = config.accessTokenTtl;
299
+ const now = Math.floor(Date.now() / 1000);
300
+ const accessToken = await new SignJWT({
301
+ org: approved.orgId,
302
+ principal_type: 'service_account',
303
+ role: 'member',
304
+ })
305
+ .setProtectedHeader({
306
+ alg: jwt.algorithm,
307
+ ...(jwt.keyId === undefined ? {} : { kid: jwt.keyId }),
308
+ })
309
+ .setSubject(approved.serviceAccountId)
310
+ .setIssuer(config.jwtIssuer)
311
+ .setAudience(config.jwtAudience)
312
+ .setIssuedAt(now)
313
+ .setExpirationTime(now + ttl)
314
+ .sign(jwt.signing);
315
+ return { accessToken, expiresIn: ttl };
316
+ },
317
+ },
253
318
  });
254
319
  const port = Number(process.env.PORT ?? 8080);
255
320
  server.listen(port, () => {
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,MAAM,EACN,WAAW,EACX,cAAc,EACd,yBAAyB,EACzB,KAAK,EACL,UAAU,EACV,QAAQ,EACR,EAAE,EACF,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,WAAW,EACX,aAAa,EACb,aAAa,GACd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,kBAAkB,GACnB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,WAAW,EAAmC,MAAM,aAAa,CAAA;AAC1E,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/D,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC;;;;;;GAMG;AAEH,MAAM,QAAQ,GAAG,WAAW,CAAA;AAE5B,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;IAE3B,+EAA+E;IAC/E,+EAA+E;IAC/E,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;IAEtE,8EAA8E;IAC9E,+EAA+E;IAC/E,8EAA8E;IAC9E,8EAA8E;IAC9E,MAAM,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEjC,MAAM,GAAG,GAAG,WAAW,EAAE,CAAA;IAEzB,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,gBAAgB,EAAE,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;IAClF,MAAM,OAAO,GAAG,IAAI,WAAW,CAC7B,MAAM,CAAC,YAAY,KAAK,SAAS;QAC/B,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE;QAC3B,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,CAC3D,CAAA;IACD,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAEvE,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAA;IAC/B,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEhE,2EAA2E;IAC3E,6EAA6E;IAC7E,kEAAkE;IAClE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEjD,wEAAwE;IACxE,8EAA8E;IAC9E,yEAAyE;IACzE,2EAA2E;IAC3E,iBAAiB;IACjB,EAAE;IACF,8EAA8E;IAC9E,wEAAwE;IACxE,6EAA6E;IAC7E,gDAAgD;IAChD,MAAM,eAAe,GAAG,EAAE,KAAK,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,CAAA;IAGxF,MAAM,aAAa,GAAkC;QACnD,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,gBAAgB,EAAE,aAAa,EAAE,EAAE,EAAE;QAC7D,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,iBAAiB,EAAE,aAAa,EAAE,IAAI,EAAE;QAChE,4EAA4E;QAC5E,yEAAyE;QACzE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,iBAAiB,EAAE,aAAa,EAAE,GAAG,EAAE;QAC9D,uEAAuE;QACvE,wEAAwE;QACxE,4DAA4D;QAC5D,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,uBAAuB,EAAE,aAAa,EAAE,GAAG,EAAE;KAC5E,CAAA;IAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC;QAC7B,KAAK;QACL,QAAQ,EAAE,aAAa;QACvB,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC9B,wEAAwE;YACxE,qEAAqE;YACrE,qEAAqE;YACrE,6CAA6C;YAC7C,EAAE;YACF,yEAAyE;YACzE,kEAAkE;YAClE,mEAAmE;YACnE,wCAAwC;YACxC,OAAO,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;YAC9C,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE,EAAE,QAAQ;gBACnE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QAC3C,CAAC;KACF,CAAC,CAAA;IAEF,oEAAoE;IACpE,yEAAyE;IACzE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAEpC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;QAClC,KAAK;QACL,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YACpB,MAAM,CAAC,IAAI,CAAC,2DAA2D,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QAClH,CAAC;KACF,CAAC,CAAA;IAEF,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI;QACJ,0EAA0E;QAC1E,0EAA0E;QAC1E,OAAO;QACP,GAAG,EAAE,GAAG,CAAC,OAAO;QAChB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC;QACxD,MAAM,EAAE,MAAM,CAAC,SAAS;QACxB,QAAQ,EAAE,MAAM,CAAC,WAAW;QAC5B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,IAAI,EAAE,QAAQ;KACf,CAAC,CAAA;IAEF,oDAAoD;IACpD,EAAE;IACF,6EAA6E;IAC7E,qEAAqE;IACrE,+EAA+E;IAC/E,6EAA6E;IAC7E,gEAAgE;IAChE,EAAE;IACF,4EAA4E;IAC5E,6EAA6E;IAC7E,sEAAsE;IACtE,aAAa;IACb,MAAM,KAAK,GAAG,KAAK,IAAsC,EAAE;QACzD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAClE,OAAO,CAAC,IAAI,EAAE,sCAAsC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;gBAChE,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;gBACzB,OAAO,IAAI,CAAA;YACb,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YACzC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YAClC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YAC/B,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YACvF,6DAA6D;YAC7D,EAAE;YACF,wEAAwE;YACxE,uEAAuE;YACvE,sEAAsE;YACtE,yEAAyE;YACzE,mEAAmE;YACnE,sDAAsD;YACtD,EAAE;YACF,kEAAkE;YAClE,8DAA8D;YAC9D,EAAE;YACF,qEAAqE;YACrE,wEAAwE;YACxE,mEAAmE;YACnE,qEAAqE;YACrE,uEAAuE;YACvE,iEAAiE;YACjE,EAAE;YACF,kEAAkE;YAClE,uEAAuE;YACvE,iCAAiC;YACjC,iBAAiB,CAAC,IAAI,CAAC;iBACpB,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,IAAI,CAAA;gBACrC,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;oBACzC,OAAO,EAAE,OAAO,CAAC,MAAM;oBACvB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;iBACjB,CAAC,CAAA;gBACF,OAAO,KAAK,CAAA;YACd,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBACxB,mEAAmE;gBACnE,qEAAqE;gBACrE,uCAAuC;gBACvC,MAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;gBAC5E,OAAO,KAAK,CAAA;YACd,CAAC,CAAC;SACL,CAAC,CAAA;QACF,OAAO;YACL,QAAQ;YACR,MAAM;YACN,KAAK,EAAE,OAAO;YACd,MAAM;YACN,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;SAC5C,CAAA;IACH,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,SAAS,CAAC;QACvB,MAAM,EAAE;YACN,GAAG,EAAE,GAAG,CAAC,YAAY;YACrB,yEAAyE;YACzE,kEAAkE;YAClE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,CAAC;YACtE,UAAU,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;YAC3B,MAAM,EAAE,MAAM,CAAC,SAAS;YACxB,QAAQ,EAAE,MAAM,CAAC,WAAW;YAC5B,WAAW,EAAE,IAAI,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC;SACrD;QACD,OAAO,EAAE,QAAQ;QACjB,gBAAgB,EAAE,yBAAyB,CAAC;YAC1C,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,GAAG,CAAC,MAAM,CAAC,wBAAwB,KAAK,EAAE;gBACxC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,wBAAwB,EAAE,CAAC;SAC9D,CAAC;QACF,4EAA4E;QAC5E,4EAA4E;QAC5E,wEAAwE;QACxE,UAAU;QACV,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;QACrD,0EAA0E;QAC1E,uEAAuE;QACvE,iCAAiC;QACjC,OAAO,EAAE,OAAO;QAChB,KAAK;QACL,YAAY,EAAE,MAAM,CAAC,gBAAgB;QACrC,qEAAqE;QACrE,mEAAmE;QACnE,aAAa,EAAE,OAAO,KAAK,SAAS;QACpC,MAAM;QACN,aAAa;QACb,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;QACnF,WAAW;QACX,KAAK;QACL,WAAW,EAAE,IAAI,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC;QACrE,OAAO,EAAE,IAAI,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC;QACtE,gBAAgB,EAAE,IAAI,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC;QAC/E,SAAS,EAAE,IAAI,iBAAiB,CAC9B,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,eAAe,EACf,OAAO,KAAK,SAAS;YACnB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CACtE;QACD,MAAM,EAAE,IAAI,kBAAkB,CAAC;YAC7B,eAAe;YACf,IAAI;YACJ,OAAO;YACP,WAAW,EAAE,YAAY,CAAC,IAAI,EAAE;YAChC,IAAI,EAAE,QAAQ;YACd,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC/C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE;gBACxB,qEAAqE;gBACrE,qEAAqE;gBACrE,sEAAsE;gBACtE,mEAAmE;gBACnE,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;YACtG,CAAC;SACF,CAAC;QACF,MAAM,EAAE,IAAI,WAAW,CAAC;YACtB,IAAI;YACJ,eAAe;YACf,SAAS,EAAE,OAAO;YAClB,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,IAAI,EAAE,QAAQ;SACf,CAAC;QACF,KAAK,EAAE,IAAI,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC;QACxC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,IAAI,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC;QACvD,MAAM,EAAE,IAAI,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC;QACpE,UAAU,EAAE,IAAI,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC;QACnE,MAAM,EAAE,IAAI,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,eAAe,CAAC;QAC3D,eAAe,EAAE,IAAI,uBAAuB,CAAC,IAAI,EAAE,QAAQ,CAAC;QAC5D,KAAK,EAAE,IAAI,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC;QACxC,MAAM,EAAE,IAAI,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC;KAC3C,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAA;IAC7C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;QACvB,4EAA4E;QAC5E,wEAAwE;QACxE,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,IAAI;YAC/B,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,MAAM,EAAE,MAAM,CAAC,SAAS;YACxB,OAAO,EAAE,GAAG,CAAC,SAAS;YACtB,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC;YACzC,uEAAuE;YACvE,kEAAkE;YAClE,mCAAmC;YACnC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;gBAC7B,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7D,sEAAsE;YACtE,qEAAqE;YACrE,qEAAqE;YACrE,0CAA0C;YAC1C,UAAU,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAElC,aAAa,CAAC;QACZ,OAAO,EAAE,KAAK;QACd,wEAAwE;QACxE,wEAAwE;QACxE,2EAA2E;QAC3E,uEAAuE;QACvE,4EAA4E;QAC5E,uEAAuE;QACvE,QAAQ,EAAE,KAAK,IAAI,EAAE;YACnB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YACnE,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,MAAM,IAAI,CAAC,GAAG,EAAE,CAAA;QAClB,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Storage for the authorization server.
3
+ *
4
+ * Two tables and two shapes. `oauth_clients` holds no tenant data — a client
5
+ * registers before anybody has signed in, and a `client_id` permits nothing —
6
+ * so it is read and written outside `withOrg`, and that is stated here rather
7
+ * than left for a reader to wonder about. `oauth_authorizations` is tenant data
8
+ * the moment it exists, because it names a service account, and every statement
9
+ * against it goes through `withOrg`.
10
+ */
11
+ import type { Pool } from 'pg';
12
+ import type { AuthContext } from './auth.js';
13
+ export interface RegisteredClient {
14
+ readonly clientId: string;
15
+ readonly clientName: string;
16
+ readonly redirectUris: readonly string[];
17
+ }
18
+ /** A standing connection: this application, acting as this agent. */
19
+ export interface Consent {
20
+ readonly id: string;
21
+ readonly clientId: string;
22
+ readonly clientName: string;
23
+ readonly serviceAccountId: string;
24
+ readonly serviceAccountName: string;
25
+ readonly approvedBy: string;
26
+ readonly createdAt: string;
27
+ readonly lastRefreshedAt: string | null;
28
+ readonly revokedAt: string | null;
29
+ }
30
+ /** A consent that has been given and not yet exchanged. */
31
+ export interface PendingAuthorization {
32
+ readonly orgId: string;
33
+ /** The standing connection this code belongs to. */
34
+ readonly consentId?: string;
35
+ readonly serviceAccountId: string;
36
+ readonly clientId: string;
37
+ readonly redirectUri: string;
38
+ readonly codeChallenge: string;
39
+ readonly resource?: string;
40
+ }
41
+ export interface OAuthClients {
42
+ register(name: string, redirectUris: readonly string[], clientId: string): Promise<RegisteredClient>;
43
+ find(clientId: string): Promise<RegisteredClient | undefined>;
44
+ }
45
+ export interface OAuthConsents {
46
+ /**
47
+ * The connection, created or found.
48
+ *
49
+ * Approving twice is the same connection rather than a second one: a screen
50
+ * full of duplicates is one where ending a connection leaves the others
51
+ * working.
52
+ */
53
+ record(auth: AuthContext, clientId: string, serviceAccountId: string): Promise<string>;
54
+ /**
55
+ * Every connection this caller may see.
56
+ *
57
+ * An `org_admin` sees the organization's; everybody else sees the ones they
58
+ * approved. That is not a permission gradient invented here — an agent is the
59
+ * organization's, and somebody has to be able to end a connection whose
60
+ * approver has left.
61
+ */
62
+ list(auth: AuthContext): Promise<readonly Consent[]>;
63
+ /**
64
+ * End it. Returns false when there is nothing of theirs by that id, which is
65
+ * the same answer as "no such connection" — invariant 4.
66
+ */
67
+ revoke(auth: AuthContext, id: string): Promise<boolean>;
68
+ }
69
+ export interface OAuthRefreshTokens {
70
+ /** Issue one against a connection, in the family a rotation continues. */
71
+ issue(orgId: string, consentId: string, token: string, family: string | undefined, expiresAt: Date): Promise<string>;
72
+ /**
73
+ * Spend one and say what it was for, or refuse.
74
+ *
75
+ * Refuses an expired token, a revoked connection, and — loudly — a **replay**:
76
+ * a token already spent means two holders have it and there is no way to tell
77
+ * which is genuine, so the whole family is ended rather than the one token.
78
+ */
79
+ rotate(token: string): Promise<{
80
+ orgId: string;
81
+ consentId: string;
82
+ serviceAccountId: string;
83
+ family: string;
84
+ } | undefined>;
85
+ }
86
+ export interface OAuthAuthorizations {
87
+ /** Records a consent and returns nothing: the code is the caller's to hand back. */
88
+ approve(auth: AuthContext, input: PendingAuthorization & {
89
+ code: string;
90
+ expiresAt: Date;
91
+ }): Promise<void>;
92
+ /**
93
+ * Exchange, once.
94
+ *
95
+ * Consumption and lookup are one statement on purpose. Two — read, then mark
96
+ * — is a window in which the same code is exchanged twice, and an
97
+ * authorization code redeemed twice is the definition of a replay.
98
+ */
99
+ redeem(code: string): Promise<PendingAuthorization | undefined>;
100
+ }
101
+ export declare class PostgresOAuthClients implements OAuthClients {
102
+ private readonly pool;
103
+ private readonly role?;
104
+ constructor(pool: Pool, role?: string | undefined);
105
+ register(name: string, redirectUris: readonly string[], clientId: string): Promise<RegisteredClient>;
106
+ find(clientId: string): Promise<RegisteredClient | undefined>;
107
+ }
108
+ export declare class PostgresOAuthAuthorizations implements OAuthAuthorizations {
109
+ private readonly pool;
110
+ private readonly role?;
111
+ constructor(pool: Pool, role?: string | undefined);
112
+ approve(auth: AuthContext, input: PendingAuthorization & {
113
+ code: string;
114
+ expiresAt: Date;
115
+ }): Promise<void>;
116
+ redeem(code: string): Promise<PendingAuthorization | undefined>;
117
+ }
118
+ export declare class PostgresOAuthConsents implements OAuthConsents {
119
+ private readonly pool;
120
+ private readonly role?;
121
+ constructor(pool: Pool, role?: string | undefined);
122
+ record(auth: AuthContext, clientId: string, serviceAccountId: string): Promise<string>;
123
+ list(auth: AuthContext): Promise<readonly Consent[]>;
124
+ revoke(auth: AuthContext, id: string): Promise<boolean>;
125
+ }
126
+ export declare class PostgresOAuthRefreshTokens implements OAuthRefreshTokens {
127
+ private readonly pool;
128
+ private readonly role?;
129
+ constructor(pool: Pool, role?: string | undefined);
130
+ issue(orgId: string, consentId: string, token: string, family: string | undefined, expiresAt: Date): Promise<string>;
131
+ rotate(token: string): Promise<{
132
+ orgId: string;
133
+ consentId: string;
134
+ serviceAccountId: string;
135
+ family: string;
136
+ } | undefined>;
137
+ }
138
+ //# sourceMappingURL=oauth-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-store.d.ts","sourceRoot":"","sources":["../src/oauth-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Storage for the authorization server.
3
+ *
4
+ * Two tables and two shapes. `oauth_clients` holds no tenant data — a client
5
+ * registers before anybody has signed in, and a `client_id` permits nothing —
6
+ * so it is read and written outside `withOrg`, and that is stated here rather
7
+ * than left for a reader to wonder about. `oauth_authorizations` is tenant data
8
+ * the moment it exists, because it names a service account, and every statement
9
+ * against it goes through `withOrg`.
10
+ */
11
+ import { hashCode, whileAuthenticating, withOrg } from '@nacre.work/core';
12
+ export class PostgresOAuthClients {
13
+ pool;
14
+ role;
15
+ constructor(pool, role) {
16
+ this.pool = pool;
17
+ this.role = role;
18
+ }
19
+ async register(name, redirectUris, clientId) {
20
+ // Outside `withOrg`, and the mechanism that permits it is
21
+ // `whileAuthenticating` — the same one credential resolution uses, for the
22
+ // same reason: there is no organization yet, because nobody has signed in.
23
+ // A client row is not tenant data and grants nothing.
24
+ return whileAuthenticating(this.pool, async (client) => {
25
+ await client.query(`INSERT INTO oauth_clients (client_id, client_name, redirect_uris) VALUES ($1, $2, $3)`, [clientId, name, [...redirectUris]]);
26
+ return { clientId, clientName: name, redirectUris };
27
+ }, this.role === undefined ? {} : { role: this.role });
28
+ }
29
+ async find(clientId) {
30
+ return whileAuthenticating(this.pool, async (client) => {
31
+ const { rows } = await client.query('SELECT client_id, client_name, redirect_uris FROM oauth_clients WHERE client_id = $1', [clientId]);
32
+ const row = rows[0];
33
+ if (row === undefined)
34
+ return undefined;
35
+ return { clientId: row.client_id, clientName: row.client_name, redirectUris: row.redirect_uris };
36
+ }, this.role === undefined ? {} : { role: this.role });
37
+ }
38
+ }
39
+ export class PostgresOAuthAuthorizations {
40
+ pool;
41
+ role;
42
+ constructor(pool, role) {
43
+ this.pool = pool;
44
+ this.role = role;
45
+ }
46
+ async approve(auth, input) {
47
+ await withOrg(this.pool, auth.orgId, async (client) => {
48
+ await client.query(`INSERT INTO oauth_authorizations
49
+ (org_id, client_id, service_account_id, approved_by, code_hash,
50
+ code_challenge, redirect_uri, resource, expires_at, consent_id)
51
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, [
52
+ auth.orgId,
53
+ input.clientId,
54
+ input.serviceAccountId,
55
+ auth.principal.id,
56
+ hashCode(input.code),
57
+ input.codeChallenge,
58
+ input.redirectUri,
59
+ input.resource ?? null,
60
+ input.expiresAt,
61
+ input.consentId ?? null,
62
+ ]);
63
+ }, this.role === undefined ? {} : { role: this.role });
64
+ }
65
+ async redeem(code) {
66
+ // Two statements, and the split is the point rather than a compromise.
67
+ //
68
+ // The token endpoint is handed a code and nothing else, so it cannot scope
69
+ // the lookup before it has done it — the same position credential
70
+ // resolution is in, and it uses the same mechanism: the
71
+ // `authenticating_lookup` policy from 0023, which is **SELECT only**. That
72
+ // restriction is migration 0008's property and this must not end it: an
73
+ // UPDATE under `whileAuthenticating` would be a cross-tenant write, and it
74
+ // would also raise, because no organization is set for the org-scoped
75
+ // policy to read.
76
+ const found = await whileAuthenticating(this.pool, async (client) => {
77
+ const { rows } = await client.query(`SELECT org_id FROM oauth_authorizations
78
+ WHERE code_hash = $1 AND consumed_at IS NULL AND expires_at > now()`, [hashCode(code)]);
79
+ return rows[0]?.org_id;
80
+ }, this.role === undefined ? {} : { role: this.role });
81
+ if (found === undefined)
82
+ return undefined;
83
+ // The decision, under the organization the lookup named. `consumed_at IS
84
+ // NULL` inside the UPDATE is what refuses a replay: two exchanges race for
85
+ // one row and exactly one of them gets it back. The SELECT above decides
86
+ // nothing — it only says which tenant to ask.
87
+ return withOrg(this.pool, found, async (client) => {
88
+ const { rows } = await client.query(`UPDATE oauth_authorizations
89
+ SET consumed_at = now()
90
+ WHERE code_hash = $1
91
+ AND consumed_at IS NULL
92
+ AND expires_at > now()
93
+ RETURNING org_id, service_account_id, client_id, redirect_uri, code_challenge, resource, consent_id`, [hashCode(code)]);
94
+ const row = rows[0];
95
+ if (row === undefined)
96
+ return undefined;
97
+ return {
98
+ orgId: row.org_id,
99
+ serviceAccountId: row.service_account_id,
100
+ clientId: row.client_id,
101
+ redirectUri: row.redirect_uri,
102
+ codeChallenge: row.code_challenge,
103
+ ...(row.resource === null ? {} : { resource: row.resource }),
104
+ ...(row.consent_id === null ? {} : { consentId: row.consent_id }),
105
+ };
106
+ }, this.role === undefined ? {} : { role: this.role });
107
+ }
108
+ }
109
+ export class PostgresOAuthConsents {
110
+ pool;
111
+ role;
112
+ constructor(pool, role) {
113
+ this.pool = pool;
114
+ this.role = role;
115
+ }
116
+ async record(auth, clientId, serviceAccountId) {
117
+ return withOrg(this.pool, auth.orgId, async (client) => {
118
+ // Approving again reuses the row and clears a previous revocation: the
119
+ // person is deliberately reconnecting an application they had ended,
120
+ // and leaving it marked revoked would show them a connection that says
121
+ // "ended" while the client works.
122
+ const { rows } = await client.query(`INSERT INTO oauth_consents (org_id, client_id, service_account_id, approved_by)
123
+ VALUES ($1,$2,$3,$4)
124
+ ON CONFLICT (org_id, client_id, service_account_id)
125
+ DO UPDATE SET revoked_at = NULL, approved_by = EXCLUDED.approved_by
126
+ RETURNING id`, [auth.orgId, clientId, serviceAccountId, auth.principal.id]);
127
+ return rows[0].id;
128
+ }, this.role === undefined ? {} : { role: this.role });
129
+ }
130
+ async list(auth) {
131
+ return withOrg(this.pool, auth.orgId, async (client) => {
132
+ // An org_admin sees the organization's, everybody else their own. Not
133
+ // an invented gradient: an agent belongs to the organization, so
134
+ // somebody has to be able to end a connection whose approver has left.
135
+ const mine = auth.role === 'org_admin' || auth.role === 'platform_admin' ? '' : ' AND c.approved_by = $2';
136
+ const { rows } = await client.query(`SELECT c.id, c.client_id, oc.client_name, c.service_account_id,
137
+ sa.name AS service_account_name, c.approved_by,
138
+ c.created_at::text, c.last_refreshed_at::text, c.revoked_at::text
139
+ FROM oauth_consents c
140
+ JOIN oauth_clients oc ON oc.client_id = c.client_id
141
+ JOIN service_accounts sa ON sa.id = c.service_account_id AND sa.org_id = c.org_id
142
+ WHERE c.org_id = $1${mine}
143
+ ORDER BY c.created_at DESC, c.id`, mine === '' ? [auth.orgId] : [auth.orgId, auth.principal.id]);
144
+ return rows.map((r) => ({
145
+ id: r.id,
146
+ clientId: r.client_id,
147
+ clientName: r.client_name,
148
+ serviceAccountId: r.service_account_id,
149
+ serviceAccountName: r.service_account_name,
150
+ approvedBy: r.approved_by,
151
+ createdAt: r.created_at,
152
+ lastRefreshedAt: r.last_refreshed_at,
153
+ revokedAt: r.revoked_at,
154
+ }));
155
+ }, this.role === undefined ? {} : { role: this.role });
156
+ }
157
+ async revoke(auth, id) {
158
+ if (!/^[0-9a-f-]{36}$/i.test(id))
159
+ return false;
160
+ return withOrg(this.pool, auth.orgId, async (client) => {
161
+ const mine = auth.role === 'org_admin' || auth.role === 'platform_admin' ? '' : ' AND approved_by = $3';
162
+ const params = mine === '' ? [auth.orgId, id] : [auth.orgId, id, auth.principal.id];
163
+ const { rows } = await client.query(`UPDATE oauth_consents SET revoked_at = now()
164
+ WHERE org_id = $1 AND id = $2 AND revoked_at IS NULL${mine}
165
+ RETURNING id`, params);
166
+ if (rows.length === 0)
167
+ return false;
168
+ // The refresh tokens go with it, in the same transaction. Leaving them
169
+ // is the difference between a connection that says ended and one that
170
+ // *is*: the application renews on its own schedule, and a token that
171
+ // still works is a connection that has not ended.
172
+ //
173
+ // Deleted rather than marked. There is nothing to investigate later
174
+ // about a credential whose whole purpose was to be exchanged, and a row
175
+ // kept is a hash kept.
176
+ await client.query('DELETE FROM oauth_refresh_tokens WHERE org_id = $1 AND consent_id = $2', [auth.orgId, id]);
177
+ return true;
178
+ }, this.role === undefined ? {} : { role: this.role });
179
+ }
180
+ }
181
+ export class PostgresOAuthRefreshTokens {
182
+ pool;
183
+ role;
184
+ constructor(pool, role) {
185
+ this.pool = pool;
186
+ this.role = role;
187
+ }
188
+ async issue(orgId, consentId, token, family, expiresAt) {
189
+ return withOrg(this.pool, orgId, async (client) => {
190
+ const { rows } = await client.query(`INSERT INTO oauth_refresh_tokens (org_id, consent_id, token_hash, family_id, expires_at)
191
+ VALUES ($1,$2,$3,COALESCE($4::uuid, gen_random_uuid()),$5)
192
+ RETURNING family_id`, [orgId, consentId, hashCode(token), family ?? null, expiresAt]);
193
+ return rows[0].family_id;
194
+ }, this.role === undefined ? {} : { role: this.role });
195
+ }
196
+ async rotate(token) {
197
+ // The same split as an authorization code, and for the same reason: the
198
+ // endpoint holds a bearer secret and no organization, so the lookup crosses
199
+ // tenants and is **read-only** — that restriction is what keeps the one
200
+ // tenant-spanning path unable to write.
201
+ const found = await whileAuthenticating(this.pool, async (client) => {
202
+ const { rows } = await client.query('SELECT org_id FROM oauth_refresh_tokens WHERE token_hash = $1', [hashCode(token)]);
203
+ return rows[0]?.org_id;
204
+ }, this.role === undefined ? {} : { role: this.role });
205
+ if (found === undefined)
206
+ return undefined;
207
+ return withOrg(this.pool, found, async (client) => {
208
+ const { rows } = await client.query(`SELECT t.id, t.consent_id, t.family_id, t.used_at, t.expires_at <= now() AS expired,
209
+ CASE WHEN c.revoked_at IS NULL THEN c.service_account_id END AS service_account_id
210
+ FROM oauth_refresh_tokens t
211
+ JOIN oauth_consents c ON c.id = t.consent_id
212
+ WHERE t.token_hash = $1
213
+ FOR UPDATE OF t`, [hashCode(token)]);
214
+ const row = rows[0];
215
+ if (row === undefined)
216
+ return undefined;
217
+ if (row.used_at !== null) {
218
+ // A replay. The legitimate holder has already exchanged this, so two
219
+ // parties hold it and there is no way to tell which is which — the
220
+ // only safe answer is that neither continues. Same rule as the
221
+ // sign-in family, and it is the reason a family id exists at all.
222
+ await client.query('DELETE FROM oauth_refresh_tokens WHERE org_id = $1 AND family_id = $2', [
223
+ found,
224
+ row.family_id,
225
+ ]);
226
+ return undefined;
227
+ }
228
+ if (row.expired || row.service_account_id === null)
229
+ return undefined;
230
+ // Spent, in the statement that reads it: two concurrent exchanges race
231
+ // for one row and exactly one wins.
232
+ const { rows: spent } = await client.query('UPDATE oauth_refresh_tokens SET used_at = now() WHERE id = $1 AND used_at IS NULL RETURNING id', [row.id]);
233
+ if (spent.length === 0)
234
+ return undefined;
235
+ await client.query('UPDATE oauth_consents SET last_refreshed_at = now() WHERE org_id = $1 AND id = $2', [
236
+ found,
237
+ row.consent_id,
238
+ ]);
239
+ return {
240
+ orgId: found,
241
+ consentId: row.consent_id,
242
+ serviceAccountId: row.service_account_id,
243
+ family: row.family_id,
244
+ };
245
+ }, this.role === undefined ? {} : { role: this.role });
246
+ }
247
+ }
248
+ //# sourceMappingURL=oauth-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-store.js","sourceRoot":"","sources":["../src/oauth-store.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -4,6 +4,7 @@ import { type AuthContext, type VerifyOptions } from './auth.js';
4
4
  import { type IdempotencyStore } from './idempotency.js';
5
5
  import { type LimitPolicy, type RateLimiter, type Resource } from './limits.js';
6
6
  import type { Login } from './login.js';
7
+ import type { OAuthAuthorizations, OAuthClients, OAuthConsents, OAuthRefreshTokens } from './oauth-store.js';
7
8
  import { type Groups, type Users } from './principals.js';
8
9
  import { type Page, type PageResult } from './pagination.js';
9
10
  export type { Page, PageResult };
@@ -392,6 +393,8 @@ export interface ServiceAccountView {
392
393
  readonly createdAt: string;
393
394
  readonly lastUsedAt: string | null;
394
395
  readonly revokedAt: string | null;
396
+ /** The person who created it, where one did. See the port's own note. */
397
+ readonly createdBy?: string | null;
395
398
  }
396
399
  export interface ServiceAccountPort {
397
400
  list(auth: AuthContext, page?: Page): Promise<PageResult<ServiceAccountView>>;
@@ -602,6 +605,48 @@ export interface ReferenceQueries {
602
605
  export interface AuditReader {
603
606
  read(auth: AuthContext, query: AuditQuery, page: Page): Promise<PageResult<AuditRecord>>;
604
607
  }
608
+ /**
609
+ * The authorization server, when a deployment runs one.
610
+ *
611
+ * Optional, and its absence is a supported shape rather than a degraded one: a
612
+ * deployment with its own identity provider names that in
613
+ * `NACRE_OAUTH_AUTHORIZATION_SERVER` and this stays off, which is exactly what
614
+ * this product was before the flow existed.
615
+ */
616
+ export interface OAuthServer {
617
+ /** The issuer, which is this API's canonical URL. */
618
+ readonly issuer: string;
619
+ /** Where a browser is sent to choose an agent. The admin UI's consent screen. */
620
+ readonly consentUrl: string;
621
+ readonly clients: OAuthClients;
622
+ readonly authorizations: OAuthAuthorizations;
623
+ readonly consents: OAuthConsents;
624
+ readonly refreshTokens: OAuthRefreshTokens;
625
+ /** How long an OAuth refresh token lives. The connection's real lifetime. */
626
+ readonly refreshTtlSeconds: number;
627
+ /**
628
+ * How long an access token lives, reported to whoever ends a connection.
629
+ *
630
+ * A revocation deletes the refresh token; the access token already out is
631
+ * verified against a key and keeps working until it expires. Saying so is the
632
+ * honest form of "ended".
633
+ */
634
+ readonly accessTtlSeconds: number;
635
+ /**
636
+ * Mint an access token for the approved **service account**.
637
+ *
638
+ * Never for the person who consented. That is the whole design: they
639
+ * authenticate, the agent is authorized, and revoking one does not touch the
640
+ * other.
641
+ */
642
+ mint(approved: {
643
+ orgId: string;
644
+ serviceAccountId: string;
645
+ }): Promise<{
646
+ accessToken: string;
647
+ expiresIn: number;
648
+ }>;
649
+ }
605
650
  export interface ApiOptions {
606
651
  readonly verify: VerifyOptions;
607
652
  /** Rendered at /metrics. Absent means the endpoint answers 404. */
@@ -663,6 +708,7 @@ export interface ApiOptions {
663
708
  */
664
709
  readonly jwks?: readonly Record<string, unknown>[];
665
710
  /** Absent means the workspace paths answer 404, like any capability a surface lacks. */
711
+ readonly oauth?: OAuthServer;
666
712
  readonly workspaces?: Workspaces;
667
713
  /** Layer reindex. Absent means the reindex paths answer 404. */
668
714
  readonly reindex?: Reindex;