life-as-api 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 (303) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +377 -0
  3. package/dist/agent/finance-agent.d.ts +44 -0
  4. package/dist/agent/finance-agent.js +75 -0
  5. package/dist/agent/finance-agent.js.map +1 -0
  6. package/dist/agent/legal-agent.d.ts +44 -0
  7. package/dist/agent/legal-agent.js +76 -0
  8. package/dist/agent/legal-agent.js.map +1 -0
  9. package/dist/agent/medical-agent.d.ts +44 -0
  10. package/dist/agent/medical-agent.js +75 -0
  11. package/dist/agent/medical-agent.js.map +1 -0
  12. package/dist/agent/trusted-agent-registry.d.ts +53 -0
  13. package/dist/agent/trusted-agent-registry.js +57 -0
  14. package/dist/agent/trusted-agent-registry.js.map +1 -0
  15. package/dist/audit/audit-chain-verifier.d.ts +10 -0
  16. package/dist/audit/audit-chain-verifier.js +67 -0
  17. package/dist/audit/audit-chain-verifier.js.map +1 -0
  18. package/dist/audit/audit-log.d.ts +48 -0
  19. package/dist/audit/audit-log.js +74 -0
  20. package/dist/audit/audit-log.js.map +1 -0
  21. package/dist/audit/sqlite-audit-log.d.ts +29 -0
  22. package/dist/audit/sqlite-audit-log.js +142 -0
  23. package/dist/audit/sqlite-audit-log.js.map +1 -0
  24. package/dist/auth/access-context-issuer.d.ts +18 -0
  25. package/dist/auth/access-context-issuer.js +88 -0
  26. package/dist/auth/access-context-issuer.js.map +1 -0
  27. package/dist/auth/assert-authorized-for-subject.d.ts +2 -0
  28. package/dist/auth/assert-authorized-for-subject.js +20 -0
  29. package/dist/auth/assert-authorized-for-subject.js.map +1 -0
  30. package/dist/auth/backend-context-minting-boundary.d.ts +23 -0
  31. package/dist/auth/backend-context-minting-boundary.js +281 -0
  32. package/dist/auth/backend-context-minting-boundary.js.map +1 -0
  33. package/dist/auth/default-authorization-policy.d.ts +7 -0
  34. package/dist/auth/default-authorization-policy.js +64 -0
  35. package/dist/auth/default-authorization-policy.js.map +1 -0
  36. package/dist/auth/fake-auth-adapter.d.ts +7 -0
  37. package/dist/auth/fake-auth-adapter.js +27 -0
  38. package/dist/auth/fake-auth-adapter.js.map +1 -0
  39. package/dist/auth/http-client.d.ts +12 -0
  40. package/dist/auth/http-client.js +7 -0
  41. package/dist/auth/http-client.js.map +1 -0
  42. package/dist/auth/in-memory-grant-resolver.d.ts +21 -0
  43. package/dist/auth/in-memory-grant-resolver.js +73 -0
  44. package/dist/auth/in-memory-grant-resolver.js.map +1 -0
  45. package/dist/auth/in-memory-tenant-boundary.d.ts +16 -0
  46. package/dist/auth/in-memory-tenant-boundary.js +37 -0
  47. package/dist/auth/in-memory-tenant-boundary.js.map +1 -0
  48. package/dist/auth/jwks-key-ring-auth-adapter.d.ts +38 -0
  49. package/dist/auth/jwks-key-ring-auth-adapter.js +123 -0
  50. package/dist/auth/jwks-key-ring-auth-adapter.js.map +1 -0
  51. package/dist/auth/jwks-key-ring.d.ts +25 -0
  52. package/dist/auth/jwks-key-ring.js +111 -0
  53. package/dist/auth/jwks-key-ring.js.map +1 -0
  54. package/dist/auth/jwt-auth-adapter.d.ts +15 -0
  55. package/dist/auth/jwt-auth-adapter.js +59 -0
  56. package/dist/auth/jwt-auth-adapter.js.map +1 -0
  57. package/dist/auth/jwt-core.d.ts +32 -0
  58. package/dist/auth/jwt-core.js +226 -0
  59. package/dist/auth/jwt-core.js.map +1 -0
  60. package/dist/auth/jwt-key-ring-auth-adapter.d.ts +16 -0
  61. package/dist/auth/jwt-key-ring-auth-adapter.js +58 -0
  62. package/dist/auth/jwt-key-ring-auth-adapter.js.map +1 -0
  63. package/dist/auth/oidc-discovery.d.ts +15 -0
  64. package/dist/auth/oidc-discovery.js +46 -0
  65. package/dist/auth/oidc-discovery.js.map +1 -0
  66. package/dist/auth/production-scoped-life-api.d.ts +58 -0
  67. package/dist/auth/production-scoped-life-api.js +802 -0
  68. package/dist/auth/production-scoped-life-api.js.map +1 -0
  69. package/dist/auth/proposal-scope-inspector.d.ts +3 -0
  70. package/dist/auth/proposal-scope-inspector.js +42 -0
  71. package/dist/auth/proposal-scope-inspector.js.map +1 -0
  72. package/dist/auth/proposal-scoped-life-api.d.ts +21 -0
  73. package/dist/auth/proposal-scoped-life-api.js +168 -0
  74. package/dist/auth/proposal-scoped-life-api.js.map +1 -0
  75. package/dist/auth/rate-limited-context-minting-boundary.d.ts +27 -0
  76. package/dist/auth/rate-limited-context-minting-boundary.js +77 -0
  77. package/dist/auth/rate-limited-context-minting-boundary.js.map +1 -0
  78. package/dist/auth/revocation-aware-auth-adapter.d.ts +21 -0
  79. package/dist/auth/revocation-aware-auth-adapter.js +88 -0
  80. package/dist/auth/revocation-aware-auth-adapter.js.map +1 -0
  81. package/dist/auth/sqlite-grant-resolver.d.ts +8 -0
  82. package/dist/auth/sqlite-grant-resolver.js +78 -0
  83. package/dist/auth/sqlite-grant-resolver.js.map +1 -0
  84. package/dist/auth/sqlite-tenant-boundary.d.ts +7 -0
  85. package/dist/auth/sqlite-tenant-boundary.js +41 -0
  86. package/dist/auth/sqlite-tenant-boundary.js.map +1 -0
  87. package/dist/auth/static-jwt-key-ring.d.ts +13 -0
  88. package/dist/auth/static-jwt-key-ring.js +73 -0
  89. package/dist/auth/static-jwt-key-ring.js.map +1 -0
  90. package/dist/auth/subject-scoped-life-api.d.ts +14 -0
  91. package/dist/auth/subject-scoped-life-api.js +51 -0
  92. package/dist/auth/subject-scoped-life-api.js.map +1 -0
  93. package/dist/auth/test-context-minting-boundary.d.ts +13 -0
  94. package/dist/auth/test-context-minting-boundary.js +74 -0
  95. package/dist/auth/test-context-minting-boundary.js.map +1 -0
  96. package/dist/auth/types.d.ts +77 -0
  97. package/dist/auth/types.js +16 -0
  98. package/dist/auth/types.js.map +1 -0
  99. package/dist/compliance/subject-data-report.d.ts +43 -0
  100. package/dist/compliance/subject-data-report.js +155 -0
  101. package/dist/compliance/subject-data-report.js.map +1 -0
  102. package/dist/consent/consent-guard.d.ts +4 -0
  103. package/dist/consent/consent-guard.js +37 -0
  104. package/dist/consent/consent-guard.js.map +1 -0
  105. package/dist/consent/grant-registry.d.ts +7 -0
  106. package/dist/consent/grant-registry.js +13 -0
  107. package/dist/consent/grant-registry.js.map +1 -0
  108. package/dist/consent/intersect-selector.d.ts +3 -0
  109. package/dist/consent/intersect-selector.js +66 -0
  110. package/dist/consent/intersect-selector.js.map +1 -0
  111. package/dist/contract/diagnostics.d.ts +32 -0
  112. package/dist/contract/diagnostics.js +112 -0
  113. package/dist/contract/diagnostics.js.map +1 -0
  114. package/dist/contract/project-contracts.d.ts +5 -0
  115. package/dist/contract/project-contracts.js +159 -0
  116. package/dist/contract/project-contracts.js.map +1 -0
  117. package/dist/contract/types.d.ts +32 -0
  118. package/dist/contract/types.js +5 -0
  119. package/dist/contract/types.js.map +1 -0
  120. package/dist/crypto/aes-gcm.d.ts +11 -0
  121. package/dist/crypto/aes-gcm.js +78 -0
  122. package/dist/crypto/aes-gcm.js.map +1 -0
  123. package/dist/crypto/claim-serializer.d.ts +26 -0
  124. package/dist/crypto/claim-serializer.js +59 -0
  125. package/dist/crypto/claim-serializer.js.map +1 -0
  126. package/dist/crypto/sha256.d.ts +12 -0
  127. package/dist/crypto/sha256.js +40 -0
  128. package/dist/crypto/sha256.js.map +1 -0
  129. package/dist/crypto/static-key.d.ts +11 -0
  130. package/dist/crypto/static-key.js +60 -0
  131. package/dist/crypto/static-key.js.map +1 -0
  132. package/dist/crypto/types.d.ts +20 -0
  133. package/dist/crypto/types.js +8 -0
  134. package/dist/crypto/types.js.map +1 -0
  135. package/dist/datasource/trusted-data-source-registry.d.ts +51 -0
  136. package/dist/datasource/trusted-data-source-registry.js +57 -0
  137. package/dist/datasource/trusted-data-source-registry.js.map +1 -0
  138. package/dist/erasure/tombstone.d.ts +13 -0
  139. package/dist/erasure/tombstone.js +20 -0
  140. package/dist/erasure/tombstone.js.map +1 -0
  141. package/dist/evidence/evidence-backed-claim-creator.d.ts +48 -0
  142. package/dist/evidence/evidence-backed-claim-creator.js +107 -0
  143. package/dist/evidence/evidence-backed-claim-creator.js.map +1 -0
  144. package/dist/evidence/in-memory-raw-document-store.d.ts +26 -0
  145. package/dist/evidence/in-memory-raw-document-store.js +84 -0
  146. package/dist/evidence/in-memory-raw-document-store.js.map +1 -0
  147. package/dist/evidence/raw-document-store.d.ts +12 -0
  148. package/dist/evidence/raw-document-store.js +8 -0
  149. package/dist/evidence/raw-document-store.js.map +1 -0
  150. package/dist/evidence/source-evidence-validator.d.ts +4 -0
  151. package/dist/evidence/source-evidence-validator.js +14 -0
  152. package/dist/evidence/source-evidence-validator.js.map +1 -0
  153. package/dist/evidence/sqlite-raw-document-store.d.ts +19 -0
  154. package/dist/evidence/sqlite-raw-document-store.js +122 -0
  155. package/dist/evidence/sqlite-raw-document-store.js.map +1 -0
  156. package/dist/guardian/guardian-registry.d.ts +96 -0
  157. package/dist/guardian/guardian-registry.js +95 -0
  158. package/dist/guardian/guardian-registry.js.map +1 -0
  159. package/dist/index.d.ts +44 -0
  160. package/dist/index.js +72 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/observability/health.d.ts +12 -0
  163. package/dist/observability/health.js +16 -0
  164. package/dist/observability/health.js.map +1 -0
  165. package/dist/observability/logger.d.ts +21 -0
  166. package/dist/observability/logger.js +40 -0
  167. package/dist/observability/logger.js.map +1 -0
  168. package/dist/observability/metrics.d.ts +15 -0
  169. package/dist/observability/metrics.js +52 -0
  170. package/dist/observability/metrics.js.map +1 -0
  171. package/dist/persistence/backup.d.ts +24 -0
  172. package/dist/persistence/backup.js +251 -0
  173. package/dist/persistence/backup.js.map +1 -0
  174. package/dist/persistence/decryptability-scan.d.ts +10 -0
  175. package/dist/persistence/decryptability-scan.js +144 -0
  176. package/dist/persistence/decryptability-scan.js.map +1 -0
  177. package/dist/persistence/in-memory-unit-of-work.d.ts +11 -0
  178. package/dist/persistence/in-memory-unit-of-work.js +32 -0
  179. package/dist/persistence/in-memory-unit-of-work.js.map +1 -0
  180. package/dist/persistence/key-availability.d.ts +9 -0
  181. package/dist/persistence/key-availability.js +125 -0
  182. package/dist/persistence/key-availability.js.map +1 -0
  183. package/dist/persistence/sqlite/migrations.d.ts +9 -0
  184. package/dist/persistence/sqlite/migrations.js +535 -0
  185. package/dist/persistence/sqlite/migrations.js.map +1 -0
  186. package/dist/persistence/sqlite/schema.d.ts +10 -0
  187. package/dist/persistence/sqlite/schema.js +101 -0
  188. package/dist/persistence/sqlite/schema.js.map +1 -0
  189. package/dist/persistence/sqlite/sqlite-fact-store.d.ts +24 -0
  190. package/dist/persistence/sqlite/sqlite-fact-store.js +207 -0
  191. package/dist/persistence/sqlite/sqlite-fact-store.js.map +1 -0
  192. package/dist/persistence/sqlite/sqlite-source-registry.d.ts +17 -0
  193. package/dist/persistence/sqlite/sqlite-source-registry.js +132 -0
  194. package/dist/persistence/sqlite/sqlite-source-registry.js.map +1 -0
  195. package/dist/persistence/sqlite/sqlite-unit-of-work.d.ts +8 -0
  196. package/dist/persistence/sqlite/sqlite-unit-of-work.js +41 -0
  197. package/dist/persistence/sqlite/sqlite-unit-of-work.js.map +1 -0
  198. package/dist/persistence/sqlite/types.d.ts +24 -0
  199. package/dist/persistence/sqlite/types.js +28 -0
  200. package/dist/persistence/sqlite/types.js.map +1 -0
  201. package/dist/persistence/unit-of-work.d.ts +6 -0
  202. package/dist/persistence/unit-of-work.js +15 -0
  203. package/dist/persistence/unit-of-work.js.map +1 -0
  204. package/dist/proposal/accepted-claim-appender.d.ts +7 -0
  205. package/dist/proposal/accepted-claim-appender.js +16 -0
  206. package/dist/proposal/accepted-claim-appender.js.map +1 -0
  207. package/dist/proposal/in-memory-proposal-queue.d.ts +21 -0
  208. package/dist/proposal/in-memory-proposal-queue.js +218 -0
  209. package/dist/proposal/in-memory-proposal-queue.js.map +1 -0
  210. package/dist/proposal/policy-aware-proposal-queue.d.ts +23 -0
  211. package/dist/proposal/policy-aware-proposal-queue.js +162 -0
  212. package/dist/proposal/policy-aware-proposal-queue.js.map +1 -0
  213. package/dist/proposal/proposal-policy.d.ts +37 -0
  214. package/dist/proposal/proposal-policy.js +72 -0
  215. package/dist/proposal/proposal-policy.js.map +1 -0
  216. package/dist/proposal/proposal-queue.d.ts +13 -0
  217. package/dist/proposal/proposal-queue.js +15 -0
  218. package/dist/proposal/proposal-queue.js.map +1 -0
  219. package/dist/proposal/source-aware-claim-appender.d.ts +13 -0
  220. package/dist/proposal/source-aware-claim-appender.js +47 -0
  221. package/dist/proposal/source-aware-claim-appender.js.map +1 -0
  222. package/dist/proposal/sqlite-proposal-queue.d.ts +26 -0
  223. package/dist/proposal/sqlite-proposal-queue.js +282 -0
  224. package/dist/proposal/sqlite-proposal-queue.js.map +1 -0
  225. package/dist/resolution/resolve-claims.d.ts +4 -0
  226. package/dist/resolution/resolve-claims.js +101 -0
  227. package/dist/resolution/resolve-claims.js.map +1 -0
  228. package/dist/resolution/trust-profile.d.ts +12 -0
  229. package/dist/resolution/trust-profile.js +23 -0
  230. package/dist/resolution/trust-profile.js.map +1 -0
  231. package/dist/resolution/types.d.ts +15 -0
  232. package/dist/resolution/types.js +8 -0
  233. package/dist/resolution/types.js.map +1 -0
  234. package/dist/sdk/create-backend-integrated-life-api-for-test.d.ts +23 -0
  235. package/dist/sdk/create-backend-integrated-life-api-for-test.js +240 -0
  236. package/dist/sdk/create-backend-integrated-life-api-for-test.js.map +1 -0
  237. package/dist/sdk/create-life-api.d.ts +55 -0
  238. package/dist/sdk/create-life-api.js +251 -0
  239. package/dist/sdk/create-life-api.js.map +1 -0
  240. package/dist/sdk/create-sqlite-life-api.d.ts +33 -0
  241. package/dist/sdk/create-sqlite-life-api.js +654 -0
  242. package/dist/sdk/create-sqlite-life-api.js.map +1 -0
  243. package/dist/sdk/life-api.d.ts +27 -0
  244. package/dist/sdk/life-api.js +17 -0
  245. package/dist/sdk/life-api.js.map +1 -0
  246. package/dist/sdk/validation.d.ts +8 -0
  247. package/dist/sdk/validation.js +216 -0
  248. package/dist/sdk/validation.js.map +1 -0
  249. package/dist/source/in-memory-source-registry.d.ts +15 -0
  250. package/dist/source/in-memory-source-registry.js +104 -0
  251. package/dist/source/in-memory-source-registry.js.map +1 -0
  252. package/dist/source/source-aware-fact-store.d.ts +19 -0
  253. package/dist/source/source-aware-fact-store.js +40 -0
  254. package/dist/source/source-aware-fact-store.js.map +1 -0
  255. package/dist/source/source-kind-predicate-policy.d.ts +4 -0
  256. package/dist/source/source-kind-predicate-policy.js +62 -0
  257. package/dist/source/source-kind-predicate-policy.js.map +1 -0
  258. package/dist/source/source-registry.d.ts +11 -0
  259. package/dist/source/source-registry.js +12 -0
  260. package/dist/source/source-registry.js.map +1 -0
  261. package/dist/store/in-memory-fact-store.d.ts +25 -0
  262. package/dist/store/in-memory-fact-store.js +192 -0
  263. package/dist/store/in-memory-fact-store.js.map +1 -0
  264. package/dist/surface/context-query.d.ts +21 -0
  265. package/dist/surface/context-query.js +113 -0
  266. package/dist/surface/context-query.js.map +1 -0
  267. package/dist/surface/evidence-backed-context-query.d.ts +62 -0
  268. package/dist/surface/evidence-backed-context-query.js +240 -0
  269. package/dist/surface/evidence-backed-context-query.js.map +1 -0
  270. package/dist/types/access-context.d.ts +25 -0
  271. package/dist/types/access-context.js +6 -0
  272. package/dist/types/access-context.js.map +1 -0
  273. package/dist/types/claim.d.ts +48 -0
  274. package/dist/types/claim.js +5 -0
  275. package/dist/types/claim.js.map +1 -0
  276. package/dist/types/consent.d.ts +41 -0
  277. package/dist/types/consent.js +3 -0
  278. package/dist/types/consent.js.map +1 -0
  279. package/dist/types/crypto-boundary.d.ts +12 -0
  280. package/dist/types/crypto-boundary.js +15 -0
  281. package/dist/types/crypto-boundary.js.map +1 -0
  282. package/dist/types/evidence.d.ts +31 -0
  283. package/dist/types/evidence.js +8 -0
  284. package/dist/types/evidence.js.map +1 -0
  285. package/dist/types/fact-store.d.ts +24 -0
  286. package/dist/types/fact-store.js +12 -0
  287. package/dist/types/fact-store.js.map +1 -0
  288. package/dist/types/ids.d.ts +36 -0
  289. package/dist/types/ids.js +11 -0
  290. package/dist/types/ids.js.map +1 -0
  291. package/dist/types/proposal.d.ts +38 -0
  292. package/dist/types/proposal.js +7 -0
  293. package/dist/types/proposal.js.map +1 -0
  294. package/dist/types/source.d.ts +33 -0
  295. package/dist/types/source.js +6 -0
  296. package/dist/types/source.js.map +1 -0
  297. package/dist/types/trust.d.ts +24 -0
  298. package/dist/types/trust.js +5 -0
  299. package/dist/types/trust.js.map +1 -0
  300. package/dist/utilities/deep-freeze.d.ts +1 -0
  301. package/dist/utilities/deep-freeze.js +17 -0
  302. package/dist/utilities/deep-freeze.js.map +1 -0
  303. package/package.json +55 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-grant-resolver.js","sourceRoot":"","sources":["../../src/auth/sqlite-grant-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import Database from "better-sqlite3";
