@camstack/system 1.2.377 → 1.2.379

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 (93) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/addon-runner.mjs +1 -1
  3. package/dist/addon-utils.js +1 -1
  4. package/dist/addon-utils.mjs +1 -1
  5. package/dist/auth/auth-manager.d.ts +10 -2
  6. package/dist/auth/jwt-signing-key.d.ts +42 -0
  7. package/dist/auth/user-manager.d.ts +19 -19
  8. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  9. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  10. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  11. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  12. package/dist/builtins/alerts/alerts.addon.js +1 -1
  13. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  14. package/dist/builtins/autotrack/index.js +1 -1
  15. package/dist/builtins/autotrack/index.mjs +1 -1
  16. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  17. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  18. package/dist/builtins/calendars/calendars.addon.js +1 -1
  19. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  20. package/dist/builtins/camera-grid/index.js +1 -1
  21. package/dist/builtins/camera-grid/index.mjs +1 -1
  22. package/dist/builtins/composer/composer.addon.js +2 -2
  23. package/dist/builtins/composer/composer.addon.mjs +2 -2
  24. package/dist/builtins/console-logging/index.js +1 -1
  25. package/dist/builtins/console-logging/index.mjs +1 -1
  26. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  27. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  28. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  29. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  30. package/dist/builtins/hub-forwarder/index.js +1 -1
  31. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  32. package/dist/builtins/keychain/index.js +67 -11
  33. package/dist/builtins/keychain/index.mjs +67 -11
  34. package/dist/builtins/keychain/keychain-service.d.ts +14 -2
  35. package/dist/builtins/keychain/system-held-secrets.d.ts +11 -0
  36. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  37. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  38. package/dist/builtins/local-auth/admin-account-boot.d.ts +1 -1
  39. package/dist/builtins/local-auth/auth-config-reader.d.ts +9 -7
  40. package/dist/builtins/local-auth/jwt-signing-key-keeper.d.ts +30 -0
  41. package/dist/builtins/local-auth/local-auth.addon.d.ts +2 -6
  42. package/dist/builtins/local-auth/local-auth.addon.js +127 -221
  43. package/dist/builtins/local-auth/local-auth.addon.mjs +126 -220
  44. package/dist/builtins/local-network/local-network.addon.js +1 -1
  45. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  46. package/dist/builtins/loki-logging/index.js +1 -1
  47. package/dist/builtins/loki-logging/index.mjs +1 -1
  48. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  49. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  50. package/dist/builtins/platform-probe/index.js +1 -1
  51. package/dist/builtins/platform-probe/index.mjs +1 -1
  52. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  53. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  54. package/dist/builtins/snapshot/index.js +1 -1
  55. package/dist/builtins/snapshot/index.mjs +1 -1
  56. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  57. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  58. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  59. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  60. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  61. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  62. package/dist/builtins/system-config/cluster-secret-keeper.d.ts +36 -0
  63. package/dist/builtins/system-config/system-config.addon.d.ts +13 -0
  64. package/dist/builtins/system-config/system-config.addon.js +244 -53
  65. package/dist/builtins/system-config/system-config.addon.mjs +244 -54
  66. package/dist/builtins/winston-logging/index.js +1 -1
  67. package/dist/builtins/winston-logging/index.mjs +1 -1
  68. package/dist/{child-cap-dispatch-DlDSoqm1.js → child-cap-dispatch-CZeRUgYF.js} +1 -1
  69. package/dist/{child-cap-dispatch-CgmOo0yl.mjs → child-cap-dispatch-CpjohToR.mjs} +1 -1
  70. package/dist/cluster-secret-BDue-uJj.mjs +83 -0
  71. package/dist/cluster-secret-Dg0OOOSr.js +148 -0
  72. package/dist/{composition-sources-BNyXPSs_.js → composition-sources-CHvLMrFI.js} +1 -1
  73. package/dist/{composition-sources-D39bl0nP.mjs → composition-sources-DT_uJwI3.mjs} +1 -1
  74. package/dist/{dist-BWNoS-1S.mjs → dist-B9oFw2jh.mjs} +200 -3
  75. package/dist/{dist-D_a9mUiM.js → dist-Cc6KOdY-.js} +211 -2
  76. package/dist/{event-loop-stall-monitor-ClPhfx7Y.mjs → event-loop-stall-monitor-anUH2IE1.mjs} +21 -20
  77. package/dist/{event-loop-stall-monitor-DuOn8H1n.js → event-loop-stall-monitor-mk6WGxir.js} +21 -20
  78. package/dist/index.d.ts +4 -2
  79. package/dist/index.js +192 -62
  80. package/dist/index.mjs +171 -55
  81. package/dist/jwt-signing-key-C2rE3wH6.js +174 -0
  82. package/dist/jwt-signing-key-Qhde8r82.mjs +127 -0
  83. package/dist/kernel/config-manager.d.ts +1 -1
  84. package/dist/kernel/config-schema.d.ts +4 -11
  85. package/dist/kernel/index.d.ts +2 -1
  86. package/dist/kernel/moleculer/broker-factory.d.ts +0 -2
  87. package/dist/kernel/moleculer/cluster-secret.d.ts +31 -0
  88. package/dist/kernel/moleculer/hub-service.d.ts +7 -4
  89. package/dist/kernel/moleculer/node-registry.d.ts +1 -1
  90. package/dist/kernel/system-settings-policy.d.ts +7 -9
  91. package/dist/{retired-settings-keys-iGcmzwLV.mjs → retired-settings-keys-DlZ3VV6x.mjs} +1 -1
  92. package/dist/{retired-settings-keys-CDyOGAje.js → retired-settings-keys-YOOKLA3v.js} +1 -1
  93. package/package.json +1 -1
