@synoi/sraid 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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/PROJECTION_SPEC.md +245 -0
  3. package/README.md +149 -0
  4. package/SPEC.md +216 -0
  5. package/dist/attestation.d.ts +92 -0
  6. package/dist/attestation.d.ts.map +1 -0
  7. package/dist/attestation.js +155 -0
  8. package/dist/attestation.js.map +1 -0
  9. package/dist/authority.d.ts +351 -0
  10. package/dist/authority.d.ts.map +1 -0
  11. package/dist/authority.js +563 -0
  12. package/dist/authority.js.map +1 -0
  13. package/dist/canonicalize.d.ts +70 -0
  14. package/dist/canonicalize.d.ts.map +1 -0
  15. package/dist/canonicalize.js +151 -0
  16. package/dist/canonicalize.js.map +1 -0
  17. package/dist/ed25519.d.ts +26 -0
  18. package/dist/ed25519.d.ts.map +1 -0
  19. package/dist/ed25519.js +53 -0
  20. package/dist/ed25519.js.map +1 -0
  21. package/dist/index.d.ts +28 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +46 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/internal/base64.d.ts +28 -0
  26. package/dist/internal/base64.d.ts.map +1 -0
  27. package/dist/internal/base64.js +45 -0
  28. package/dist/internal/base64.js.map +1 -0
  29. package/dist/internal/key-cache.d.ts +47 -0
  30. package/dist/internal/key-cache.d.ts.map +1 -0
  31. package/dist/internal/key-cache.js +77 -0
  32. package/dist/internal/key-cache.js.map +1 -0
  33. package/dist/lineage.d.ts +104 -0
  34. package/dist/lineage.d.ts.map +1 -0
  35. package/dist/lineage.js +0 -0
  36. package/dist/lineage.js.map +1 -0
  37. package/dist/mldsa.d.ts +41 -0
  38. package/dist/mldsa.d.ts.map +1 -0
  39. package/dist/mldsa.js +119 -0
  40. package/dist/mldsa.js.map +1 -0
  41. package/dist/oid.d.ts +109 -0
  42. package/dist/oid.d.ts.map +1 -0
  43. package/dist/oid.js +140 -0
  44. package/dist/oid.js.map +1 -0
  45. package/dist/sensitivity.d.ts +104 -0
  46. package/dist/sensitivity.d.ts.map +1 -0
  47. package/dist/sensitivity.js +117 -0
  48. package/dist/sensitivity.js.map +1 -0
  49. package/dist/signature.d.ts +46 -0
  50. package/dist/signature.d.ts.map +1 -0
  51. package/dist/signature.js +89 -0
  52. package/dist/signature.js.map +1 -0
  53. package/dist/types.d.ts +313 -0
  54. package/dist/types.d.ts.map +1 -0
  55. package/dist/types.js +16 -0
  56. package/dist/types.js.map +1 -0
  57. package/dist/validate.d.ts +88 -0
  58. package/dist/validate.d.ts.map +1 -0
  59. package/dist/validate.js +339 -0
  60. package/dist/validate.js.map +1 -0
  61. package/package.json +69 -0
  62. package/src/attestation.ts +204 -0
  63. package/src/authority.ts +849 -0
  64. package/src/canonicalize.ts +167 -0
  65. package/src/ed25519.ts +60 -0
  66. package/src/index.ts +118 -0
  67. package/src/internal/base64.ts +44 -0
  68. package/src/internal/key-cache.ts +79 -0
  69. package/src/lineage.ts +0 -0
  70. package/src/mldsa.ts +131 -0
  71. package/src/oid.ts +146 -0
  72. package/src/sensitivity.ts +154 -0
  73. package/src/signature.ts +119 -0
  74. package/src/types.ts +351 -0
  75. package/src/validate.ts +402 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @synoi/sraid — validate.ts