2
+ import type { TenantBoundary } from "./types.js";
3
+ export declare class SQLiteTenantBoundary implements TenantBoundary {
4
+ private readonly _stmt;
5
+ constructor(db: Database.Database);
6
+ assertOwnership(tenantId: string, personId: string): Promise<void>;
7
+ }
@@ -0,0 +1,41 @@
1
+ // SQLite-backed TenantBoundary — Production-02d-b.
2
+ // Do NOT export from src/index.ts.
3
+ //
4
+ // AUTH_SQLITE_TENANT_BOUNDARY_BACKEND_001: implements TenantBoundary with a
5
+ // Database.Database-backed read path; behaviorally identical to InMemoryTenantBoundary.
6
+ // AUTH_SQLITE_TENANT_MEMBERSHIP_STATUS_CHECKED_001: assertOwnership checks
7
+ // status === "active" at read time; suspended rows are denied with the same
8
+ // code as missing rows (AUTH_TENANT_OWNERSHIP_DENIED_001) — no enumeration leak.
9
+ // AUTH_SQLITE_TENANT_MEMBERSHIP_SCHEMA_001: constructor throws this code when
10
+ // auth_tenant_memberships table is absent — signals missing runMigrations call,
11
+ // not a runtime auth denial.
12
+ //
13
+ // Storage-failure behavior: SQLite errors propagate as thrown — never converted
14
+ // to AUTH_TENANT_OWNERSHIP_DENIED_001 (a real storage failure is not a denial).
15
+ const SCHEMA_CODE = "AUTH_SQLITE_TENANT_MEMBERSHIP_SCHEMA_001";
16
+ const DENIED_CODE = "AUTH_TENANT_OWNERSHIP_DENIED_001";
17
+ export class SQLiteTenantBoundary {
18
+ _stmt;
19
+ constructor(db) {
20
+ // AUTH_SQLITE_TENANT_MEMBERSHIP_SCHEMA_001: fail if migration has not run
21
+ const tablePresent = db
22
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='auth_tenant_memberships'")
23
+ .get() !== undefined;
24
+ if (!tablePresent) {
25
+ throw Object.assign(new Error(`[${SCHEMA_CODE}] auth_tenant_memberships table absent — call runMigrations before constructing SQLiteTenantBoundary`), { code: SCHEMA_CODE });
26
+ }
27
+ this._stmt = db.prepare("SELECT status FROM auth_tenant_memberships WHERE tenant_id = ? AND person_id = ?");
28
+ }
29
+ async assertOwnership(tenantId, personId) {
30
+ // AUTH_SQLITE_TENANT_MEMBERSHIP_STATUS_CHECKED_001
31
+ // SQLite errors propagate — they are NOT caught here.
32
+ const row = this._stmt.get(tenantId, personId);
33
+ // AUTH_TENANT_SUBJECT_NOT_FOUND_SAFE_001:
34
+ // Missing and suspended use the same error code — no enumeration leak.
35
+ if (row === undefined || row.status !== "active") {
36
+ throw Object.assign(new Error(`[${DENIED_CODE}] subject is not an active member of the tenant`), { code: DENIED_CODE });
37
+ }
38
+ // Resolves void on success.
39
+ }
40
+ }
41
+ //# sourceMappingURL=sqlite-tenant-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-tenant-boundary.js","sourceRoot":"","sources":["../../src/auth/sqlite-tenant-boundary.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,mCAAmC;AACnC,EAAE;AACF,4EAA4E;AAC5E,0FAA0F;AAC1F,2EAA2E;AAC3E,8EAA8E;AAC9E,mFAAmF;AACnF,8EAA8E;AAC9E,kFAAkF;AAClF,+BAA+B;AAC/B,EAAE;AACF,gFAAgF;AAChF,kFAAkF;AAKlF,MAAM,WAAW,GAAG,0CAA0C,CAAC;AAC/D,MAAM,WAAW,GAAG,kCAAkC,CAAC;AAEvD,MAAM,OAAO,oBAAoB;IACd,KAAK,CAAqB;IAE3C,YAAY,EAAqB;QAC/B,0EAA0E;QAC1E,MAAM,YAAY,GACf,EAAE;aACA,OAAO,CACN,sFAAsF,CACvF;aACA,GAAG,EAAmC,KAAK,SAAS,CAAC;QAE1D,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CACP,IAAI,WAAW,sGAAsG,CACtH,EACD,EAAE,IAAI,EAAE,WAAW,EAAE,CACtB,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,OAAO,CACrB,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,QAAgB,EAAE,QAAgB;QACtD,mDAAmD;QACnD,sDAAsD;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAEhC,CAAC;QAEd,0CAA0C;QAC1C,uEAAuE;QACvE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACjD,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CACP,IAAI,WAAW,iDAAiD,CACjE,EACD,EAAE,IAAI,EAAE,WAAW,EAAE,CACtB,CAAC;QACJ,CAAC;QACD,4BAA4B;IAC9B,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ export type JwtKeyStatus = "active" | "verifying-only" | "revoked";
2
+ export interface JwtKeyDescriptor {
3
+ readonly keyId: string;
4
+ readonly secret: Uint8Array;
5
+ readonly status: JwtKeyStatus;
6
+ readonly notBefore?: string;
7
+ readonly notAfter?: string;
8
+ }
9
+ export declare class StaticJwtKeyRing {
10
+ private readonly _keys;
11
+ constructor(keys: ReadonlyArray<JwtKeyDescriptor>);
12
+ resolveKey(keyId: string, nowMs: number): Buffer;
13
+ }
@@ -0,0 +1,73 @@
1
+ // src/auth/static-jwt-key-ring.ts
2
+ // TEST/DEV only — NOT exported from src/index.ts.
3
+ // Constructor-injected, in-memory JWT key ring for HS256 secret management.
4
+ // Analogous to StaticKeyProvider (src/crypto/static-key.ts) but for JWT HMAC secrets.
5
+ // JWT secrets are raw Uint8Array — distinct from CryptoKey objects used in at-rest encryption.
6
+ //
7
+ // AUTH_JWT_SECRET_SOURCE_INJECTED_001 ✅ Production-04-a (architecture invariant)
8
+ // AUTH_JWT_KEY_RING_VALIDATED_001 ✅ Production-04-a (construction-time postcondition)
9
+ // AUTH_JWT_KEY_ID_DUPLICATE_001 ✅ Production-04-a
10
+ // AUTH_JWT_ROTATION_GRACE_BOUNDED_001 ✅ Production-04-a
11
+ // AUTH_JWT_KEY_REVOKED_DENIED_001 ✅ Production-04-a
12
+ // AUTH_JWT_KEY_EXPIRED_DENIED_001 ✅ Production-04-a
13
+ import { throwErr, MIN_SECRET_BYTES } from "./jwt-core.js";
14
+ // ─── StaticJwtKeyRing ─────────────────────────────────────────────────────────
15
+ export class StaticJwtKeyRing {
16
+ _keys;
17
+ constructor(keys) {
18
+ const map = new Map();
19
+ for (const desc of keys) {
20
+ // Empty / missing keyId
21
+ if (typeof desc.keyId !== "string" || desc.keyId.length === 0) {
22
+ throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", "each key descriptor in the ring must have a non-empty keyId");
23
+ }
24
+ // Duplicate keyId (AUTH_JWT_KEY_ID_DUPLICATE_001)
25
+ if (map.has(desc.keyId)) {
26
+ throwErr("AUTH_JWT_KEY_ID_DUPLICATE_001", `duplicate keyId in ring: "${desc.keyId}"`);
27
+ }
28
+ // Secret length guard (reuses AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001)
29
+ if (desc.secret == null || desc.secret.length < MIN_SECRET_BYTES) {
30
+ throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", `key "${desc.keyId}" secret must be a Uint8Array of at least ${MIN_SECRET_BYTES} bytes`);
31
+ }
32
+ // Temporal string validation — parse at construction to fail fast
33
+ if (desc.notBefore !== undefined && isNaN(Date.parse(desc.notBefore))) {
34
+ throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", `key "${desc.keyId}" notBefore is not a valid ISO-8601 instant`);
35
+ }
36
+ if (desc.notAfter !== undefined && isNaN(Date.parse(desc.notAfter))) {
37
+ throwErr("AUTH_CREDENTIAL_KEY_CONFIG_INVALID_001", `key "${desc.keyId}" notAfter is not a valid ISO-8601 instant`);
38
+ }
39
+ // verifying-only must have notAfter to bound the grace window
40
+ // (AUTH_JWT_ROTATION_GRACE_BOUNDED_001)
41
+ if (desc.status === "verifying-only" && desc.notAfter === undefined) {
42
+ throwErr("AUTH_JWT_ROTATION_GRACE_BOUNDED_001", `verifying-only key "${desc.keyId}" must have notAfter to bound the grace window`);
43
+ }
44
+ map.set(desc.keyId, desc);
45
+ }
46
+ // AUTH_JWT_KEY_RING_VALIDATED_001: ring is internally consistent past this point
47
+ this._keys = map;
48
+ }
49
+ // Resolve a key for verification at the given instant (nowMs = epoch milliseconds).
50
+ // Throws on unknown, revoked, not-yet-active, or grace-window-closed keys.
51
+ resolveKey(keyId, nowMs) {
52
+ const desc = this._keys.get(keyId);
53
+ if (desc === undefined) {
54
+ throwErr("AUTH_CREDENTIAL_KEY_ID_UNKNOWN_001", `key "${keyId}" not found in ring`);
55
+ }
56
+ // Revoked: fail closed unconditionally — ignores token exp
57
+ // (AUTH_JWT_KEY_REVOKED_DENIED_001)
58
+ if (desc.status === "revoked") {
59
+ throwErr("AUTH_JWT_KEY_REVOKED_DENIED_001", `key "${keyId}" has been revoked`);
60
+ }
61
+ // notBefore: key not yet active (use parsed instant, not string comparison)
62
+ // (AUTH_JWT_KEY_REVOKED_DENIED_001 — pre-active treated as revoked/unavailable)
63
+ if (desc.notBefore !== undefined && nowMs < Date.parse(desc.notBefore)) {
64
+ throwErr("AUTH_JWT_KEY_REVOKED_DENIED_001", `key "${keyId}" is not yet active (notBefore)`);
65
+ }
66
+ // notAfter: grace window closed (AUTH_JWT_KEY_EXPIRED_DENIED_001)
67
+ if (desc.notAfter !== undefined && nowMs >= Date.parse(desc.notAfter)) {
68
+ throwErr("AUTH_JWT_KEY_EXPIRED_DENIED_001", `key "${keyId}" grace window has closed (notAfter)`);
69
+ }
70
+ return Buffer.from(desc.secret);
71
+ }
72
+ }
73
+ //# sourceMappingURL=static-jwt-key-ring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static-jwt-key-ring.js","sourceRoot":"","sources":["../../src/auth/static-jwt-key-ring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { PersonId } from "../types/ids.js";
2
+ import type { ErasureStatus } from "../erasure/tombstone.js";
3
+ import type { QueryContractsInput, ContextQueryResult } from "../surface/evidence-backed-context-query.js";
4
+ import type { LifeApi } from "../sdk/life-api.js";
5
+ import type { MintedContext } from "./types.js";
6
+ export declare class SubjectScopedLifeApi {
7
+ private readonly _api;
8
+ private readonly _minted;
9
+ constructor(_api: LifeApi, _minted: MintedContext);
10
+ requestErasure(subject: PersonId): Promise<void>;
11
+ getErasureStatus(subject: PersonId): Promise<ErasureStatus | undefined>;
12
+ queryContracts(input: QueryContractsInput): Promise<ContextQueryResult>;
13
+ }
14
+ export declare function createSubjectScopedLifeApi(api: LifeApi, minted: MintedContext): SubjectScopedLifeApi;
@@ -0,0 +1,51 @@
1
+ // AUTH_CONTEXT_SUBJECT_SCOPE_ENFORCED_001 — Production-01c
2
+ //
3
+ // Facade: binds a LifeApi instance + a MintedContext. No ctx parameter on any facade method —
4
+ // context is bound at construction time. assertAuthorizedForSubject() fires BEFORE any
5
+ // subject-bearing LifeApi call. Excluded methods are intentionally absent.
6
+ //
7
+ // SubjectScopedLifeApi does NOT implement LifeApi.
8
+ // Callers that need non-facade methods must call LifeApi directly with minted.context.
9
+ //
10
+ // PROPOSAL METHODS ARE EXCLUDED (Production-01c hardening):
11
+ // ProposalId-only is not subject-free proof — a Proposal's candidateClaims may contain
12
+ // subject-scoped data. getProposal/listProposals/acceptProposal/rejectProposal are deferred
13
+ // to Production-01d where explicit Proposal-scope enforcement will be implemented.
14
+ import { assertAuthorizedForSubject } from "./assert-authorized-for-subject.js";
15
+ export class SubjectScopedLifeApi {
16
+ _api;
17
+ _minted;
18
+ constructor(_api, _minted) {
19
+ this._api = _api;
20
+ this._minted = _minted;
21
+ }
22
+ // ── Subject-enforced ──────────────────────────────────────────────────────────
23
+ // assertAuthorizedForSubject() fires BEFORE any LifeApi call.
24
+ async requestErasure(subject) {
25
+ assertAuthorizedForSubject(this._minted, subject);
26
+ return this._api.requestErasure(this._minted.context, subject);
27
+ }
28
+ async getErasureStatus(subject) {
29
+ assertAuthorizedForSubject(this._minted, subject);
30
+ return this._api.getErasureStatus(this._minted.context, subject);
31
+ }
32
+ async queryContracts(input) {
33
+ if (input.selector.subject !== undefined) {
34
+ // Case A: subject present — enforce exact match against authorizedPersonId
35
+ assertAuthorizedForSubject(this._minted, input.selector.subject);
36
+ }
37
+ else if (this._minted.authorizedPersonId !== undefined) {
38
+ // Case B: person-scoped credential cannot execute cross-subject queries.
39
+ // A missing subject selector would return data across all subjects in the tenant.
40
+ throw Object.assign(new Error("AUTH_SUBJECT_SCOPE_VIOLATION_001: person-scoped credential may not execute " +
41
+ "a cross-subject query (input.selector.subject is absent but " +
42
+ "MintedContext.authorizedPersonId is set)"), { code: "AUTH_SUBJECT_SCOPE_VIOLATION_001" });
43
+ }
44
+ // Case C: subject absent + authorizedPersonId absent → tenant/system scope, no restriction
45
+ return this._api.queryContracts(this._minted.context, input);
46
+ }
47
+ }
48
+ export function createSubjectScopedLifeApi(api, minted) {
49
+ return new SubjectScopedLifeApi(api, minted);
50
+ }
51
+ //# sourceMappingURL=subject-scoped-life-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subject-scoped-life-api.js","sourceRoot":"","sources":["../../src/auth/subject-scoped-life-api.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,8FAA8F;AAC9F,uFAAuF;AACvF,2EAA2E;AAC3E,EAAE;AACF,mDAAmD;AACnD,uFAAuF;AACvF,EAAE;AACF,4DAA4D;AAC5D,uFAAuF;AACvF,4FAA4F;AAC5F,mFAAmF;AAQnF,OAAO,EAAE,0BAA0B,EAAE,MAAc,oCAAoC,CAAC;AAExF,MAAM,OAAO,oBAAoB;IAEZ;IACA;IAFnB,YACmB,IAAgB,EAChB,OAAsB;QADtB,SAAI,GAAJ,IAAI,CAAY;QAChB,YAAO,GAAP,OAAO,CAAe;IACtC,CAAC;IAEJ,iFAAiF;IACjF,8DAA8D;IAE9D,KAAK,CAAC,cAAc,CAAC,OAAiB;QACpC,0BAA0B,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,OAAkC,EAAE,OAAO,CAAC,CAAC;IAC5F,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,OAAiB;QACtC,0BAA0B,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAkC,EAAE,OAAO,CAAC,CAAC;IAC9F,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAA0B;QAC7C,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACzC,2EAA2E;YAC3E,0BAA0B,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACzD,yEAAyE;YACzE,kFAAkF;YAClF,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CACP,6EAA6E;gBAC7E,8DAA8D;gBAC9D,0CAA0C,CAC3C,EACD,EAAE,IAAI,EAAE,kCAAkC,EAAE,CAC7C,CAAC;QACJ,CAAC;QACD,2FAA2F;QAC3F,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;CAUF;AAED,MAAM,UAAU,0BAA0B,CACxC,GAAe,EACf,MAAqB;IAErB,OAAO,IAAI,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { AuthAdapter, AuthorizationPolicy, Clock, ContextMintingBoundary, MintedContext } from "./types.js";
2
+ import type { AccessContextIssuer } from "./access-context-issuer.js";
3
+ /** @remarks TEST/DEV ONLY — not for production use. */
4
+ export declare class TestContextMintingBoundary implements ContextMintingBoundary {
5
+ private readonly _opts;
6
+ constructor(_opts: {
7
+ readonly adapter: AuthAdapter;
8
+ readonly policy: AuthorizationPolicy;
9
+ readonly issuer: AccessContextIssuer;
10
+ readonly clock: Clock;
11
+ });
12
+ mint(credential: string, targetPersonId: string, requestedKind: "owner" | "agent" | "system" | "audit"): Promise<MintedContext>;
13
+ }
@@ -0,0 +1,74 @@
1
+ // TEST/DEV ONLY — AUTH_CONTEXT_MINTING_BOUNDARY_001 (first concrete implementation).
2
+ // Do NOT export from src/index.ts. Do NOT use in production.
3
+ // AUTH_TOKEN_SECRETS_NOT_AUDITED_001: raw credential never enters MintedContext or errors.
4
+ import { asPersonId, asGrantId, asISOTime } from "../types/ids.js";
5
+ /** @remarks TEST/DEV ONLY — not for production use. */
6
+ export class TestContextMintingBoundary {
7
+ _opts;
8
+ constructor(_opts) {
9
+ this._opts = _opts;
10
+ }
11
+ async mint(credential, targetPersonId, requestedKind) {
12
+ const { adapter, policy, issuer, clock } = this._opts;
13
+ // 1. Verify credential → VerifiedPrincipal (no raw credential stored beyond this call)
14
+ const principal = await adapter.verify(credential);
15
+ // 2. Expiry check before policy — AUTH_TOKEN_EXPIRY_CHECKED_001
16
+ if (principal.expiresAt <= clock.now()) {
17
+ throw Object.assign(new Error("AUTH_CREDENTIAL_EXPIRED_001: credential has expired"), { code: "AUTH_CREDENTIAL_EXPIRED_001" });
18
+ }
19
+ // 3. Resolve authorization decision
20
+ const decision = await policy.resolve(principal, targetPersonId);
21
+ // 4. Kind check — AUTH_DECISION_KIND_MISMATCH_001 (with specific sub-codes)
22
+ if (decision.kind !== requestedKind) {
23
+ // AUTH_AGENT_CANNOT_MINT_OWNER_001: specific invariant for this well-known violation
24
+ if (requestedKind === "owner" && principal.principalType === "agent") {
25
+ throw Object.assign(new Error("AUTH_AGENT_CANNOT_MINT_OWNER_001: an agent principal may not receive an OwnerContext"), { code: "AUTH_AGENT_CANNOT_MINT_OWNER_001" });
26
+ }
27
+ // AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001
28
+ if (requestedKind === "system" && principal.principalType !== "service") {
29
+ throw Object.assign(new Error("AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001: " +
30
+ "only service principals may mint a SystemProjectionContext"), { code: "AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001" });
31
+ }
32
+ throw Object.assign(new Error(`AUTH_DECISION_KIND_MISMATCH_001: policy resolved "${decision.kind}" ` +
33
+ `but "${requestedKind}" was requested`), { code: "AUTH_DECISION_KIND_MISMATCH_001" });
34
+ }
35
+ // 5. Mint context and build MintedContext — credential is NOT carried forward
36
+ const base = {
37
+ principalId: principal.principalId,
38
+ principalType: principal.principalType,
39
+ tenantId: principal.tenantId,
40
+ };
41
+ switch (decision.kind) {
42
+ case "owner": {
43
+ const ctx = issuer.mintOwner(asPersonId(decision.personId));
44
+ return {
45
+ ...base,
46
+ context: ctx,
47
+ authorizedPersonId: principal.authorizedPersonId ?? decision.personId,
48
+ };
49
+ }
50
+ case "agent": {
51
+ const ctx = issuer.mintAgent({
52
+ agentId: decision.agentId,
53
+ grantId: asGrantId(decision.grantId),
54
+ purpose: decision.purpose,
55
+ notAfter: asISOTime(decision.notAfter),
56
+ });
57
+ return {
58
+ ...base,
59
+ context: ctx,
60
+ authorizedGrantId: decision.grantId,
61
+ };
62
+ }
63
+ case "system": {
64
+ const ctx = issuer.mintSystemProjection();
65
+ return { ...base, context: ctx };
66
+ }
67
+ case "audit": {
68
+ const ctx = issuer.mintAudit(asPersonId(targetPersonId));
69
+ return { ...base, context: ctx };
70
+ }
71
+ }
72
+ }
73
+ }
74
+ //# sourceMappingURL=test-context-minting-boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-context-minting-boundary.js","sourceRoot":"","sources":["../../src/auth/test-context-minting-boundary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import type { AccessContext, PurposeTag } from "../types/access-context.js";
2
+ import type { PersonId } from "../types/ids.js";
3
+ export type PrincipalType = "user" | "agent" | "service" | "audit";
4
+ export interface VerifiedPrincipal {
5
+ readonly principalId: string;
6
+ readonly principalType: PrincipalType;
7
+ readonly tenantId: string;
8
+ readonly roles: ReadonlyArray<"owner" | "agent" | "system" | "audit">;
9
+ readonly grantIds: ReadonlyArray<string>;
10
+ readonly authorizedPersonId?: string;
11
+ readonly expiresAt: string;
12
+ readonly issuedAt: string;
13
+ }
14
+ export interface AuthAdapter {
15
+ verify(credential: string): Promise<VerifiedPrincipal>;
16
+ }
17
+ export type AuthorizationDecision = {
18
+ readonly kind: "owner";
19
+ readonly personId: string;
20
+ } | {
21
+ readonly kind: "agent";
22
+ readonly agentId: string;
23
+ readonly grantId: string;
24
+ readonly purpose: PurposeTag;
25
+ readonly notAfter: string;
26
+ } | {
27
+ readonly kind: "system";
28
+ readonly projection: string;
29
+ } | {
30
+ readonly kind: "audit";
31
+ };
32
+ export interface AuthorizationPolicy {
33
+ resolve(principal: VerifiedPrincipal, targetPersonId: string): Promise<AuthorizationDecision>;
34
+ }
35
+ export interface TenantBoundary {
36
+ assertOwnership(tenantId: string, personId: string): Promise<void>;
37
+ }
38
+ export interface GrantDescriptor {
39
+ readonly grantId: string;
40
+ readonly agentId: string;
41
+ readonly tenantId: string;
42
+ readonly notAfter: string;
43
+ readonly personId?: PersonId;
44
+ readonly purpose?: string;
45
+ }
46
+ export interface GrantResolver {
47
+ resolveActiveGrant(agentId: string, grantId: string, tenantId: string): Promise<GrantDescriptor | undefined>;
48
+ }
49
+ export interface Clock {
50
+ now(): string;
51
+ }
52
+ export interface MintedContext {
53
+ readonly context: AccessContext;
54
+ readonly principalId: string;
55
+ readonly principalType: PrincipalType;
56
+ readonly tenantId: string;
57
+ readonly authorizedPersonId?: string;
58
+ readonly authorizedGrantId?: string;
59
+ readonly guardianOf?: PersonId;
60
+ readonly guardianScopes?: ReadonlyArray<string>;
61
+ readonly declaredPurpose?: PurposeTag;
62
+ }
63
+ export interface MintOptions {
64
+ readonly declaredPurpose?: PurposeTag;
65
+ }
66
+ export interface ContextMintingBoundary {
67
+ mint(credential: string, targetPersonId: string, requestedKind: "owner" | "agent" | "system" | "audit", options?: MintOptions): Promise<MintedContext>;
68
+ }
69
+ export interface GuardianContextMintingBoundary extends ContextMintingBoundary {
70
+ /**
71
+ * Mint a guardian context on behalf of wardId.
72
+ * The returned context is an OwnerContext for wardId, marked with guardianOf = wardId.
73
+ * Denials throw AUTH_GUARDIAN_CONTEXT_MINT_DENIED_001 (opaque — internal reason not propagated).
74
+ * GUARDIAN_REGISTRY_NOT_CONFIGURED_001: no registry → throws that specific code.
75
+ */
76
+ mintGuardianContext(credential: string, wardId: string): Promise<MintedContext>;
77
+ }
@@ -0,0 +1,16 @@
1
+ // Auth boundary types — Production-01a.
2
+ //
3
+ // AUTH_CONTEXT_MINTING_BOUNDARY_001: ContextMintingBoundary is the only production
4
+ // path to a trusted AccessContext; raw AccessContextIssuer.mint*() must not be
5
+ // called outside this boundary in production deployments.
6
+ // AUTH_NO_PUBLIC_ISSUER_EXPORT_001: these interfaces are exported; the
7
+ // AccessContextIssuer class and FakeAuthAdapter are NOT.
8
+ // AUTH_HOST_ADAPTER_REQUIRED_001: production factory requires an AuthAdapter.
9
+ // AUTH_CONTEXT_SUBJECT_SCOPE_ENFORCED_001: MintedContext carries authorizedPersonId /
10
+ // authorizedGrantId so call sites can enforce subject scope beyond WeakSet trust.
11
+ // AUTH_CONTEXT_INSTANCE_BOUND_001 (WeakSet) prevents cross-instance replay only —
12
+ // cross-subject misuse within the same instance requires authorizedPersonId enforcement.
13
+ // AUTH_SERVICE_PRINCIPAL_REQUIRED_FOR_SYSTEM_CONTEXT_001: principalType "service"
14
+ // is the only allowed source for SystemProjectionContext minting.
15
+ export {};
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,mFAAmF;AACnF,iFAAiF;AACjF,4DAA4D;AAC5D,uEAAuE;AACvE,2DAA2D;AAC3D,8EAA8E;AAC9E,sFAAsF;AACtF,oFAAoF;AACpF,oFAAoF;AACpF,2FAA2F;AAC3F,kFAAkF;AAClF,oEAAoE"}
@@ -0,0 +1,43 @@
1
+ import type { Database } from "better-sqlite3";
2
+ export interface GrantSummary {
3
+ readonly grantId: string;
4
+ readonly agentId: string;
5
+ readonly status: string;
6
+ readonly purpose?: string;
7
+ readonly notBefore?: string;
8
+ readonly notAfter: string;
9
+ readonly createdAt: string;
10
+ readonly updatedAt: string;
11
+ }
12
+ export interface ProposalSummary {
13
+ readonly proposalId: string;
14
+ readonly status: string;
15
+ readonly proposedByAgent: string;
16
+ readonly underGrant: string;
17
+ readonly createdAt: string;
18
+ readonly updatedAt: string;
19
+ readonly decidedAt?: string;
20
+ }
21
+ export interface AuditEventSummary {
22
+ readonly eventId: string;
23
+ readonly recordedAt: string;
24
+ readonly actor: string;
25
+ readonly decision: string;
26
+ readonly reasonCode: string;
27
+ readonly grantId?: string;
28
+ readonly actingAsGuardian?: boolean;
29
+ readonly wardId?: string;
30
+ }
31
+ export interface SubjectDataReport {
32
+ readonly generatedAt: string;
33
+ readonly subjectId: string;
34
+ readonly schemaVersion: number;
35
+ readonly grants: GrantSummary[];
36
+ readonly proposals: ProposalSummary[];
37
+ readonly auditEvents: AuditEventSummary[];
38
+ readonly dataIntegrityHash: string;
39
+ }
40
+ export interface SubjectDataReportOptions {
41
+ readonly now: string;
42
+ }
43
+ export declare function generateSubjectDataReport(db: Database, personId: string, opts: SubjectDataReportOptions): SubjectDataReport;
@@ -0,0 +1,155 @@
1
+ // DSGVO Art. 15 (Auskunftsrecht) + Art. 20 (Datenportabilität) — Subject Data Report.
2
+ //
3
+ // SUBJECT_DATA_REPORT_GDPR_ART15_001: generateSubjectDataReport() produces a complete,
4
+ // structured account of all data held about a personId: active + expired grants,
5
+ // proposals linked to those grants, and audit events linked to those grants.
6
+ // SUBJECT_DATA_REPORT_INTEGRITY_HASH_001: dataIntegrityHash = SHA-256 over the canonical
7
+ // JSON of the report (fields sorted, hash field excluded) — makes the report tamper-evident
8
+ // and admissible as evidence. Hosts wishing formal notarisation must additionally timestamp
9
+ // the hash with a qualified TSA.
10
+ // SUBJECT_DATA_REPORT_INCLUDES_EXPIRED_GRANTS_001: all grants (status "active" + "revoked" +
11
+ // "expired") are included — GDPR right of access covers historical data.
12
+ // SUBJECT_DATA_REPORT_NO_PLAINTEXT_PAYLOAD_001: proposal encrypted payloads are NOT included.
13
+ // The report records proposal metadata (id, status, agent, grant, timestamps) only —
14
+ // PROPOSAL_QUEUE_SCHEMA_ENCRYPTED_PAYLOAD_001 is respected; the key material required for
15
+ // decryption is not available to this layer.
16
+ // SUBJECT_DATA_REPORT_AUDIT_VIA_GRANT_JOIN_001: audit events are linked to the subject via
17
+ // their grant_id → auth_grants.grant_id → auth_grants.person_id join. Events without a
18
+ // grant_id are per-subject owner actions (actor matches "user:<principalId>") included via
19
+ // the owner-event path. Events with an unknown/cross-subject grant_id are excluded.
20
+ // SUBJECT_DATA_REPORT_GUARDIAN_EVENTS_INCLUDED_001: audit events with acting_as_guardian=1
21
+ // AND ward_id = personId are included — they represent actions taken on behalf of this person.
22
+ // SUBJECT_DATA_REPORT_OWNER_ONLY_001: callers must enforce that only the subject (owner
23
+ // context or authorised guardian) may call this function. The function itself does NOT
24
+ // enforce caller identity — enforcement is the host's responsibility.
25
+ import { sha256hexSync } from "../crypto/sha256.js";
26
+ // ─── Canonical JSON (for integrity hash) ─────────────────────────────────────
27
+ // SUBJECT_DATA_REPORT_INTEGRITY_HASH_001: sorted keys, no undefined/null values,
28
+ // dataIntegrityHash field excluded. The sort is deterministic across V8 versions
29
+ // because we sort recursively using Array.from(Object.keys()).sort().
30
+ function canonicalJson(value) {
31
+ if (value === null || value === undefined)
32
+ return "null";
33
+ if (typeof value !== "object" && !Array.isArray(value))
34
+ return JSON.stringify(value);
35
+ if (Array.isArray(value)) {
36
+ return "[" + value.map(canonicalJson).join(",") + "]";
37
+ }
38
+ const obj = value;
39
+ const keys = Object.keys(obj).sort();
40
+ const pairs = keys
41
+ .filter(k => obj[k] !== undefined)
42
+ .map(k => JSON.stringify(k) + ":" + canonicalJson(obj[k]));
43
+ return "{" + pairs.join(",") + "}";
44
+ }
45
+ // ─── generateSubjectDataReport ────────────────────────────────────────────────
46
+ export function generateSubjectDataReport(db, personId, opts) {
47
+ // 1. Grants — all statuses (SUBJECT_DATA_REPORT_INCLUDES_EXPIRED_GRANTS_001)
48
+ const grantRows = db.prepare(`SELECT grant_id, agent_id, status, not_before, not_after, created_at, updated_at
49
+ FROM auth_grants
50
+ WHERE person_id = ?
51
+ ORDER BY created_at ASC`).all(personId);
52
+ const grants = grantRows.map(r => {
53
+ const g = {
54
+ grantId: r.grant_id,
55
+ agentId: r.agent_id,
56
+ status: r.status,
57
+ notAfter: r.not_after,
58
+ createdAt: r.created_at,
59
+ updatedAt: r.updated_at,
60
+ };
61
+ const withOptionals = { ...g };
62
+ if (r.not_before !== null && r.not_before !== undefined) {
63
+ withOptionals["notBefore"] = r.not_before;
64
+ }
65
+ return withOptionals;
66
+ });
67
+ const grantIds = grantRows.map(r => r.grant_id);
68
+ // 2. Proposals — linked via grants (SUBJECT_DATA_REPORT_NO_PLAINTEXT_PAYLOAD_001)
69
+ let proposals = [];
70
+ if (grantIds.length > 0) {
71
+ const placeholders = grantIds.map(() => "?").join(",");
72
+ const proposalRows = db.prepare(`SELECT proposal_id, status, proposed_by_agent, under_grant,
73
+ created_at, updated_at, decided_at
74
+ FROM proposals
75
+ WHERE under_grant IN (${placeholders})
76
+ ORDER BY created_at ASC`).all(...grantIds);
77
+ proposals = proposalRows.map(r => {
78
+ const p = {
79
+ proposalId: r.proposal_id,
80
+ status: r.status,
81
+ proposedByAgent: r.proposed_by_agent,
82
+ underGrant: r.under_grant,
83
+ createdAt: r.created_at,
84
+ updatedAt: r.updated_at,
85
+ };
86
+ if (r.decided_at !== null && r.decided_at !== undefined) {
87
+ p["decidedAt"] = r.decided_at;
88
+ }
89
+ return p;
90
+ });
91
+ }
92
+ // 3. Audit events — via grant join + guardian ward events
93
+ // (SUBJECT_DATA_REPORT_AUDIT_VIA_GRANT_JOIN_001 + SUBJECT_DATA_REPORT_GUARDIAN_EVENTS_INCLUDED_001)
94
+ let auditEvents = [];
95
+ {
96
+ const parts = [];
97
+ const params = [];
98
+ if (grantIds.length > 0) {
99
+ const placeholders = grantIds.map(() => "?").join(",");
100
+ parts.push(`SELECT id, recorded_at, actor, decision, reason_code, grant_id,
101
+ acting_as_guardian, ward_id
102
+ FROM audit_events
103
+ WHERE grant_id IN (${placeholders})`);
104
+ params.push(...grantIds);
105
+ }
106
+ // Guardian events: acting on behalf of this person as ward
107
+ parts.push(`SELECT id, recorded_at, actor, decision, reason_code, grant_id,
108
+ acting_as_guardian, ward_id
109
+ FROM audit_events
110
+ WHERE acting_as_guardian = 1 AND ward_id = ?`);
111
+ params.push(personId);
112
+ if (parts.length > 0) {
113
+ const sql = parts.join(" UNION ") + " ORDER BY recorded_at ASC";
114
+ const rows = db.prepare(sql).all(...params);
115
+ // Deduplicate by id (a row may appear in both queries)
116
+ const seen = new Set();
117
+ auditEvents = rows
118
+ .filter(r => {
119
+ if (seen.has(r.id))
120
+ return false;
121
+ seen.add(r.id);
122
+ return true;
123
+ })
124
+ .map(r => {
125
+ const ev = {
126
+ eventId: r.id,
127
+ recordedAt: r.recorded_at,
128
+ actor: r.actor,
129
+ decision: r.decision,
130
+ reasonCode: r.reason_code,
131
+ };
132
+ if (r.grant_id !== null && r.grant_id !== undefined)
133
+ ev["grantId"] = r.grant_id;
134
+ if (r.acting_as_guardian === 1)
135
+ ev["actingAsGuardian"] = true;
136
+ if (r.ward_id !== null && r.ward_id !== undefined)
137
+ ev["wardId"] = r.ward_id;
138
+ return ev;
139
+ });
140
+ }
141
+ }
142
+ // 4. Assemble report without hash
143
+ const reportWithoutHash = {
144
+ generatedAt: opts.now,
145
+ subjectId: personId,
146
+ schemaVersion: 10,
147
+ grants,
148
+ proposals,
149
+ auditEvents,
150
+ };
151
+ // SUBJECT_DATA_REPORT_INTEGRITY_HASH_001: SHA-256 over canonical JSON
152
+ const dataIntegrityHash = sha256hexSync(Buffer.from(canonicalJson(reportWithoutHash), "utf8"));
153
+ return { ...reportWithoutHash, dataIntegrityHash };
154
+ }
155
+ //# sourceMappingURL=subject-data-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subject-data-report.js","sourceRoot":"","sources":["../../src/compliance/subject-data-report.ts"],"names":[],"mappings":"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"}