@@ -1,4 +1,6 @@
1
- import { Er as formatSecretScope, Fr as parseSecretRef, Gr as EventCategory, Gt as keychainCapability, Mr as normalizeSecretOwner, Wt as keychainAdminCapability, lr as BaseAddon } from "../../dist-BWNoS-1S.mjs";
1
+ import { Dr as formatSecretScope, Gt as keychainCapability, Ir as parseSecretRef, Nr as normalizeSecretOwner, Wt as keychainAdminCapability, lr as BaseAddon, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
2
+ import { r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "../../jwt-signing-key-Qhde8r82.mjs";
3
+ import { i as CLUSTER_SECRET_SETTINGS_KEY } from "../../cluster-secret-BDue-uJj.mjs";
2
4
  import { n as getPlatformKeychainKey } from "../../platform-key-source-BWlq0jjn.mjs";
3
5
  import { createCipheriv, createDecipheriv, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
4
6
  import * as path$1 from "node:path";
@@ -197,6 +199,13 @@ function buildKeySourceCandidates(opts) {
197
199
  */
198
200
  async function writeDefaultKeyFile(dataDir, key, opts) {
199
201
  const file = defaultKeyFilePath(dataDir);
202
+ try {
203
+ return await writeKeyFileAt(file, key, opts);
204
+ } catch (err) {
205
+ throw new Error(`could not write the master key at ${file}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
206
+ }
207
+ }
208
+ async function writeKeyFileAt(file, key, opts) {
200
209
  const dir = path$1.dirname(file);
201
210
  await promises.mkdir(dir, {
202
211
  recursive: true,
@@ -217,6 +226,8 @@ async function writeDefaultKeyFile(dataDir, key, opts) {
217
226
  await promises.writeFile(tmp, `${encodeKeyMaterial(key)}\n`, { mode: 384 });
218
227
  await promises.rename(tmp, file);
219
228
  await promises.chmod(file, 384);
229
+ const back = await loadKeyFile(file);
230
+ if (back.kind !== "loaded" || !back.key.equals(key)) throw new Error("the written key file does not read back as the generated key");
220
231
  return movedAside;
221
232
  }
222
233
  //#endregion
@@ -620,6 +631,14 @@ var KeychainRepository = class {
620
631
  return rows.length;
621
632
  }
622
633
  };
634
+ //#endregion
635
+ //#region src/builtins/keychain/system-held-secrets.ts
636
+ /** The refs `keychain-admin.setSystemSecret` may write, by name. */
637
+ var SYSTEM_HELD_SECRET_REFS = { "jwt-signing-key": JWT_SIGNING_KEY_REF };
638
+ /** System refs no blob points at — in use for as long as they exist. */
639
+ var PROCESS_HELD_SECRET_REFS = new Set([JWT_SIGNING_KEY_REF]);
640
+ /** `system-settings` keys that may hold a system-owned secret's marker. */
641
+ var SYSTEM_SECRET_SETTINGS_KEYS = [CLUSTER_SECRET_SETTINGS_KEY];
623
642
  var KeychainLockedError = class extends Error {
624
643
  reason;
625
644
  constructor(reason) {
@@ -664,10 +683,14 @@ var KeychainService = class {
664
683
  this.unlock = await this.computeUnlock();
665
684
  if (this.unlock.state === "ready") this.deps.logger.info("keychain unlocked", {
666
685
  source: this.unlock.source.kind,
686
+ path: this.unlock.source.path,
667
687
  fingerprint: shortFingerprint(this.unlock.fingerprint),
668
688
  rotationPending: this.unlock.rotationPending
669
689
  });
670
- else this.deps.logger.error("keychain LOCKED — every secret resolves unavailable", { reason: this.unlock.reason });
690
+ else this.deps.logger.error("keychain LOCKED — every secret resolves unavailable", {
691
+ reason: this.unlock.reason,
692
+ path: this.configuredSource?.path
693
+ });
671
694
  try {
672
695
  await this.deps.repo.pruneAudit(this.now());
673
696
  } catch (err) {
@@ -759,10 +782,19 @@ var KeychainService = class {
759
782
  };
760
783
  else if (primary.source.kind === "default-file") {
761
784
  kek = generateKey();
762
- await writeDefaultKeyFile(this.deps.dataDir, kek, {
763
- replace: false,
764
- nowMs: this.now()
765
- });
785
+ try {
786
+ await writeDefaultKeyFile(this.deps.dataDir, kek, {
787
+ replace: false,
788
+ nowMs: this.now()
789
+ });
790
+ } catch (err) {
791
+ this.deps.logger.error("keychain master key could NOT be generated — no key stored", {
792
+ path: primary.source.path,
793
+ error: errMsg(err)
794
+ });
795
+ throw err;
796
+ }
797
+ this.deps.logger.info("keychain master key generated", { path: primary.source.path });
766
798
  } else return {
767
799
  state: "locked",
768
800
  reason: "key-missing"
@@ -817,7 +849,11 @@ var KeychainService = class {
817
849
  if (parts === null || !this.owns(caller, parts.owner)) throw new KeychainForbiddenError(ref, caller);
818
850
  return parts.owner;
819
851
  }
820
- async put(caller, ref, value) {
852
+ /**
853
+ * @param actor who the audit names — the owner addon by default; the
854
+ * operator (`user:<id>`) for {@link setSystemSecret}.
855
+ */
856
+ async put(caller, ref, value, actor = actorOfAddon(caller)) {
821
857
  const owner = this.ownerOf(ref, caller);
822
858
  const unlocked = this.requireReady();
823
859
  if (value.length === 0) throw new Error("keychain.put: an empty value is not stored — delete the ref");
@@ -843,10 +879,10 @@ var KeychainService = class {
843
879
  version,
844
880
  createdAt: existing?.createdAt ?? t,
845
881
  updatedAt: t,
846
- updatedBy: actorOfAddon(caller),
882
+ updatedBy: actor,
847
883
  lastReadAt: existing?.lastReadAt ?? null
848
884
  });
849
- await this.audit("put", actorOfAddon(caller), ref, `version=${version}`);
885
+ await this.audit("put", actor, ref, `version=${version}`);
850
886
  this.deps.events.emit({
851
887
  ref,
852
888
  owner,
@@ -976,6 +1012,14 @@ var KeychainService = class {
976
1012
  usage: usage.get(row.ref) ?? "unknown"
977
1013
  }));
978
1014
  }
1015
+ /**
1016
+ * The operator replaces a system-held secret no form edits (D797) — the
1017
+ * session signing key. Stored under owner `system`, audited as the user.
1018
+ */
1019
+ async setSystemSecret(userId, name, value) {
1020
+ const ref = SYSTEM_HELD_SECRET_REFS[name];
1021
+ return this.put(SYSTEM_SECRET_OWNER, ref, value, `user:${userId}`);
1022
+ }
979
1023
  async listAudit(limit) {
980
1024
  return this.deps.repo.listAudit(limit);
981
1025
  }
@@ -1215,6 +1259,13 @@ async function prefixRows(door, collection, prefix) {
1215
1259
  }
1216
1260
  /** The blobs that may hold the marker of a ref in `scope`; `null` = cannot tell. */
1217
1261
  async function blobsFor(door, owner, scope) {
1262
+ if (owner === "system" && scope.kind === "global") return [[...PROCESS_HELD_SECRET_REFS].map((ref) => ({
1263
+ $secret: ref,
1264
+ v: 1
1265
+ })), ...await Promise.all(SYSTEM_SECRET_SETTINGS_KEYS.map((key) => door.get({
1266
+ collection: "system-settings",
1267
+ key
1268
+ })))];
1218
1269
  switch (scope.kind) {
1219
1270
  case "global":
1220
1271
  case "node": {
@@ -1303,8 +1354,12 @@ function createKeychainUsageCheck(door) {
1303
1354
  * orphans, rotation, recovery key, reset. Every method admin; the four
1304
1355
  * that change or hand out material take the session's user for the audit.
1305
1356
  *
1306
- * It does not run on agents: the manifest places it `hub-only`, and an agent
1307
- * addon reaches it through `$hub-cap-fwd` like every other hub cap.
1357
+ * It does not run on agents: an agent's Phase 1 drops `keychain` from its infra
1358
+ * list (`server/backend/src/agent/agent-infra-capabilities.ts`), and an agent
1359
+ * addon reaches it through `$hub-cap-fwd` like every other hub cap. Until
1360
+ * 2026-10-08 agents DID boot it — their store door forwards to the hub, so an
1361
+ * agent wrote the hub's `keychain:keys` row with a key file on its own disk.
1362
+ * Booting first, it left the hub locked `key-missing`.
1308
1363
  */
1309
1364
  var DAY_MS = 1440 * 6e4;
1310
1365
  /** The caller the transport stamped (or an in-process caller stated). */
@@ -1392,6 +1447,7 @@ var KeychainAddon = class extends BaseAddon {
1392
1447
  listSecrets: () => service.listSecrets(),
1393
1448
  listAudit: (input) => service.listAudit(input.limit ?? 100),
1394
1449
  reveal: (input) => service.reveal(input.caller.userId, input.ref),
1450
+ setSystemSecret: (input) => service.setSystemSecret(input.caller.userId, input.name, input.value),
1395
1451
  deleteOrphans: (input) => service.deleteOrphans(input.caller.userId, input.refs),
1396
1452
  rotateMasterKey: (input) => service.rotateMasterKey(input.caller.userId),
1397
1453
  purgeRetiredKeys: async (input) => ({ purged: await service.purgeRetiredKeys(input.caller.userId) }),
@@ -1,4 +1,4 @@
1
- import { EventCategory, KeychainAuditEntry, KeychainKeySource, KeychainResolveResult, KeychainSecretMeta, KeychainSecretUsage, KeychainState, KeychainStatus, KeychainUnavailableReason } from '@camstack/types';
1
+ import { EventCategory, KeychainAuditEntry, KeychainKeySource, KeychainResolveResult, KeychainSecretMeta, KeychainSecretUsage, KeychainState, KeychainStatus, KeychainUnavailableReason, SystemHeldSecretName } from '@camstack/types';
2
2
  import { KeychainRepository, KeychainSecretRow } from './keychain-store.js';
3
3
  import { KeySourceCandidate } from './key-sources.js';
4
4
  /** `lastReadAt` is written at most this often per ref (hub I/O is the bottleneck). */
@@ -54,7 +54,11 @@ export declare class KeychainService {
54
54
  /** May `caller` touch values owned by `owner`? */
55
55
  owns(caller: string | null, owner: string): boolean;
56
56
  private ownerOf;
57
- put(caller: string | null, ref: string, value: string): Promise<{
57
+ /**
58
+ * @param actor who the audit names — the owner addon by default; the
59
+ * operator (`user:<id>`) for {@link setSystemSecret}.
60
+ */
61
+ put(caller: string | null, ref: string, value: string, actor?: string): Promise<{
58
62
  ref: string;
59
63
  version: number;
60
64
  }>;
@@ -66,6 +70,14 @@ export declare class KeychainService {
66
70
  listSecrets(): Promise<readonly (KeychainSecretMeta & {
67
71
  usage: KeychainSecretUsage;
68
72
  })[]>;
73
+ /**
74
+ * The operator replaces a system-held secret no form edits (D797) — the
75
+ * session signing key. Stored under owner `system`, audited as the user.
76
+ */
77
+ setSystemSecret(userId: string, name: SystemHeldSecretName, value: string): Promise<{
78
+ ref: string;
79
+ version: number;
80
+ }>;
69
81
  listAudit(limit: number): Promise<readonly KeychainAuditEntry[]>;
70
82
  reveal(userId: string, ref: string): Promise<{
71
83
  value: string;
@@ -0,0 +1,11 @@
1
+ import { SystemHeldSecretName } from '@camstack/types';
2
+ import { SYSTEM_SECRET_OWNER } from '../../auth/jwt-signing-key.js';
3
+ import { CLUSTER_SECRET_REF } from '../../kernel/moleculer/cluster-secret.js';
4
+ export { SYSTEM_SECRET_OWNER };
5
+ /** The refs `keychain-admin.setSystemSecret` may write, by name. */
6
+ export declare const SYSTEM_HELD_SECRET_REFS: Readonly<Record<SystemHeldSecretName, string>>;
7
+ /** System refs no blob points at — in use for as long as they exist. */
8
+ export declare const PROCESS_HELD_SECRET_REFS: ReadonlySet<string>;
9
+ /** `system-settings` keys that may hold a system-owned secret's marker. */
10
+ export declare const SYSTEM_SECRET_SETTINGS_KEYS: readonly string[];
11
+ export { CLUSTER_SECRET_REF };
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../chunk-Cek0wNdY.js");
3
- const require_dist = require("../../dist-D_a9mUiM.js");
3
+ const require_dist = require("../../dist-Cc6KOdY-.js");
4
4
  //#region src/builtins/liveness-monitor/liveness-checks.ts
5
5
  var NO_DEVICES = "liveness:no-devices";
6
6
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -1,4 +1,4 @@
1
- import { F as RecordingStatusSchema, Gr as EventCategory, N as RECORDING_SOURCE_CAMSTACK_ADDON, Sr as createEvent, cr as errMsg, lr as BaseAddon } from "../../dist-BWNoS-1S.mjs";
1
+ import { Cr as createEvent, F as RecordingStatusSchema, N as RECORDING_SOURCE_CAMSTACK_ADDON, cr as errMsg, lr as BaseAddon, qr as EventCategory } from "../../dist-B9oFw2jh.mjs";
2
2
  //#region src/builtins/liveness-monitor/liveness-checks.ts
3
3
  var NO_DEVICES = "liveness:no-devices";
4
4
  var ALL_OFFLINE = "liveness:all-devices-offline";
@@ -21,7 +21,7 @@ export interface AdminAccountBootInput {
21
21
  }
22
22
  export interface AdminAccountBootResult {
23
23
  readonly outcome: AdminSeedOutcome;
24
- /** The admin still signs in with {@link DEFAULT_ADMIN_PASSWORD}. */
24
+ /** The admin still signs in with {@link FIRST_BOOT_ADMIN_PASSWORD}. */
25
25
  readonly usesDefaultPassword: boolean;
26
26
  }
27
27
  export declare function reconcileAdminAccountAtBoot(input: AdminAccountBootInput): Promise<AdminAccountBootResult>;
@@ -1,9 +1,13 @@
1
1
  import { AuthConfigReader } from '../../auth/auth-manager.js';
2
- /** The values `local-auth` pre-resolves before constructing its AuthManager. */
2
+ /**
3
+ * The values `local-auth` pre-resolves before constructing its AuthManager.
4
+ *
5
+ * No credential is among them (D797): the session signing key lives in the
6
+ * keychain (`jwt-signing-key.ts`) and the first-boot admin is fixed
7
+ * (`admin` / `changeme`), so `auth.jwtSecret`, `auth.adminUsername` and
8
+ * `auth.adminPassword` are answered by nothing.
9
+ */
3
10
  export interface ResolvedAuthConfig {
4
- readonly jwtSecret: string;
5
- readonly adminUsername: string;
6
- readonly adminPassword: string;
7
11
  /**
8
12
  * Operator-configured session lifetime. `undefined` when the `auth` section
9
13
  * carries no value — the signer then applies `DEFAULT_TOKEN_EXPIRY`, which
@@ -11,10 +15,8 @@ export interface ResolvedAuthConfig {
11
15
  */
12
16
  readonly tokenExpiry: string | undefined;
13
17
  }
14
- /** Persist the generated JWT secret. Called by AuthManager on first boot. */
15
- export type AuthSectionWriter = (patch: Record<string, unknown>) => void;
16
18
  /**
17
19
  * Every config path this reader can answer. Anything else resolves to
18
20
  * `undefined` by construction — see the module docblock.
19
21
  */
20
- export declare function createAuthConfigReader(resolved: ResolvedAuthConfig, writeAuthSection: AuthSectionWriter): AuthConfigReader;
22
+ export declare function createAuthConfigReader(resolved: ResolvedAuthConfig): AuthConfigReader;
@@ -0,0 +1,30 @@
1
+ import { SecretsAccess } from '@camstack/types';
2
+ /** How often a locked keychain is asked again. */
3
+ export declare const SIGNING_KEY_RETRY_MS = 30000;
4
+ interface KeeperLogger {
5
+ info(message: string, meta?: {
6
+ meta?: Record<string, unknown>;
7
+ }): void;
8
+ error(message: string, meta?: {
9
+ meta?: Record<string, unknown>;
10
+ }): void;
11
+ }
12
+ export interface JwtSigningKeyKeeperDeps {
13
+ /** A keychain handle for owner `system`; `null` when this process has no keychain door. */
14
+ readonly secrets: SecretsAccess | null;
15
+ readonly logger: KeeperLogger;
16
+ readonly retryMs?: number;
17
+ }
18
+ export declare class JwtSigningKeyKeeper {
19
+ private readonly deps;
20
+ private retryTimer;
21
+ private unsubscribe;
22
+ private stopped;
23
+ constructor(deps: JwtSigningKeyKeeperDeps);
24
+ start(): Promise<void>;
25
+ stop(): void;
26
+ private load;
27
+ private apply;
28
+ private scheduleRetry;
29
+ }
30
+ export {};
@@ -1,10 +1,5 @@
1
1
  import { ProviderRegistration, BaseAddon } from '@camstack/types';
2
- interface LocalAuthConfig {
3
- jwtSecret?: string;
4
- adminUsername?: string;
5
- adminPassword?: string;
6
- }
7
- export declare class LocalAuthAddon extends BaseAddon<LocalAuthConfig> {
2
+ export declare class LocalAuthAddon extends BaseAddon {
8
3
  private authManager;
9
4
  private userManager;
10
5
  private apiKeyManager;
@@ -13,6 +8,7 @@ export declare class LocalAuthAddon extends BaseAddon<LocalAuthConfig> {
13
8
  private reapTimer;
14
9
  private totpManager;
15
10
  private externalIdentities;
11
+ private signingKeyKeeper;
16
12
  constructor();
17
13
  protected onInitialize(): Promise<ProviderRegistration[]>;
18
14
  /**