@aster-rpc/aster 0.1.2

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 (233) hide show
  1. package/dist/capabilities.d.ts +26 -0
  2. package/dist/capabilities.d.ts.map +1 -0
  3. package/dist/capabilities.js +29 -0
  4. package/dist/capabilities.js.map +1 -0
  5. package/dist/client.d.ts +65 -0
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +108 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/codec.d.ts +156 -0
  10. package/dist/codec.d.ts.map +1 -0
  11. package/dist/codec.js +477 -0
  12. package/dist/codec.js.map +1 -0
  13. package/dist/config.d.ts +102 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +454 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/contract/identity.d.ts +115 -0
  18. package/dist/contract/identity.d.ts.map +1 -0
  19. package/dist/contract/identity.js +188 -0
  20. package/dist/contract/identity.js.map +1 -0
  21. package/dist/contract/manifest.d.ts +77 -0
  22. package/dist/contract/manifest.d.ts.map +1 -0
  23. package/dist/contract/manifest.js +127 -0
  24. package/dist/contract/manifest.js.map +1 -0
  25. package/dist/contract/publication.d.ts +71 -0
  26. package/dist/contract/publication.d.ts.map +1 -0
  27. package/dist/contract/publication.js +85 -0
  28. package/dist/contract/publication.js.map +1 -0
  29. package/dist/decorators.d.ts +139 -0
  30. package/dist/decorators.d.ts.map +1 -0
  31. package/dist/decorators.js +175 -0
  32. package/dist/decorators.js.map +1 -0
  33. package/dist/dynamic.d.ts +61 -0
  34. package/dist/dynamic.d.ts.map +1 -0
  35. package/dist/dynamic.js +147 -0
  36. package/dist/dynamic.js.map +1 -0
  37. package/dist/framing.d.ts +74 -0
  38. package/dist/framing.d.ts.map +1 -0
  39. package/dist/framing.js +162 -0
  40. package/dist/framing.js.map +1 -0
  41. package/dist/health.d.ts +127 -0
  42. package/dist/health.d.ts.map +1 -0
  43. package/dist/health.js +236 -0
  44. package/dist/health.js.map +1 -0
  45. package/dist/index.d.ts +67 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +101 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/interceptors/audit.d.ts +25 -0
  50. package/dist/interceptors/audit.d.ts.map +1 -0
  51. package/dist/interceptors/audit.js +46 -0
  52. package/dist/interceptors/audit.js.map +1 -0
  53. package/dist/interceptors/auth.d.ts +13 -0
  54. package/dist/interceptors/auth.d.ts.map +1 -0
  55. package/dist/interceptors/auth.js +34 -0
  56. package/dist/interceptors/auth.js.map +1 -0
  57. package/dist/interceptors/base.d.ts +74 -0
  58. package/dist/interceptors/base.d.ts.map +1 -0
  59. package/dist/interceptors/base.js +103 -0
  60. package/dist/interceptors/base.js.map +1 -0
  61. package/dist/interceptors/capability.d.ts +16 -0
  62. package/dist/interceptors/capability.d.ts.map +1 -0
  63. package/dist/interceptors/capability.js +63 -0
  64. package/dist/interceptors/capability.js.map +1 -0
  65. package/dist/interceptors/circuit-breaker.d.ts +40 -0
  66. package/dist/interceptors/circuit-breaker.d.ts.map +1 -0
  67. package/dist/interceptors/circuit-breaker.js +91 -0
  68. package/dist/interceptors/circuit-breaker.js.map +1 -0
  69. package/dist/interceptors/compression.d.ts +11 -0
  70. package/dist/interceptors/compression.d.ts.map +1 -0
  71. package/dist/interceptors/compression.js +12 -0
  72. package/dist/interceptors/compression.js.map +1 -0
  73. package/dist/interceptors/deadline.d.ts +12 -0
  74. package/dist/interceptors/deadline.d.ts.map +1 -0
  75. package/dist/interceptors/deadline.js +28 -0
  76. package/dist/interceptors/deadline.js.map +1 -0
  77. package/dist/interceptors/metrics.d.ts +43 -0
  78. package/dist/interceptors/metrics.d.ts.map +1 -0
  79. package/dist/interceptors/metrics.js +132 -0
  80. package/dist/interceptors/metrics.js.map +1 -0
  81. package/dist/interceptors/rate-limit.d.ts +24 -0
  82. package/dist/interceptors/rate-limit.d.ts.map +1 -0
  83. package/dist/interceptors/rate-limit.js +84 -0
  84. package/dist/interceptors/rate-limit.js.map +1 -0
  85. package/dist/interceptors/retry.d.ts +25 -0
  86. package/dist/interceptors/retry.d.ts.map +1 -0
  87. package/dist/interceptors/retry.js +55 -0
  88. package/dist/interceptors/retry.js.map +1 -0
  89. package/dist/limits.d.ts +77 -0
  90. package/dist/limits.d.ts.map +1 -0
  91. package/dist/limits.js +137 -0
  92. package/dist/limits.js.map +1 -0
  93. package/dist/logging.d.ts +40 -0
  94. package/dist/logging.d.ts.map +1 -0
  95. package/dist/logging.js +92 -0
  96. package/dist/logging.js.map +1 -0
  97. package/dist/metadata.d.ts +14 -0
  98. package/dist/metadata.d.ts.map +1 -0
  99. package/dist/metadata.js +68 -0
  100. package/dist/metadata.js.map +1 -0
  101. package/dist/metrics.d.ts +40 -0
  102. package/dist/metrics.d.ts.map +1 -0
  103. package/dist/metrics.js +92 -0
  104. package/dist/metrics.js.map +1 -0
  105. package/dist/peer-store.d.ts +53 -0
  106. package/dist/peer-store.d.ts.map +1 -0
  107. package/dist/peer-store.js +105 -0
  108. package/dist/peer-store.js.map +1 -0
  109. package/dist/protocol.d.ts +44 -0
  110. package/dist/protocol.d.ts.map +1 -0
  111. package/dist/protocol.js +59 -0
  112. package/dist/protocol.js.map +1 -0
  113. package/dist/registration.d.ts +81 -0
  114. package/dist/registration.d.ts.map +1 -0
  115. package/dist/registration.js +161 -0
  116. package/dist/registration.js.map +1 -0
  117. package/dist/registry/acl.d.ts +57 -0
  118. package/dist/registry/acl.d.ts.map +1 -0
  119. package/dist/registry/acl.js +104 -0
  120. package/dist/registry/acl.js.map +1 -0
  121. package/dist/registry/client.d.ts +70 -0
  122. package/dist/registry/client.d.ts.map +1 -0
  123. package/dist/registry/client.js +115 -0
  124. package/dist/registry/client.js.map +1 -0
  125. package/dist/registry/gossip.d.ts +43 -0
  126. package/dist/registry/gossip.d.ts.map +1 -0
  127. package/dist/registry/gossip.js +102 -0
  128. package/dist/registry/gossip.js.map +1 -0
  129. package/dist/registry/keys.d.ts +25 -0
  130. package/dist/registry/keys.d.ts.map +1 -0
  131. package/dist/registry/keys.js +47 -0
  132. package/dist/registry/keys.js.map +1 -0
  133. package/dist/registry/models.d.ts +80 -0
  134. package/dist/registry/models.d.ts.map +1 -0
  135. package/dist/registry/models.js +35 -0
  136. package/dist/registry/models.js.map +1 -0
  137. package/dist/registry/publisher.d.ts +65 -0
  138. package/dist/registry/publisher.d.ts.map +1 -0
  139. package/dist/registry/publisher.js +164 -0
  140. package/dist/registry/publisher.js.map +1 -0
  141. package/dist/runtime.d.ts +267 -0
  142. package/dist/runtime.d.ts.map +1 -0
  143. package/dist/runtime.js +1366 -0
  144. package/dist/runtime.js.map +1 -0
  145. package/dist/server.d.ts +100 -0
  146. package/dist/server.d.ts.map +1 -0
  147. package/dist/server.js +511 -0
  148. package/dist/server.js.map +1 -0
  149. package/dist/service.d.ts +72 -0
  150. package/dist/service.d.ts.map +1 -0
  151. package/dist/service.js +98 -0
  152. package/dist/service.js.map +1 -0
  153. package/dist/session.d.ts +64 -0
  154. package/dist/session.d.ts.map +1 -0
  155. package/dist/session.js +350 -0
  156. package/dist/session.js.map +1 -0
  157. package/dist/status.d.ts +113 -0
  158. package/dist/status.d.ts.map +1 -0
  159. package/dist/status.js +206 -0
  160. package/dist/status.js.map +1 -0
  161. package/dist/transport/base.d.ts +46 -0
  162. package/dist/transport/base.d.ts.map +1 -0
  163. package/dist/transport/base.js +10 -0
  164. package/dist/transport/base.js.map +1 -0
  165. package/dist/transport/iroh.d.ts +45 -0
  166. package/dist/transport/iroh.d.ts.map +1 -0
  167. package/dist/transport/iroh.js +225 -0
  168. package/dist/transport/iroh.js.map +1 -0
  169. package/dist/transport/local.d.ts +48 -0
  170. package/dist/transport/local.d.ts.map +1 -0
  171. package/dist/transport/local.js +139 -0
  172. package/dist/transport/local.js.map +1 -0
  173. package/dist/trust/admission.d.ts +60 -0
  174. package/dist/trust/admission.d.ts.map +1 -0
  175. package/dist/trust/admission.js +149 -0
  176. package/dist/trust/admission.js.map +1 -0
  177. package/dist/trust/bootstrap.d.ts +109 -0
  178. package/dist/trust/bootstrap.d.ts.map +1 -0
  179. package/dist/trust/bootstrap.js +311 -0
  180. package/dist/trust/bootstrap.js.map +1 -0
  181. package/dist/trust/clock.d.ts +93 -0
  182. package/dist/trust/clock.d.ts.map +1 -0
  183. package/dist/trust/clock.js +154 -0
  184. package/dist/trust/clock.js.map +1 -0
  185. package/dist/trust/consumer.d.ts +139 -0
  186. package/dist/trust/consumer.d.ts.map +1 -0
  187. package/dist/trust/consumer.js +323 -0
  188. package/dist/trust/consumer.js.map +1 -0
  189. package/dist/trust/credentials.d.ts +98 -0
  190. package/dist/trust/credentials.d.ts.map +1 -0
  191. package/dist/trust/credentials.js +250 -0
  192. package/dist/trust/credentials.js.map +1 -0
  193. package/dist/trust/delegated.d.ts +118 -0
  194. package/dist/trust/delegated.d.ts.map +1 -0
  195. package/dist/trust/delegated.js +292 -0
  196. package/dist/trust/delegated.js.map +1 -0
  197. package/dist/trust/gossip.d.ts +146 -0
  198. package/dist/trust/gossip.d.ts.map +1 -0
  199. package/dist/trust/gossip.js +334 -0
  200. package/dist/trust/gossip.js.map +1 -0
  201. package/dist/trust/hooks.d.ts +84 -0
  202. package/dist/trust/hooks.d.ts.map +1 -0
  203. package/dist/trust/hooks.js +125 -0
  204. package/dist/trust/hooks.js.map +1 -0
  205. package/dist/trust/iid.d.ts +65 -0
  206. package/dist/trust/iid.d.ts.map +1 -0
  207. package/dist/trust/iid.js +104 -0
  208. package/dist/trust/iid.js.map +1 -0
  209. package/dist/trust/mesh.d.ts +43 -0
  210. package/dist/trust/mesh.d.ts.map +1 -0
  211. package/dist/trust/mesh.js +105 -0
  212. package/dist/trust/mesh.js.map +1 -0
  213. package/dist/trust/nonce.d.ts +39 -0
  214. package/dist/trust/nonce.d.ts.map +1 -0
  215. package/dist/trust/nonce.js +46 -0
  216. package/dist/trust/nonce.js.map +1 -0
  217. package/dist/trust/producer.d.ts +80 -0
  218. package/dist/trust/producer.d.ts.map +1 -0
  219. package/dist/trust/producer.js +151 -0
  220. package/dist/trust/producer.js.map +1 -0
  221. package/dist/trust/rcan.d.ts +29 -0
  222. package/dist/trust/rcan.d.ts.map +1 -0
  223. package/dist/trust/rcan.js +57 -0
  224. package/dist/trust/rcan.js.map +1 -0
  225. package/dist/types.d.ts +57 -0
  226. package/dist/types.d.ts.map +1 -0
  227. package/dist/types.js +50 -0
  228. package/dist/types.js.map +1 -0
  229. package/dist/xlang.d.ts +26 -0
  230. package/dist/xlang.d.ts.map +1 -0
  231. package/dist/xlang.js +55 -0
  232. package/dist/xlang.js.map +1 -0
  233. package/package.json +59 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * LocalTransport — in-process transport for testing.