3
+ *
4
+ * Non-throwing shape validators for CDRO objects. Returns `{ ok, errors }`
5
+ * so callers can collect every violation in one pass.
6
+ *
7
+ * Validation here is intentionally LOW-LEVEL — it checks the CDRO
8
+ * envelope shape, not the semantics of a specific `body`. Higher-layer
9
+ * packages (GAP, Vault, …) layer their own validators on top.
10
+ *
11
+ * Style mirrors the hand-rolled validators in synoi-mcp-server (no zod,
12
+ * no heavy validation library) — kept tiny on purpose.
13
+ */
14
+ import type { AttestationEnvelope, AttestationSignature, AuthorityBlock, CDRO, LineageLink, LinkRel, SignatureEnvelope, SRO } from './types.js';
15
+ export interface ValidationResult {
16
+ ok: boolean;
17
+ errors: string[];
18
+ }
19
+ /**
20
+ * Validate that `x` matches the CDRO envelope shape. Does not verify the
21
+ * signature — use `verifySignature` for that. Does not recompute the
22
+ * OID — use `oidOf` and compare for that.
23
+ *
24
+ * [E01] not an object / null
25
+ * [E02] oid missing or not a non-empty string
26
+ * [E03] oid missing "sha256:" prefix
27
+ * [E04] type missing or not a non-empty string
28
+ * [E05] sraid_version not "2.0"
29
+ * [E06] tenant_id missing or not a non-empty string
30
+ * [E07] created_at_ms not a positive integer
31
+ * [E08] created_by missing or not a non-empty string
32
+ * [E09] body field absent (it may be any value, but must be present)
33
+ * [E10] supersedes, if present, not a canonical OID (sha256:<64 hex>)
34
+ * [E11] signature, if present, malformed envelope
35
+ * [E12] authority, if present, malformed block
36
+ * [E13] prev, if present, not a non-empty "sha256:" string
37
+ * [E14] links, if present, not an array of well-formed typed edges
38
+ * [E15] attestation, if present, malformed DSSE envelope
39
+ * [E16] sensitivity, if present, not a known opaque tier (s0..s4)
40
+ */
41
+ export declare function validateCdro(x: unknown): ValidationResult;
42
+ /**
43
+ * Validate the shape of an L4 AuthorityBlock. This is a SHAPE check only —
44
+ * it does NOT verify that the referenced grant exists, is signed, covers
45
+ * the action, or is unrevoked. For real authorization verification use
46
+ * `verifyAuthority` in authority.ts (it does binding/signature/coverage
47
+ * locally and marks revocation/existence as resolver-dependent).
48
+ */
49
+ export declare function validateAuthorityBlock(x: unknown): ValidationResult;
50
+ /**
51
+ * Validate a single L3 lineage edge ({ rel, oid }). Shape check only — it
52
+ * does NOT resolve the target OID or check it exists / is signed / is
53
+ * unrevoked (resolver concern). `rel` is an OPEN taxonomy: any non-empty
54
+ * string is accepted so the format stays forward-compatible.
55
+ */
56
+ export declare function validateLineageLink(x: unknown): ValidationResult;
57
+ /**
58
+ * Validate the shape of a SignatureEnvelope. Useful when verifying a
59
+ * detached signature or when a caller wants a quick sanity check before
60
+ * a more expensive verifySignature() call.
61
+ */
62
+ export declare function validateSignatureEnvelope(x: unknown): ValidationResult;
63
+ /**
64
+ * Validate the shape of a DSSE `AttestationEnvelope`. Shape check only — it
65
+ * does NOT verify the signatures (use `verifyAttestation` in attestation.ts
66
+ * for that) and does NOT enforce the hybrid both-required policy (the
67
+ * verifier does). It checks: `payloadType` is a non-empty string, `payload`
68
+ * is a string, and `signatures` is an array of well-formed `{ alg, sig }`
69
+ * entries.
70
+ */
71
+ export declare function validateAttestationEnvelope(x: unknown): ValidationResult;
72
+ /**
73
+ * Validate that `x` matches the SRO shape — a CDRO whose `type` is
74
+ * "sraid:sro" and whose `body` carries predecessor/successor pointers and
75
+ * an authorizer. Reuses validateCdro and layers SRO-specific checks on
76
+ * top.
77
+ *
78
+ * [S01] envelope is not a valid CDRO
79
+ * [S02] type is not "sraid:sro"
80
+ * [S03] body.predecessor_oid not a canonical OID (sha256:<64 hex>)
81
+ * [S04] body.successor_oid not a canonical OID (sha256:<64 hex>)
82
+ * [S05] body.reason not a non-empty string
83
+ * [S06] body.authorized_by not a non-empty string
84
+ * [S07] body.evidence_oids, if present, not an array of non-empty strings
85
+ */
86
+ export declare function validateSro(x: unknown): ValidationResult;
87
+ export type { AttestationEnvelope, AttestationSignature, AuthorityBlock, CDRO, LineageLink, LinkRel, SRO, SignatureEnvelope, };
88
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,IAAI,EACJ,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,GAAG,EACJ,MAAM,YAAY,CAAA;AAkBnB,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAmFzD;AAID;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAGnE;AA0CD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAGhE;AA+BD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAGtE;AAsBD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAGxE;AAyCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,gBAAgB,CA2CxD;AAID,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,IAAI,EACJ,WAAW,EACX,OAAO,EACP,GAAG,EACH,iBAAiB,GAClB,CAAA"}
@@ -0,0 +1,339 @@
1
+ /**
2
+ * @synoi/sraid — validate.ts
3
+ *
4
+ * Non-throwing shape validators for CDRO objects. Returns `{ ok, errors }`
5
+ * so callers can collect every violation in one pass.
6
+ *
7
+ * Validation here is intentionally LOW-LEVEL — it checks the CDRO
8
+ * envelope shape, not the semantics of a specific `body`. Higher-layer
9
+ * packages (GAP, Vault, …) layer their own validators on top.
10
+ *
11
+ * Style mirrors the hand-rolled validators in synoi-mcp-server (no zod,
12
+ * no heavy validation library) — kept tiny on purpose.
13
+ */
14
+ import { SENSITIVITY_TIERS, isSensitivityTier } from './sensitivity.js';
15
+ const VALID_AUTHORITY_DECISIONS = new Set([
16
+ 'allow',
17
+ 'deny',
18
+ 'defer',
19
+ 'step_up',
20
+ 'delegate',
21
+ 'revoke',
22
+ ]);
23
+ // Matches the output of oidOf(): "sha256:" followed by exactly 64 lowercase hex chars.
24
+ const CANONICAL_OID_RE = /^sha256:[0-9a-f]{64}$/;
25
+ function isCanonicalOid(v) {
26
+ return typeof v === 'string' && CANONICAL_OID_RE.test(v);
27
+ }
28
+ // ── CDRO validation ──────────────────────────────────────────────────────────
29
+ /**
30
+ * Validate that `x` matches the CDRO envelope shape. Does not verify the
31
+ * signature — use `verifySignature` for that. Does not recompute the
32
+ * OID — use `oidOf` and compare for that.
33
+ *
34
+ * [E01] not an object / null
35
+ * [E02] oid missing or not a non-empty string
36
+ * [E03] oid missing "sha256:" prefix
37
+ * [E04] type missing or not a non-empty string
38
+ * [E05] sraid_version not "2.0"
39
+ * [E06] tenant_id missing or not a non-empty string
40
+ * [E07] created_at_ms not a positive integer
41
+ * [E08] created_by missing or not a non-empty string
42
+ * [E09] body field absent (it may be any value, but must be present)
43
+ * [E10] supersedes, if present, not a canonical OID (sha256:<64 hex>)
44
+ * [E11] signature, if present, malformed envelope
45
+ * [E12] authority, if present, malformed block
46
+ * [E13] prev, if present, not a non-empty "sha256:" string
47
+ * [E14] links, if present, not an array of well-formed typed edges
48
+ * [E15] attestation, if present, malformed DSSE envelope
49
+ * [E16] sensitivity, if present, not a known opaque tier (s0..s4)
50
+ */
51
+ export function validateCdro(x) {
52
+ const errors = [];
53
+ if (x === null || typeof x !== 'object' || Array.isArray(x)) {
54
+ return { ok: false, errors: ['[E01] CDRO must be a plain object'] };
55
+ }
56
+ const o = x;
57
+ if (typeof o['oid'] !== 'string' || o['oid'].length === 0) {
58
+ errors.push('[E02] oid must be a non-empty string');
59
+ }
60
+ else if (!o['oid'].startsWith('sha256:')) {
61
+ errors.push('[E03] oid must start with "sha256:"');
62
+ }
63
+ if (typeof o['type'] !== 'string' || o['type'].length === 0) {
64
+ errors.push('[E04] type must be a non-empty string');
65
+ }
66
+ if (o['sraid_version'] !== '2.0') {
67
+ errors.push('[E05] sraid_version must be "2.0"');
68
+ }
69
+ if (typeof o['tenant_id'] !== 'string' || o['tenant_id'].length === 0) {
70
+ errors.push('[E06] tenant_id must be a non-empty string');
71
+ }
72
+ const createdAt = o['created_at_ms'];
73
+ if (typeof createdAt !== 'number' || !Number.isInteger(createdAt) || createdAt <= 0) {
74
+ errors.push('[E07] created_at_ms must be a positive integer (Unix ms)');
75
+ }
76
+ if (typeof o['created_by'] !== 'string' || o['created_by'].length === 0) {
77
+ errors.push('[E08] created_by must be a non-empty string');
78
+ }
79
+ if (!('body' in o)) {
80
+ errors.push('[E09] body field must be present');
81
+ }
82
+ if (o['supersedes'] !== undefined) {
83
+ if (!isCanonicalOid(o['supersedes'])) {
84
+ errors.push('[E10] supersedes, if present, must be a canonical OID (sha256:<64 hex>)');
85
+ }
86
+ }
87
+ if (o['prev'] !== undefined && o['prev'] !== null) {
88
+ if (typeof o['prev'] !== 'string' || o['prev'].length === 0) {
89
+ errors.push('[E13] prev, if present, must be a non-empty string');
90
+ }
91
+ else if (!o['prev'].startsWith('sha256:')) {
92
+ errors.push('[E13] prev must start with "sha256:"');
93
+ }
94
+ }
95
+ if (o['links'] !== undefined) {
96
+ const linkErrors = validateLinksShape(o['links']);
97
+ for (const e of linkErrors)
98
+ errors.push('[E14] ' + e);
99
+ }
100
+ if (o['signature'] !== undefined) {
101
+ const envErrors = validateSignatureEnvelopeShape(o['signature']);
102
+ for (const e of envErrors)
103
+ errors.push('[E11] ' + e);
104
+ }
105
+ if (o['authority'] !== undefined) {
106
+ const authErrors = validateAuthorityBlockShape(o['authority']);
107
+ for (const e of authErrors)
108
+ errors.push('[E12] ' + e);
109
+ }
110
+ if (o['attestation'] !== undefined) {
111
+ const attErrors = validateAttestationEnvelopeShape(o['attestation']);
112
+ for (const e of attErrors)
113
+ errors.push('[E15] ' + e);
114
+ }
115
+ if (o['sensitivity'] !== undefined && o['sensitivity'] !== null) {
116
+ if (!isSensitivityTier(o['sensitivity'])) {
117
+ errors.push(`[E16] sensitivity, if present, must be one of ${SENSITIVITY_TIERS.join('|')} ` +
118
+ '(a coarse, opaque tier — NOT a literal category like "phi"; SPEC §7)');
119
+ }
120
+ }
121
+ return { ok: errors.length === 0, errors };
122
+ }
123
+ // ── Authority block validation (L4) ───────────────────────────────────────────
124
+ /**
125
+ * Validate the shape of an L4 AuthorityBlock. This is a SHAPE check only —
126
+ * it does NOT verify that the referenced grant exists, is signed, covers
127
+ * the action, or is unrevoked. For real authorization verification use
128
+ * `verifyAuthority` in authority.ts (it does binding/signature/coverage
129
+ * locally and marks revocation/existence as resolver-dependent).
130
+ */
131
+ export function validateAuthorityBlock(x) {
132
+ const errors = validateAuthorityBlockShape(x);
133
+ return { ok: errors.length === 0, errors };
134
+ }
135
+ function validateAuthorityBlockShape(x) {
136
+ const errors = [];
137
+ if (x === null || typeof x !== 'object' || Array.isArray(x)) {
138
+ return ['authority must be a plain object'];
139
+ }
140
+ const o = x;
141
+ if (o['grant_oid'] !== undefined) {
142
+ if (typeof o['grant_oid'] !== 'string' || o['grant_oid'].length === 0) {
143
+ errors.push('authority.grant_oid, if present, must be a non-empty string');
144
+ }
145
+ else if (!o['grant_oid'].startsWith('sha256:')) {
146
+ errors.push('authority.grant_oid must start with "sha256:"');
147
+ }
148
+ }
149
+ // decision may be null (the orphan / uncorrelated case) or a valid verb.
150
+ if (o['decision'] !== undefined && o['decision'] !== null) {
151
+ if (typeof o['decision'] !== 'string' ||
152
+ !VALID_AUTHORITY_DECISIONS.has(o['decision'])) {
153
+ errors.push('authority.decision must be one of allow|deny|defer|step_up|delegate|revoke (or null)');
154
+ }
155
+ }
156
+ if (o['intent_oid'] !== undefined) {
157
+ if (typeof o['intent_oid'] !== 'string' || o['intent_oid'].length === 0) {
158
+ errors.push('authority.intent_oid, if present, must be a non-empty string');
159
+ }
160
+ else if (!o['intent_oid'].startsWith('sha256:')) {
161
+ errors.push('authority.intent_oid must start with "sha256:"');
162
+ }
163
+ }
164
+ return errors;
165
+ }
166
+ // ── Lineage validation (L3) ───────────────────────────────────────────────────
167
+ /**
168
+ * Validate a single L3 lineage edge ({ rel, oid }). Shape check only — it
169
+ * does NOT resolve the target OID or check it exists / is signed / is
170
+ * unrevoked (resolver concern). `rel` is an OPEN taxonomy: any non-empty
171
+ * string is accepted so the format stays forward-compatible.
172
+ */
173
+ export function validateLineageLink(x) {
174
+ const errors = validateLineageLinkShape(x);
175
+ return { ok: errors.length === 0, errors };
176
+ }
177
+ function validateLineageLinkShape(x) {
178
+ const errors = [];
179
+ if (x === null || typeof x !== 'object' || Array.isArray(x)) {
180
+ return ['link must be a plain object { rel, oid }'];
181
+ }
182
+ const o = x;
183
+ if (typeof o['rel'] !== 'string' || o['rel'].length === 0) {
184
+ errors.push('link.rel must be a non-empty string');
185
+ }
186
+ if (typeof o['oid'] !== 'string' || o['oid'].length === 0) {
187
+ errors.push('link.oid must be a non-empty string');
188
+ }
189
+ else if (!o['oid'].startsWith('sha256:')) {
190
+ errors.push('link.oid must start with "sha256:"');
191
+ }
192
+ return errors;
193
+ }
194
+ function validateLinksShape(x) {
195
+ if (!Array.isArray(x))
196
+ return ['links, if present, must be an array'];
197
+ const errors = [];
198
+ for (let i = 0; i < x.length; i++) {
199
+ const edgeErrors = validateLineageLinkShape(x[i]);
200
+ for (const e of edgeErrors)
201
+ errors.push(`links[${i}]: ${e}`);
202
+ }
203
+ return errors;
204
+ }
205
+ // ── Signature envelope validation ────────────────────────────────────────────
206
+ /**
207
+ * Validate the shape of a SignatureEnvelope. Useful when verifying a
208
+ * detached signature or when a caller wants a quick sanity check before
209
+ * a more expensive verifySignature() call.
210
+ */
211
+ export function validateSignatureEnvelope(x) {
212
+ const errors = validateSignatureEnvelopeShape(x);
213
+ return { ok: errors.length === 0, errors };
214
+ }
215
+ function validateSignatureEnvelopeShape(x) {
216
+ const errors = [];
217
+ if (x === null || typeof x !== 'object' || Array.isArray(x)) {
218
+ return ['signature envelope must be a plain object'];
219
+ }
220
+ const o = x;
221
+ if (typeof o['ed25519'] !== 'string' || o['ed25519'].length === 0) {
222
+ errors.push('signature.ed25519 must be a non-empty base64 string');
223
+ }
224
+ if (typeof o['ml_dsa_65'] !== 'string' || o['ml_dsa_65'].length === 0) {
225
+ errors.push('signature.ml_dsa_65 must be a non-empty base64 string');
226
+ }
227
+ if (typeof o['signer_kid'] !== 'string' || o['signer_kid'].length === 0) {
228
+ errors.push('signature.signer_kid must be a non-empty string');
229
+ }
230
+ return errors;
231
+ }
232
+ // ── DSSE attestation envelope validation (L2) ─────────────────────────────────
233
+ /**
234
+ * Validate the shape of a DSSE `AttestationEnvelope`. Shape check only — it
235
+ * does NOT verify the signatures (use `verifyAttestation` in attestation.ts
236
+ * for that) and does NOT enforce the hybrid both-required policy (the
237
+ * verifier does). It checks: `payloadType` is a non-empty string, `payload`
238
+ * is a string, and `signatures` is an array of well-formed `{ alg, sig }`
239
+ * entries.
240
+ */
241
+ export function validateAttestationEnvelope(x) {
242
+ const errors = validateAttestationEnvelopeShape(x);
243
+ return { ok: errors.length === 0, errors };
244
+ }
245
+ function validateAttestationEnvelopeShape(x) {
246
+ const errors = [];
247
+ if (x === null || typeof x !== 'object' || Array.isArray(x)) {
248
+ return ['attestation must be a plain object'];
249
+ }
250
+ const o = x;
251
+ if (typeof o['payloadType'] !== 'string' || o['payloadType'].length === 0) {
252
+ errors.push('attestation.payloadType must be a non-empty string');
253
+ }
254
+ if (typeof o['payload'] !== 'string') {
255
+ errors.push('attestation.payload must be a string');
256
+ }
257
+ if (!Array.isArray(o['signatures'])) {
258
+ errors.push('attestation.signatures must be an array');
259
+ }
260
+ else {
261
+ const sigs = o['signatures'];
262
+ for (let i = 0; i < sigs.length; i++) {
263
+ const s = sigs[i];
264
+ if (s === null || typeof s !== 'object' || Array.isArray(s)) {
265
+ errors.push(`attestation.signatures[${i}] must be a plain object { alg, sig }`);
266
+ continue;
267
+ }
268
+ const se = s;
269
+ if (typeof se['alg'] !== 'string' || se['alg'].length === 0) {
270
+ errors.push(`attestation.signatures[${i}].alg must be a non-empty string`);
271
+ }
272
+ if (typeof se['sig'] !== 'string' || se['sig'].length === 0) {
273
+ errors.push(`attestation.signatures[${i}].sig must be a non-empty base64 string`);
274
+ }
275
+ if (se['keyid'] !== undefined && typeof se['keyid'] !== 'string') {
276
+ errors.push(`attestation.signatures[${i}].keyid, if present, must be a string`);
277
+ }
278
+ }
279
+ }
280
+ return errors;
281
+ }
282
+ // ── SRO validation ───────────────────────────────────────────────────────────
283
+ /**
284
+ * Validate that `x` matches the SRO shape — a CDRO whose `type` is
285
+ * "sraid:sro" and whose `body` carries predecessor/successor pointers and
286
+ * an authorizer. Reuses validateCdro and layers SRO-specific checks on
287
+ * top.
288
+ *
289
+ * [S01] envelope is not a valid CDRO
290
+ * [S02] type is not "sraid:sro"
291
+ * [S03] body.predecessor_oid not a canonical OID (sha256:<64 hex>)
292
+ * [S04] body.successor_oid not a canonical OID (sha256:<64 hex>)
293
+ * [S05] body.reason not a non-empty string
294
+ * [S06] body.authorized_by not a non-empty string
295
+ * [S07] body.evidence_oids, if present, not an array of non-empty strings
296
+ */
297
+ export function validateSro(x) {
298
+ const cdroResult = validateCdro(x);
299
+ if (!cdroResult.ok) {
300
+ return { ok: false, errors: cdroResult.errors.map((e) => '[S01] ' + e) };
301
+ }
302
+ const errors = [];
303
+ const o = x;
304
+ if (o.type !== 'sraid:sro') {
305
+ errors.push('[S02] type must be "sraid:sro" for an SRO');
306
+ }
307
+ if (o.body === null || typeof o.body !== 'object' || Array.isArray(o.body)) {
308
+ errors.push('[S01] body must be an object');
309
+ return { ok: false, errors };
310
+ }
311
+ const b = o.body;
312
+ if (!isCanonicalOid(b['predecessor_oid'])) {
313
+ errors.push('[S03] body.predecessor_oid must be a canonical OID (sha256:<64 hex>)');
314
+ }
315
+ if (!isCanonicalOid(b['successor_oid'])) {
316
+ errors.push('[S04] body.successor_oid must be a canonical OID (sha256:<64 hex>)');
317
+ }
318
+ if (typeof b['reason'] !== 'string' || b['reason'].length === 0) {
319
+ errors.push('[S05] body.reason must be a non-empty string');
320
+ }
321
+ if (typeof b['authorized_by'] !== 'string' || b['authorized_by'].length === 0) {
322
+ errors.push('[S06] body.authorized_by must be a non-empty string');
323
+ }
324
+ if (b['evidence_oids'] !== undefined) {
325
+ if (!Array.isArray(b['evidence_oids'])) {
326
+ errors.push('[S07] body.evidence_oids, if present, must be an array');
327
+ }
328
+ else {
329
+ const arr = b['evidence_oids'];
330
+ for (let i = 0; i < arr.length; i++) {
331
+ if (typeof arr[i] !== 'string' || arr[i].length === 0) {
332
+ errors.push(`[S07] body.evidence_oids[${i}] must be a non-empty string`);
333
+ }
334
+ }
335
+ }
336
+ }
337
+ return { ok: errors.length === 0, errors };
338
+ }
339
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@synoi/sraid",
3
+ "version": "0.2.0",
4
+ "description": "Reference TypeScript library for the SynOI SRAID (Self-Routing Addressable Identity Data) protocol - types, canonical object serializer, OID computation, signature verification, and validators for L0 of the SRAID Stack.",
5
+ "license": "MIT",
6
+ "homepage": "https://synoi.systems",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/synoi/synoi-sraid.git"
10
+ },
11
+ "author": {
12
+ "name": "SynOI Inc.",
13
+ "url": "https://synoi.systems"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public",
17
+ "registry": "https://registry.npmjs.org"
18
+ },
19
+ "type": "module",
20
+ "main": "dist/index.js",
21
+ "types": "dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "./canonicalize": {
28
+ "types": "./dist/canonicalize.d.ts",
29
+ "default": "./dist/canonicalize.js"
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "src",
35
+ "README.md",
36
+ "SPEC.md",
37
+ "PROJECTION_SPEC.md",
38
+ "LICENSE"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "typecheck": "tsc --noEmit",
43
+ "test": "npx tsx test/run-all.ts"
44
+ },
45
+ "dependencies": {
46
+ "@noble/curves": "^1.9.7",
47
+ "@noble/hashes": "^1.5.0",
48
+ "@noble/post-quantum": "^0.6.1"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^20.12.0",
52
+ "tsx": "^4.22.2",
53
+ "typescript": "^5.4.5"
54
+ },
55
+ "engines": {
56
+ "node": ">=22"
57
+ },
58
+ "keywords": [
59
+ "synoi",
60
+ "sraid",
61
+ "canonical-object-format",
62
+ "cdro",
63
+ "content-addressed",
64
+ "ed25519",
65
+ "ml-dsa",
66
+ "post-quantum",
67
+ "canonicalization"
68
+ ]
69
+ }