3
+ *
4
+ * Executes RPC calls directly against a ServiceRegistry without
5
+ * network I/O or serialization. Useful for unit testing service logic.
6
+ */
7
+ import { StatusCode, RpcError } from '../status.js';
8
+ import { RpcPattern } from '../types.js';
9
+ /**
10
+ * In-memory receive stream for testing.
11
+ * Wraps a pre-filled buffer and exposes a read() interface.
12
+ */
13
+ export class MemRecvStream {
14
+ data;
15
+ pos = 0;
16
+ constructor(data) {
17
+ this.data = data;
18
+ }
19
+ /**
20
+ * Read up to n bytes. Returns null at EOF.
21
+ */
22
+ read(n) {
23
+ if (this.pos >= this.data.byteLength)
24
+ return null;
25
+ const slice = this.data.subarray(this.pos, this.pos + n);
26
+ this.pos += slice.byteLength;
27
+ return slice;
28
+ }
29
+ async readExact(n) {
30
+ if (this.pos + n > this.data.byteLength)
31
+ throw new Error('EOF');
32
+ const slice = this.data.subarray(this.pos, this.pos + n);
33
+ this.pos += n;
34
+ return slice;
35
+ }
36
+ }
37
+ /**
38
+ * In-process transport that dispatches directly to registered services.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const registry = new ServiceRegistry();
43
+ * registry.register(new EchoService());
44
+ * const transport = new LocalTransport(registry);
45
+ *
46
+ * const result = await transport.unary("Echo", "echo", { message: "hi" });
47
+ * ```
48
+ */
49
+ export class LocalTransport {
50
+ registry;
51
+ constructor(registry) {
52
+ this.registry = registry;
53
+ }
54
+ async unary(service, method, request, _opts) {
55
+ const [svcInfo, methodInfo] = this.resolve(service, method);
56
+ this.assertPattern(methodInfo, RpcPattern.UNARY);
57
+ const handler = methodInfo.handler;
58
+ return handler.call(svcInfo.instance, request);
59
+ }
60
+ async *serverStream(service, method, request, _opts) {
61
+ const [svcInfo, methodInfo] = this.resolve(service, method);
62
+ this.assertPattern(methodInfo, RpcPattern.SERVER_STREAM);
63
+ const handler = methodInfo.handler;
64
+ const gen = handler.call(svcInfo.instance, request);
65
+ yield* gen;
66
+ }
67
+ async clientStream(service, method, requests, _opts) {
68
+ const [svcInfo, methodInfo] = this.resolve(service, method);
69
+ this.assertPattern(methodInfo, RpcPattern.CLIENT_STREAM);
70
+ const handler = methodInfo.handler;
71
+ return handler.call(svcInfo.instance, requests);
72
+ }
73
+ bidiStream(service, method, _opts) {
74
+ const [svcInfo, methodInfo] = this.resolve(service, method);
75
+ this.assertPattern(methodInfo, RpcPattern.BIDI_STREAM);
76
+ // Create a simple in-process bidi channel
77
+ const requestQueue = [];
78
+ let requestResolve = null;
79
+ let sendClosed = false;
80
+ const handler = methodInfo.handler;
81
+ // Request iterable that the handler reads from
82
+ const requestIterable = {
83
+ [Symbol.asyncIterator]() {
84
+ return {
85
+ async next() {
86
+ while (requestQueue.length === 0 && !sendClosed) {
87
+ await new Promise((r) => { requestResolve = r; });
88
+ }
89
+ if (requestQueue.length > 0) {
90
+ return { value: requestQueue.shift(), done: false };
91
+ }
92
+ return { value: undefined, done: true };
93
+ },
94
+ };
95
+ },
96
+ };
97
+ // Start the handler
98
+ const responseGen = handler.call(svcInfo.instance, requestIterable);
99
+ const channel = {
100
+ async send(msg) {
101
+ requestQueue.push(msg);
102
+ requestResolve?.();
103
+ requestResolve = null;
104
+ },
105
+ async *[Symbol.asyncIterator]() {
106
+ yield* responseGen;
107
+ },
108
+ async close() {
109
+ sendClosed = true;
110
+ requestResolve?.();
111
+ requestResolve = null;
112
+ },
113
+ async waitForTrailer() {
114
+ return [StatusCode.OK, ''];
115
+ },
116
+ };
117
+ return channel;
118
+ }
119
+ async close() {
120
+ // Nothing to close for in-process transport
121
+ }
122
+ /** The remote endpoint ID (always 'local' for in-process transport). */
123
+ get remoteId() {
124
+ return 'local';
125
+ }
126
+ resolve(service, method) {
127
+ const result = this.registry.lookupMethod(service, method);
128
+ if (!result) {
129
+ throw new RpcError(StatusCode.NOT_FOUND, `${service}/${method} not found`);
130
+ }
131
+ return result;
132
+ }
133
+ assertPattern(methodInfo, expected) {
134
+ if (methodInfo.pattern !== expected) {
135
+ throw new RpcError(StatusCode.UNIMPLEMENTED, `${methodInfo.name} is ${methodInfo.pattern}, not ${expected}`);
136
+ }
137
+ }
138
+ }
139
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.js","sourceRoot":"","sources":["../../src/transport/local.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Admission gates for consumer/producer authorization.
3
+ *
4
+ * Spec reference: Aster-trust-spec.md §2.4, §3.2
5
+ *
6
+ * Two-phase admission:
7
+ * 1. checkOffline — signature, expiry, endpoint ID binding, nonce
8
+ * 2. checkRuntime — IID verification (cloud identity)
9
+ *
10
+ * admit() orchestrates both. Refusal reasons are logged internally —
11
+ * never sent to peer (oracle protection).
12
+ */
13
+ import type { EnrollmentCredential, ConsumerEnrollmentCredential } from './credentials.js';
14
+ import type { NonceStore } from './nonce.js';
15
+ import { type IIDBackend } from './iid.js';
16
+ /** Result of an admission check. */
17
+ export interface AdmissionResult {
18
+ admitted: boolean;
19
+ attributes?: Record<string, string>;
20
+ /** Internal only — never send to peer. */
21
+ reason?: string;
22
+ }
23
+ /**
24
+ * Offline admission checks — no network calls.
25
+ *
26
+ * 1. Structural validity (nonce length, policy-vs-OTT constraints)
27
+ * 2. Signature valid against rootPubkey
28
+ * 3. expiresAt > now
29
+ * 4. Endpoint ID match (always for EnrollmentCredential; if set for Consumer)
30
+ * 5. OTT nonce not already consumed
31
+ */
32
+ export declare function checkOffline(cred: EnrollmentCredential | ConsumerEnrollmentCredential, peerEndpointId: string, nonceStore?: NonceStore): Promise<AdmissionResult>;
33
+ /**
34
+ * Runtime admission checks (IID verification).
35
+ * Only runs if aster.iid_provider is present in attributes.
36
+ */
37
+ export declare function checkRuntime(cred: EnrollmentCredential | ConsumerEnrollmentCredential, iidBackend?: IIDBackend, iidToken?: string): Promise<AdmissionResult>;
38
+ /** Options for the admit() orchestrator. */
39
+ export interface AdmitOptions {
40
+ nonceStore?: NonceStore;
41
+ iidBackend?: IIDBackend;
42
+ iidToken?: string;
43
+ }
44
+ /**
45
+ * Orchestrate offline + runtime admission checks.
46
+ * Fails fast: if offline checks fail, runtime checks are skipped.
47
+ * Refusal reason is logged but never sent to peer.
48
+ */
49
+ export declare function admit(cred: EnrollmentCredential | ConsumerEnrollmentCredential, peerEndpointId: string, opts?: AdmitOptions): Promise<AdmissionResult>;
50
+ /**
51
+ * @deprecated Use checkOffline + checkRuntime via admit() instead.
52
+ * Legacy: checks only pubkey match + expiry (no signature verification).
53
+ */
54
+ export declare function verifyConsumerCredential(cred: ConsumerEnrollmentCredential, expectedRootPubkey: string): Promise<AdmissionResult>;
55
+ /**
56
+ * @deprecated Use checkOffline + checkRuntime via admit() instead.
57
+ * Legacy: checks only pubkey match + expiry (no signature verification).
58
+ */
59
+ export declare function verifyProducerCredential(cred: EnrollmentCredential, expectedRootPubkey: string): Promise<AdmissionResult>;
60
+ //# sourceMappingURL=admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission.d.ts","sourceRoot":"","sources":["../../src/trust/admission.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAE3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtD,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA8BD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,oBAAoB,GAAG,4BAA4B,EACzD,cAAc,EAAE,MAAM,EACtB,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,eAAe,CAAC,CAiD1B;AAID;;;GAGG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,oBAAoB,GAAG,4BAA4B,EACzD,UAAU,CAAC,EAAE,UAAU,EACvB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAM1B;AAID,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,KAAK,CACzB,IAAI,EAAE,oBAAoB,GAAG,4BAA4B,EACzD,cAAc,EAAE,MAAM,EACtB,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC,eAAe,CAAC,CAQ1B;AAID;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,4BAA4B,EAClC,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,eAAe,CAAC,CAS1B;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,oBAAoB,EAC1B,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,eAAe,CAAC,CAS1B"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Admission gates for consumer/producer authorization.
3
+ *
4
+ * Spec reference: Aster-trust-spec.md §2.4, §3.2
5
+ *
6
+ * Two-phase admission:
7
+ * 1. checkOffline — signature, expiry, endpoint ID binding, nonce
8
+ * 2. checkRuntime — IID verification (cloud identity)
9
+ *
10
+ * admit() orchestrates both. Refusal reasons are logged internally —
11
+ * never sent to peer (oracle protection).
12
+ */
13
+ import { verifyCredentialSignature, hexToBytes } from './credentials.js';
14
+ import { verifyIID } from './iid.js';
15
+ // ── Structural validation ───────────────────────────────────────────────────
16
+ function validateStructure(cred) {
17
+ if ('credentialType' in cred) {
18
+ const consumer = cred;
19
+ if (consumer.credentialType === 'ott') {
20
+ if (consumer.nonce == null) {
21
+ return { ok: false, reason: 'OTT credential must carry a nonce' };
22
+ }
23
+ const nonceBytes = hexToBytes(consumer.nonce);
24
+ if (nonceBytes.length !== 32) {
25
+ return { ok: false, reason: `OTT nonce must be exactly 32 bytes; got ${nonceBytes.length}` };
26
+ }
27
+ }
28
+ else if (consumer.credentialType === 'policy') {
29
+ if (consumer.nonce != null) {
30
+ return { ok: false, reason: 'Policy credential must not carry a nonce' };
31
+ }
32
+ }
33
+ else {
34
+ return { ok: false, reason: `Unknown credentialType: ${consumer.credentialType}` };
35
+ }
36
+ }
37
+ return { ok: true };
38
+ }
39
+ // ── Offline checks ──────────────────────────────────────────────────────────
40
+ /**
41
+ * Offline admission checks — no network calls.
42
+ *
43
+ * 1. Structural validity (nonce length, policy-vs-OTT constraints)
44
+ * 2. Signature valid against rootPubkey
45
+ * 3. expiresAt > now
46
+ * 4. Endpoint ID match (always for EnrollmentCredential; if set for Consumer)
47
+ * 5. OTT nonce not already consumed
48
+ */
49
+ export async function checkOffline(cred, peerEndpointId, nonceStore) {
50
+ // 1. Structural validation
51
+ const { ok, reason: structReason } = validateStructure(cred);
52
+ if (!ok) {
53
+ console.log(`[DEBUG] admission checkOffline: structure failed: ${structReason}`);
54
+ return { admitted: false, reason: structReason };
55
+ }
56
+ // 2. Signature verification
57
+ const sigValid = await verifyCredentialSignature(cred);
58
+ if (!sigValid) {
59
+ return { admitted: false, reason: 'invalid signature' };
60
+ }
61
+ // 3. Expiry check
62
+ const nowSec = Math.floor(Date.now() / 1000);
63
+ if (cred.expiresAt <= nowSec) {
64
+ return { admitted: false, reason: `credential expired (expiresAt=${cred.expiresAt}, now=${nowSec})` };
65
+ }
66
+ // 4. Endpoint ID binding (only for OTT credentials; policy credentials are not bound)
67
+ if (!('credentialType' in cred)) {
68
+ // EnrollmentCredential — strict binding
69
+ const producer = cred;
70
+ if (producer.endpointId !== peerEndpointId) {
71
+ return { admitted: false, reason: `endpoint ID mismatch: credential=${producer.endpointId}, peer=${peerEndpointId}` };
72
+ }
73
+ }
74
+ // For policy credentials, endpoint_id is informational only — no binding check
75
+ // 5. OTT nonce consumption
76
+ if ('credentialType' in cred) {
77
+ const consumer = cred;
78
+ if (consumer.credentialType === 'ott') {
79
+ if (consumer.endpointId != null && consumer.endpointId !== peerEndpointId) {
80
+ return { admitted: false, reason: `OTT endpoint ID mismatch: credential=${consumer.endpointId}, peer=${peerEndpointId}` };
81
+ }
82
+ if (!nonceStore) {
83
+ return { admitted: false, reason: 'OTT credential presented but no nonceStore configured' };
84
+ }
85
+ const nonceHex = consumer.nonce;
86
+ if (nonceStore.has(nonceHex)) {
87
+ return { admitted: false, reason: 'OTT nonce already consumed' };
88
+ }
89
+ nonceStore.consume(nonceHex);
90
+ }
91
+ }
92
+ return { admitted: true, attributes: { ...cred.attributes } };
93
+ }
94
+ // ── Runtime checks ──────────────────────────────────────────────────────────
95
+ /**
96
+ * Runtime admission checks (IID verification).
97
+ * Only runs if aster.iid_provider is present in attributes.
98
+ */
99
+ export async function checkRuntime(cred, iidBackend, iidToken) {
100
+ const [ok, reason] = await verifyIID(cred.attributes, iidBackend, iidToken);
101
+ if (!ok) {
102
+ return { admitted: false, reason };
103
+ }
104
+ return { admitted: true, attributes: { ...cred.attributes } };
105
+ }
106
+ /**
107
+ * Orchestrate offline + runtime admission checks.
108
+ * Fails fast: if offline checks fail, runtime checks are skipped.
109
+ * Refusal reason is logged but never sent to peer.
110
+ */
111
+ export async function admit(cred, peerEndpointId, opts) {
112
+ const offline = await checkOffline(cred, peerEndpointId, opts?.nonceStore);
113
+ if (!offline.admitted)
114
+ return offline;
115
+ const runtime = await checkRuntime(cred, opts?.iidBackend, opts?.iidToken);
116
+ if (!runtime.admitted)
117
+ return runtime;
118
+ return { admitted: true, attributes: offline.attributes };
119
+ }
120
+ // ── Legacy compat (kept for existing callers) ───────────────────────────────
121
+ /**
122
+ * @deprecated Use checkOffline + checkRuntime via admit() instead.
123
+ * Legacy: checks only pubkey match + expiry (no signature verification).
124
+ */
125
+ export async function verifyConsumerCredential(cred, expectedRootPubkey) {
126
+ if (cred.rootPubkey !== expectedRootPubkey) {
127
+ return { admitted: false, reason: 'root pubkey mismatch' };
128
+ }
129
+ const nowSec = Math.floor(Date.now() / 1000);
130
+ if (cred.expiresAt > 0 && cred.expiresAt <= nowSec) {
131
+ return { admitted: false, reason: 'credential expired' };
132
+ }
133
+ return { admitted: true, attributes: { ...cred.attributes } };
134
+ }
135
+ /**
136
+ * @deprecated Use checkOffline + checkRuntime via admit() instead.
137
+ * Legacy: checks only pubkey match + expiry (no signature verification).
138
+ */
139
+ export async function verifyProducerCredential(cred, expectedRootPubkey) {
140
+ if (cred.rootPubkey !== expectedRootPubkey) {
141
+ return { admitted: false, reason: 'root pubkey mismatch' };
142
+ }
143
+ const nowSec = Math.floor(Date.now() / 1000);
144
+ if (cred.expiresAt > 0 && cred.expiresAt <= nowSec) {
145
+ return { admitted: false, reason: 'credential expired' };
146
+ }
147
+ return { admitted: true, attributes: { ...cred.attributes } };
148
+ }
149
+ //# sourceMappingURL=admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission.js","sourceRoot":"","sources":["../../src/trust/admission.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Producer mesh bootstrap -- founding node + join.
3
+ *
4
+ * Spec reference: Aster-trust-spec.md S2.1, S2.5. Plan: ASTER_PLAN.md S14.5.
5
+ *
6
+ * Two startup modes:
7
+ *
8
+ * startFoundingNode()
9
+ * The first producer in a new mesh. Generates a random 32-byte salt, derives
10
+ * the gossip topic, initializes MeshState, and returns it for the caller.
11
+ *
12
+ * joinMesh()
13
+ * A subsequent producer. Builds an AdmissionRequest from its credential.
14
+ * The caller dials the bootstrap peer and sends the request, then calls
15
+ * applyAdmissionResponse() with the result.
16
+ *
17
+ * handleAdmissionRpc()
18
+ * Server-side handler: parses a request, runs offline admission checks,
19
+ * and returns an AdmissionResponse.
20
+ */
21
+ import { MeshState } from './mesh.js';
22
+ import type { EnrollmentCredential } from './credentials.js';
23
+ export interface BootstrapConfig {
24
+ /** State directory (default: ~/.aster). */
25
+ stateDir?: string;
26
+ }
27
+ export interface AdmissionRequest {
28
+ credentialJson: string;
29
+ iidToken?: string;
30
+ }
31
+ export interface AdmissionResponse {
32
+ accepted: boolean;
33
+ salt: string;
34
+ acceptedProducers: string[];
35
+ /** Internal only -- not exposed to peer on the wire. */
36
+ reason?: string;
37
+ }
38
+ /**
39
+ * Start the founding node of a new producer mesh.
40
+ *
41
+ * Steps (S2.1):
42
+ * 1. Load credential from JSON file.
43
+ * 2. Verify credential offline.
44
+ * 3. Generate or load 32-byte salt.
45
+ * 4. Derive gossip topic.
46
+ * 5. Create MeshState with self as only accepted producer.
47
+ * 6. Persist state.
48
+ *
49
+ * @returns The initialized MeshState.
50
+ */
51
+ export declare function startFoundingNode(enrollmentPath: string, config?: BootstrapConfig): Promise<MeshState>;
52
+ /**
53
+ * Build an AdmissionRequest from a credential for joining an existing mesh.
54
+ *
55
+ * The caller should send this request to the bootstrap peer over
56
+ * the aster.producer_admission ALPN, then call applyAdmissionResponse()
57
+ * with the result.
58
+ */
59
+ export declare function joinMesh(credential: EnrollmentCredential, iidToken?: string): AdmissionRequest;
60
+ /**
61
+ * Finalize MeshState after receiving a successful AdmissionResponse.
62
+ *
63
+ * @param response The AdmissionResponse from the bootstrap peer.
64
+ * @param ownEndpointId This node's endpoint ID.
65
+ * @param rootPubkey The root public key (raw bytes) for topic derivation.
66
+ * @returns Initialized MeshState ready for gossip subscription.
67
+ * @throws If response.accepted is false.
68
+ */
69
+ export declare function applyAdmissionResponse(response: AdmissionResponse, ownEndpointId: string, rootPubkey: Uint8Array): Promise<MeshState>;
70
+ /**
71
+ * Server-side handler for aster.producer_admission ALPN.
72
+ *
73
+ * Parses an AdmissionRequest, runs offline admission checks, and returns
74
+ * an AdmissionResponse. On success, the peer is added to ownState.
75
+ *
76
+ * @param requestJson JSON-serialized credential (the credentialJson field
77
+ * from AdmissionRequest, or a raw credential JSON).
78
+ * @param ownState The founding/accepting node's MeshState.
79
+ * @param ownRootPubkey Hex-encoded root public key this mesh trusts.
80
+ * @param config Optional BootstrapConfig.
81
+ * @returns AdmissionResponse (accepted or rejected with reason).
82
+ */
83
+ export declare function handleAdmissionRpc(requestJson: string, ownState: MeshState, ownRootPubkey: string, config?: BootstrapConfig): Promise<AdmissionResponse>;
84
+ /**
85
+ * Handle one producer admission connection: read request, write response.
86
+ *
87
+ * @param conn An IrohConnection-like object with acceptBi() and remoteId().
88
+ * @param ownRootPubkey Hex-encoded root public key.
89
+ * @param ownState This node's MeshState; mutated on accept.
90
+ * @param config Optional BootstrapConfig.
91
+ * @returns The AdmissionResponse that was sent.
92
+ */
93
+ export declare function handleProducerAdmissionConnection(conn: {
94
+ remoteId(): string;
95
+ acceptBi(): Promise<[{
96
+ writeAll(data: Uint8Array): Promise<void>;
97
+ finish(): Promise<void>;
98
+ }, {
99
+ readToEnd(maxBytes: number): Promise<Uint8Array>;
100
+ }]>;
101
+ }, ownRootPubkey: string, ownState: MeshState, config?: BootstrapConfig): Promise<AdmissionResponse>;
102
+ /**
103
+ * Build an in-memory MeshState for a standalone producer.
104
+ *
105
+ * Useful for demos, tests, and single-node setups. Generates a fresh random
106
+ * salt and an empty accepted-producer set with no persistence.
107
+ */
108
+ export declare function makeEphemeralMeshState(rootPubkey?: Uint8Array): Promise<MeshState>;
109
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/trust/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,OAAO,EAAE,SAAS,EAAiB,MAAM,WAAW,CAAC;AAErD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAM7D,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAwED;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,SAAS,CAAC,CAwBpB;AAID;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,UAAU,EAAE,oBAAoB,EAChC,QAAQ,CAAC,EAAE,MAAM,GAChB,gBAAgB,CAYlB;AAID;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,iBAAiB,EAC3B,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,SAAS,CAAC,CAkBpB;AAID;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,SAAS,EACnB,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,iBAAiB,CAAC,CA8D5B;AAID;;;;;;;;GAQG;AACH,wBAAsB,iCAAiC,CACrD,IAAI,EAAE;IACJ,QAAQ,IAAI,MAAM,CAAC;IACnB,QAAQ,IAAI,OAAO,CAAC,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,EAAE;QAAE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;KAAE,CAAC,CAAC,CAAC;CACrJ,EACD,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,SAAS,EACnB,MAAM,CAAC,EAAE,eAAe,GACvB,OAAO,CAAC,iBAAiB,CAAC,CA8C5B;AAID;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CASxF"}