@zanii/residency 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -37,3 +37,7 @@ convenience only.
37
37
  Only as strong as the region attestation source. A claim proves "a signal your verifier
38
38
  trusts said this ran in region R, and R is in your declared jurisdiction." Bind a signal
39
39
  you verify.
40
+
41
+ ## Changelog
42
+
43
+ - **0.2.2** — Cloud region to country maps and verifier, TEE + latency location checks, national profiles (UAE, KSA, EU, India, Indonesia), inference-region claims, transfer bases for crossings, foreign-access exposure, backup and sub-processor residency, dashboard, signed period certificate.
package/dist/index.d.ts CHANGED
@@ -75,4 +75,5 @@ export declare function detectCrossings(sequence: Array<{
75
75
  }>;
76
76
  /** Does an agent's scope permit acting in this region? (`residency.<region>` targets, reusing core.) */
77
77
  export declare function residencyAllowed(effectiveScopes: string[], region: string): boolean;
78
+ export * from './sovereign.js';
78
79
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6BA,6FAA6F;AAC7F,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,2FAA2F;AAC3F,MAAM,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,iBAAiB,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAEhK,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAIzD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,CAAC,CAAC;IACL,IAAI,EAAE,iBAAiB,CAAC;IACxB,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAa/G;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEvD;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE;IAAE,cAAc,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,cAAc,CAAA;CAAE,GAC/D,OAAO,CAAC,cAAc,CAAC,CAiBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,cAAc,EAAE,MAAM,EAAE,GACvB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,CAAC,CAcrE;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6BA,6FAA6F;AAC7F,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,2FAA2F;AAC3F,MAAM,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,iBAAiB,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAEhK,oFAAoF;AACpF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAIzD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,CAAC,CAAC;IACL,IAAI,EAAE,iBAAiB,CAAC;IACxB,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAa/G;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEvD;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE;IAAE,cAAc,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,cAAc,CAAA;CAAE,GAC/D,OAAO,CAAC,cAAc,CAAC,CAiBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,cAAc,EAAE,MAAM,EAAE,GACvB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,CAAC,CAcrE;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnF;AACD,cAAc,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -108,4 +108,5 @@ export function detectCrossings(sequence, allowedRegions) {
108
108
  export function residencyAllowed(effectiveScopes, region) {
109
109
  return scopesAllow(effectiveScopes, `residency.${region}`);
110
110
  }
111
+ export * from './sovereign.js';
111
112
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Sovereign residency: cloud region -> country maps, TEE + network-latency location checks,
3
+ * national profiles, inference-region claims, transfer mechanisms for crossings, provider
4
+ * foreign-access exposure, backup and sub-processor residency, a dashboard and a signed
5
+ * certificate for a period. Region signals are still authenticated by the verifier you inject.
6
+ */
7
+ import { type SignedObject } from '@zanii/core';
8
+ import { type RegionAttestation, type RegionVerifier, type ResidencyCheck } from './index.js';
9
+ /** Cloud region -> ISO country. Extend for regions you use; confirm against the provider's docs. */
10
+ export declare const CLOUD_REGION_COUNTRY: Record<string, string>;
11
+ /** The country of a provider region, or null when unknown. Accepts `core42:AE`-style sovereign-cloud signals too. */
12
+ export declare function cloudRegionCountry(provider: string, region: string): string | null;
13
+ /**
14
+ * A RegionVerifier for cloud signals (`source` like `aws:instance-identity`): your `verifyEvidence`
15
+ * checks the provider-signed document (the trust root is the provider); the region maps to a country.
16
+ */
17
+ export declare function cloudRegionVerifier(verifyEvidence: (a: RegionAttestation) => boolean | Promise<boolean>): RegionVerifier;
18
+ /** Light in fibre covers about 200 km per millisecond; a round trip bounds the distance to a landmark. */
19
+ export declare const FIBRE_KM_PER_MS = 200;
20
+ /** Is a claimed location physically consistent with measured round-trip times to known landmarks? */
21
+ export declare function latencyConsistent(measurements: Array<{
22
+ landmark: string;
23
+ rttMs: number;
24
+ distanceKm: number;
25
+ }>): {
26
+ ok: boolean;
27
+ violations: string[];
28
+ };
29
+ /**
30
+ * A RegionVerifier for TEE signals: your `verifyQuote` validates the enclave quote and returns the
31
+ * region it binds; optional latency measurements (in `evidence` as JSON) must be physically consistent.
32
+ */
33
+ export declare function teeRegionVerifier(verifyQuote: (a: RegionAttestation) => {
34
+ region: string;
35
+ } | null | Promise<{
36
+ region: string;
37
+ } | null>, distanceKm: (landmark: string, region: string) => number | undefined): RegionVerifier;
38
+ /** Localisation presets. The allowed set is your compliance team's call; these are starting points. */
39
+ export declare const SOVEREIGN_PROFILES: Record<string, {
40
+ law: string;
41
+ allowed: string[];
42
+ }>;
43
+ export declare function sovereignProfile(name: string): {
44
+ law: string;
45
+ allowed: string[];
46
+ };
47
+ /** A residency claim that inference itself (not only storage) ran in a region, bound to the model and the I/O hashes. */
48
+ export declare function buildInferenceClaim(input: {
49
+ jurisdiction: string;
50
+ model: string;
51
+ inputHash: string;
52
+ outputHash: string;
53
+ regionAttestation: RegionAttestation;
54
+ ts: string;
55
+ }): {
56
+ target: string;
57
+ payload: Record<string, unknown>;
58
+ };
59
+ /** Countries with an EU adequacy decision (the US only for Data Privacy Framework participants). Check for updates. */
60
+ export declare const EU_ADEQUACY: string[];
61
+ export interface TransferBasis {
62
+ mechanism: 'adequacy' | 'scc' | 'bcr' | 'derogation';
63
+ reference: string;
64
+ /** For the US under adequacy: the recipient is a Data Privacy Framework participant. */
65
+ dpf?: boolean;
66
+ }
67
+ /** Every exit crossing needs a transfer basis (GDPR Chapter V). Returns the crossings without a valid one. */
68
+ export declare function assessTransfers(crossings: Array<{
69
+ ts: string;
70
+ region: string;
71
+ direction: 'exit' | 'return';
72
+ }>, bases: Record<string, TransferBasis>): {
73
+ ok: boolean;
74
+ issues: {
75
+ issue: string;
76
+ ts: string;
77
+ region: string;
78
+ direction: "exit" | "return";
79
+ }[];
80
+ };
81
+ /** Provider home jurisdictions and the foreign-access law that may reach data they hold abroad. */
82
+ export declare const PROVIDER_JURISDICTION: Record<string, {
83
+ home: string;
84
+ law?: string;
85
+ }>;
86
+ /** Flag providers headquartered outside the data's jurisdiction and subject to a foreign-access law. Informational, not legal advice. */
87
+ export declare function foreignAccessExposure(providers: string[], dataJurisdiction: string[]): {
88
+ provider: string;
89
+ home: string | null;
90
+ law: string | null;
91
+ exposed: boolean;
92
+ known: boolean;
93
+ }[];
94
+ /** Primary, backup and DR copies must all be in the allowed set (the often-missed part). */
95
+ export declare function backupResidency(copies: Array<{
96
+ id: string;
97
+ kind: 'primary' | 'backup' | 'dr' | 'replica';
98
+ region: string;
99
+ }>, allowed: string[]): {
100
+ ok: boolean;
101
+ outside: {
102
+ id: string;
103
+ kind: "primary" | "backup" | "dr" | "replica";
104
+ region: string;
105
+ }[];
106
+ kinds: ("primary" | "backup" | "dr" | "replica")[];
107
+ };
108
+ /** Onward transfers: every sub-processor region must be allowed. */
109
+ export declare function subprocessorRegions(subprocessors: Array<{
110
+ name: string;
111
+ regions: string[];
112
+ }>, allowed: string[]): {
113
+ ok: boolean;
114
+ onward: {
115
+ subprocessor: string;
116
+ region: string;
117
+ }[];
118
+ };
119
+ /** Totals for a CISO view: checks by verified region, crossings and failures. */
120
+ export declare function residencyDashboard(checks: ResidencyCheck[]): {
121
+ total: number;
122
+ ok: number;
123
+ crossed: number;
124
+ unverified: number;
125
+ byRegion: Record<string, number>;
126
+ };
127
+ export type ResidencyCertificate = SignedObject<{
128
+ v: 1;
129
+ type: 'residency.certificate';
130
+ jurisdiction: string;
131
+ from: string;
132
+ to: string;
133
+ summary: ReturnType<typeof residencyDashboard>;
134
+ ts: string;
135
+ }>;
136
+ /** A signed residency statement for a period, for a supervisor. It states counts; the underlying claims are the evidence. */
137
+ export declare function residencyCertificate(input: {
138
+ jurisdiction: string;
139
+ from: string;
140
+ to: string;
141
+ checks: ResidencyCheck[];
142
+ ts?: string;
143
+ }, privateKey: Uint8Array): ResidencyCertificate;
144
+ export declare function verifyResidencyCertificate(c: ResidencyCertificate, trustedSigners?: string[]): boolean;
145
+ //# sourceMappingURL=sovereign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sovereign.d.ts","sourceRoot":"","sources":["../src/sovereign.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Sovereign residency: cloud region -> country maps, TEE + network-latency location checks,
3
+ * national profiles, inference-region claims, transfer mechanisms for crossings, provider
4
+ * foreign-access exposure, backup and sub-processor residency, a dashboard and a signed
5
+ * certificate for a period. Region signals are still authenticated by the verifier you inject.
6
+ */
7
+ import { signObject, verifySignedObject } from '@zanii/core';
8
+ import { buildResidencyClaim } from './index.js';
9
+ // ------------------------------------------------------------------------------ //
10
+ // Cloud regions
11
+ // ------------------------------------------------------------------------------ //
12
+ /** Cloud region -> ISO country. Extend for regions you use; confirm against the provider's docs. */
13
+ export const CLOUD_REGION_COUNTRY = {
14
+ 'aws:me-central-1': 'AE', 'aws:me-south-1': 'BH', 'aws:il-central-1': 'IL', 'aws:eu-central-1': 'DE', 'aws:eu-west-1': 'IE', 'aws:eu-west-3': 'FR', 'aws:eu-north-1': 'SE',
15
+ 'aws:ap-south-1': 'IN', 'aws:ap-south-2': 'IN', 'aws:ap-southeast-3': 'ID', 'aws:us-east-1': 'US', 'aws:us-west-2': 'US',
16
+ 'azure:uaenorth': 'AE', 'azure:uaecentral': 'AE', 'azure:qatarcentral': 'QA', 'azure:germanywestcentral': 'DE', 'azure:francecentral': 'FR', 'azure:westeurope': 'NL', 'azure:northeurope': 'IE',
17
+ 'azure:centralindia': 'IN', 'azure:southindia': 'IN', 'azure:eastus': 'US',
18
+ 'gcp:me-central1': 'QA', 'gcp:me-central2': 'SA', 'gcp:me-west1': 'IL', 'gcp:europe-west3': 'DE', 'gcp:europe-west1': 'BE', 'gcp:asia-south1': 'IN', 'gcp:asia-south2': 'IN', 'gcp:asia-southeast2': 'ID', 'gcp:us-central1': 'US',
19
+ 'oracle:me-dubai-1': 'AE', 'oracle:me-abudhabi-1': 'AE', 'oracle:me-jeddah-1': 'SA', 'oracle:me-riyadh-1': 'SA', 'oracle:eu-frankfurt-1': 'DE', 'oracle:ap-mumbai-1': 'IN',
20
+ };
21
+ /** The country of a provider region, or null when unknown. Accepts `core42:AE`-style sovereign-cloud signals too. */
22
+ export function cloudRegionCountry(provider, region) {
23
+ if (/^[A-Z]{2}$/.test(region))
24
+ return region;
25
+ return CLOUD_REGION_COUNTRY[`${provider.toLowerCase()}:${region}`] ?? null;
26
+ }
27
+ /**
28
+ * A RegionVerifier for cloud signals (`source` like `aws:instance-identity`): your `verifyEvidence`
29
+ * checks the provider-signed document (the trust root is the provider); the region maps to a country.
30
+ */
31
+ export function cloudRegionVerifier(verifyEvidence) {
32
+ return async (a) => {
33
+ const provider = a.source.split(':')[0] ?? '';
34
+ if (!(await verifyEvidence(a)))
35
+ return null;
36
+ const country = cloudRegionCountry(provider, a.region);
37
+ return country ? { region: country, source: a.source } : null;
38
+ };
39
+ }
40
+ // ------------------------------------------------------------------------------ //
41
+ // TEE and network latency
42
+ // ------------------------------------------------------------------------------ //
43
+ /** Light in fibre covers about 200 km per millisecond; a round trip bounds the distance to a landmark. */
44
+ export const FIBRE_KM_PER_MS = 200;
45
+ /** Is a claimed location physically consistent with measured round-trip times to known landmarks? */
46
+ export function latencyConsistent(measurements) {
47
+ const violations = measurements.filter((m) => m.distanceKm > (m.rttMs / 2) * FIBRE_KM_PER_MS).map((m) => `${m.landmark}: ${m.distanceKm} km cannot be reached in ${m.rttMs} ms round trip`);
48
+ return { ok: violations.length === 0, violations };
49
+ }
50
+ /**
51
+ * A RegionVerifier for TEE signals: your `verifyQuote` validates the enclave quote and returns the
52
+ * region it binds; optional latency measurements (in `evidence` as JSON) must be physically consistent.
53
+ */
54
+ export function teeRegionVerifier(verifyQuote, distanceKm) {
55
+ return async (a) => {
56
+ if (!a.source.startsWith('tee:'))
57
+ return null;
58
+ const q = await verifyQuote(a);
59
+ if (!q)
60
+ return null;
61
+ let rtts = [];
62
+ try {
63
+ rtts = JSON.parse(a.evidence ?? '{}').latency ?? [];
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ const m = rtts.map((r) => ({ ...r, distanceKm: distanceKm(r.landmark, q.region) })).filter((r) => r.distanceKm !== undefined);
69
+ return latencyConsistent(m).ok ? { region: q.region, source: a.source } : null;
70
+ };
71
+ }
72
+ // ------------------------------------------------------------------------------ //
73
+ // National profiles, inference, transfers, exposure
74
+ // ------------------------------------------------------------------------------ //
75
+ /** Localisation presets. The allowed set is your compliance team's call; these are starting points. */
76
+ export const SOVEREIGN_PROFILES = {
77
+ UAE: { law: 'Federal Decree-Law No. 45 of 2021 (PDPL)', allowed: ['AE'] },
78
+ KSA: { law: 'Personal Data Protection Law (Royal Decree M/19)', allowed: ['SA'] },
79
+ EU: { law: 'GDPR (Regulation (EU) 2016/679)', allowed: ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE'] },
80
+ India: { law: 'Digital Personal Data Protection Act, 2023', allowed: ['IN'] },
81
+ Indonesia: { law: 'Law No. 27 of 2022 on Personal Data Protection', allowed: ['ID'] },
82
+ };
83
+ export function sovereignProfile(name) {
84
+ const p = SOVEREIGN_PROFILES[name];
85
+ if (!p)
86
+ throw new Error(`residency: no profile '${name}' (have ${Object.keys(SOVEREIGN_PROFILES).join(', ')})`);
87
+ return p;
88
+ }
89
+ /** A residency claim that inference itself (not only storage) ran in a region, bound to the model and the I/O hashes. */
90
+ export function buildInferenceClaim(input) {
91
+ return buildResidencyClaim({ jurisdiction: input.jurisdiction, regionAttestation: input.regionAttestation, ts: input.ts, ref: `inference:${input.model}:${input.inputHash}:${input.outputHash}` });
92
+ }
93
+ /** Countries with an EU adequacy decision (the US only for Data Privacy Framework participants). Check for updates. */
94
+ export const EU_ADEQUACY = ['AD', 'AR', 'CA', 'FO', 'GG', 'IL', 'IM', 'JP', 'JE', 'NZ', 'KR', 'CH', 'GB', 'UY', 'US'];
95
+ /** Every exit crossing needs a transfer basis (GDPR Chapter V). Returns the crossings without a valid one. */
96
+ export function assessTransfers(crossings, bases) {
97
+ const issues = crossings.filter((c) => c.direction === 'exit').flatMap((c) => {
98
+ const b = bases[c.region];
99
+ if (!b)
100
+ return [{ ...c, issue: 'no transfer basis' }];
101
+ if (b.mechanism === 'adequacy' && !EU_ADEQUACY.includes(c.region))
102
+ return [{ ...c, issue: `${c.region} has no adequacy decision` }];
103
+ if (b.mechanism === 'adequacy' && c.region === 'US' && !b.dpf)
104
+ return [{ ...c, issue: 'US adequacy covers Data Privacy Framework participants only' }];
105
+ return [];
106
+ });
107
+ return { ok: issues.length === 0, issues };
108
+ }
109
+ /** Provider home jurisdictions and the foreign-access law that may reach data they hold abroad. */
110
+ export const PROVIDER_JURISDICTION = {
111
+ aws: { home: 'US', law: 'US CLOUD Act' }, azure: { home: 'US', law: 'US CLOUD Act' }, gcp: { home: 'US', law: 'US CLOUD Act' }, oracle: { home: 'US', law: 'US CLOUD Act' },
112
+ core42: { home: 'AE' }, g42: { home: 'AE' }, alibaba: { home: 'CN', law: 'PRC National Intelligence Law' }, ovh: { home: 'FR' },
113
+ };
114
+ /** Flag providers headquartered outside the data's jurisdiction and subject to a foreign-access law. Informational, not legal advice. */
115
+ export function foreignAccessExposure(providers, dataJurisdiction) {
116
+ return providers.map((p) => {
117
+ const j = PROVIDER_JURISDICTION[p.toLowerCase()];
118
+ return { provider: p, home: j?.home ?? null, law: j?.law ?? null, exposed: !!j?.law && !dataJurisdiction.includes(j.home), known: !!j };
119
+ });
120
+ }
121
+ // ------------------------------------------------------------------------------ //
122
+ // Copies, sub-processors, reporting
123
+ // ------------------------------------------------------------------------------ //
124
+ /** Primary, backup and DR copies must all be in the allowed set (the often-missed part). */
125
+ export function backupResidency(copies, allowed) {
126
+ const outside = copies.filter((c) => !allowed.includes(c.region));
127
+ return { ok: outside.length === 0, outside, kinds: [...new Set(copies.map((c) => c.kind))] };
128
+ }
129
+ /** Onward transfers: every sub-processor region must be allowed. */
130
+ export function subprocessorRegions(subprocessors, allowed) {
131
+ const onward = subprocessors.flatMap((s) => s.regions.filter((r) => !allowed.includes(r)).map((region) => ({ subprocessor: s.name, region })));
132
+ return { ok: onward.length === 0, onward };
133
+ }
134
+ /** Totals for a CISO view: checks by verified region, crossings and failures. */
135
+ export function residencyDashboard(checks) {
136
+ const byRegion = {};
137
+ for (const c of checks)
138
+ if (c.region)
139
+ byRegion[c.region] = (byRegion[c.region] ?? 0) + 1;
140
+ return { total: checks.length, ok: checks.filter((c) => c.ok).length, crossed: checks.filter((c) => c.crossed).length, unverified: checks.filter((c) => !c.region).length, byRegion };
141
+ }
142
+ /** A signed residency statement for a period, for a supervisor. It states counts; the underlying claims are the evidence. */
143
+ export function residencyCertificate(input, privateKey) {
144
+ return signObject({ v: 1, type: 'residency.certificate', jurisdiction: input.jurisdiction, from: input.from, to: input.to, summary: residencyDashboard(input.checks), ts: input.ts ?? new Date().toISOString() }, privateKey);
145
+ }
146
+ export function verifyResidencyCertificate(c, trustedSigners) {
147
+ return verifySignedObject(c) && (!trustedSigners || trustedSigners.includes(c.signer));
148
+ }
149
+ //# sourceMappingURL=sovereign.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sovereign.js","sourceRoot":"","sources":["../src/sovereign.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zanii/residency",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Prove where an agent's data physically stayed - bind a region attestation to each data touch, confirm the attested region is inside a declared jurisdiction, and emit a receipt the moment it crosses a border. Answers 'prove it never left the UAE / the EU.' The region signal is INJECTED (cloud-provider region / TEE geolocation) - we verify the binding, you supply the geo trust root; the proof is only as strong as that source.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://ledger.zanii.agency",
@@ -31,7 +31,7 @@
31
31
  "vitest": "^3.0.9"
32
32
  },
33
33
  "dependencies": {
34
- "@zanii/core": "0.4.0"
34
+ "@zanii/core": "^0.5.4"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsc -p tsconfig.build.json",
package/src/index.ts CHANGED
@@ -157,3 +157,4 @@ export function detectCrossings(
157
157
  export function residencyAllowed(effectiveScopes: string[], region: string): boolean {
158
158
  return scopesAllow(effectiveScopes, `residency.${region}`);
159
159
  }
160
+ export * from './sovereign.js';
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Sovereign residency: cloud region -> country maps, TEE + network-latency location checks,
3
+ * national profiles, inference-region claims, transfer mechanisms for crossings, provider
4
+ * foreign-access exposure, backup and sub-processor residency, a dashboard and a signed
5
+ * certificate for a period. Region signals are still authenticated by the verifier you inject.
6
+ */
7
+ import { signObject, verifySignedObject, type SignedObject } from '@zanii/core';
8
+ import { buildResidencyClaim, type RegionAttestation, type RegionVerifier, type ResidencyCheck } from './index.js';
9
+
10
+ // ------------------------------------------------------------------------------ //
11
+ // Cloud regions
12
+ // ------------------------------------------------------------------------------ //
13
+
14
+ /** Cloud region -> ISO country. Extend for regions you use; confirm against the provider's docs. */
15
+ export const CLOUD_REGION_COUNTRY: Record<string, string> = {
16
+ 'aws:me-central-1': 'AE', 'aws:me-south-1': 'BH', 'aws:il-central-1': 'IL', 'aws:eu-central-1': 'DE', 'aws:eu-west-1': 'IE', 'aws:eu-west-3': 'FR', 'aws:eu-north-1': 'SE',
17
+ 'aws:ap-south-1': 'IN', 'aws:ap-south-2': 'IN', 'aws:ap-southeast-3': 'ID', 'aws:us-east-1': 'US', 'aws:us-west-2': 'US',
18
+ 'azure:uaenorth': 'AE', 'azure:uaecentral': 'AE', 'azure:qatarcentral': 'QA', 'azure:germanywestcentral': 'DE', 'azure:francecentral': 'FR', 'azure:westeurope': 'NL', 'azure:northeurope': 'IE',
19
+ 'azure:centralindia': 'IN', 'azure:southindia': 'IN', 'azure:eastus': 'US',
20
+ 'gcp:me-central1': 'QA', 'gcp:me-central2': 'SA', 'gcp:me-west1': 'IL', 'gcp:europe-west3': 'DE', 'gcp:europe-west1': 'BE', 'gcp:asia-south1': 'IN', 'gcp:asia-south2': 'IN', 'gcp:asia-southeast2': 'ID', 'gcp:us-central1': 'US',
21
+ 'oracle:me-dubai-1': 'AE', 'oracle:me-abudhabi-1': 'AE', 'oracle:me-jeddah-1': 'SA', 'oracle:me-riyadh-1': 'SA', 'oracle:eu-frankfurt-1': 'DE', 'oracle:ap-mumbai-1': 'IN',
22
+ };
23
+
24
+ /** The country of a provider region, or null when unknown. Accepts `core42:AE`-style sovereign-cloud signals too. */
25
+ export function cloudRegionCountry(provider: string, region: string): string | null {
26
+ if (/^[A-Z]{2}$/.test(region)) return region;
27
+ return CLOUD_REGION_COUNTRY[`${provider.toLowerCase()}:${region}`] ?? null;
28
+ }
29
+
30
+ /**
31
+ * A RegionVerifier for cloud signals (`source` like `aws:instance-identity`): your `verifyEvidence`
32
+ * checks the provider-signed document (the trust root is the provider); the region maps to a country.
33
+ */
34
+ export function cloudRegionVerifier(verifyEvidence: (a: RegionAttestation) => boolean | Promise<boolean>): RegionVerifier {
35
+ return async (a) => {
36
+ const provider = a.source.split(':')[0] ?? '';
37
+ if (!(await verifyEvidence(a))) return null;
38
+ const country = cloudRegionCountry(provider, a.region);
39
+ return country ? { region: country, source: a.source } : null;
40
+ };
41
+ }
42
+
43
+ // ------------------------------------------------------------------------------ //
44
+ // TEE and network latency
45
+ // ------------------------------------------------------------------------------ //
46
+
47
+ /** Light in fibre covers about 200 km per millisecond; a round trip bounds the distance to a landmark. */
48
+ export const FIBRE_KM_PER_MS = 200;
49
+
50
+ /** Is a claimed location physically consistent with measured round-trip times to known landmarks? */
51
+ export function latencyConsistent(measurements: Array<{ landmark: string; rttMs: number; distanceKm: number }>): { ok: boolean; violations: string[] } {
52
+ const violations = measurements.filter((m) => m.distanceKm > (m.rttMs / 2) * FIBRE_KM_PER_MS).map((m) => `${m.landmark}: ${m.distanceKm} km cannot be reached in ${m.rttMs} ms round trip`);
53
+ return { ok: violations.length === 0, violations };
54
+ }
55
+
56
+ /**
57
+ * A RegionVerifier for TEE signals: your `verifyQuote` validates the enclave quote and returns the
58
+ * region it binds; optional latency measurements (in `evidence` as JSON) must be physically consistent.
59
+ */
60
+ export function teeRegionVerifier(verifyQuote: (a: RegionAttestation) => { region: string } | null | Promise<{ region: string } | null>, distanceKm: (landmark: string, region: string) => number | undefined): RegionVerifier {
61
+ return async (a) => {
62
+ if (!a.source.startsWith('tee:')) return null;
63
+ const q = await verifyQuote(a);
64
+ if (!q) return null;
65
+ let rtts: Array<{ landmark: string; rttMs: number }> = [];
66
+ try {
67
+ rtts = (JSON.parse(a.evidence ?? '{}') as { latency?: typeof rtts }).latency ?? [];
68
+ } catch {
69
+ return null;
70
+ }
71
+ const m = rtts.map((r) => ({ ...r, distanceKm: distanceKm(r.landmark, q.region) })).filter((r): r is { landmark: string; rttMs: number; distanceKm: number } => r.distanceKm !== undefined);
72
+ return latencyConsistent(m).ok ? { region: q.region, source: a.source } : null;
73
+ };
74
+ }
75
+
76
+ // ------------------------------------------------------------------------------ //
77
+ // National profiles, inference, transfers, exposure
78
+ // ------------------------------------------------------------------------------ //
79
+
80
+ /** Localisation presets. The allowed set is your compliance team's call; these are starting points. */
81
+ export const SOVEREIGN_PROFILES: Record<string, { law: string; allowed: string[] }> = {
82
+ UAE: { law: 'Federal Decree-Law No. 45 of 2021 (PDPL)', allowed: ['AE'] },
83
+ KSA: { law: 'Personal Data Protection Law (Royal Decree M/19)', allowed: ['SA'] },
84
+ EU: { law: 'GDPR (Regulation (EU) 2016/679)', allowed: ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE'] },
85
+ India: { law: 'Digital Personal Data Protection Act, 2023', allowed: ['IN'] },
86
+ Indonesia: { law: 'Law No. 27 of 2022 on Personal Data Protection', allowed: ['ID'] },
87
+ };
88
+
89
+ export function sovereignProfile(name: string) {
90
+ const p = SOVEREIGN_PROFILES[name];
91
+ if (!p) throw new Error(`residency: no profile '${name}' (have ${Object.keys(SOVEREIGN_PROFILES).join(', ')})`);
92
+ return p;
93
+ }
94
+
95
+ /** A residency claim that inference itself (not only storage) ran in a region, bound to the model and the I/O hashes. */
96
+ export function buildInferenceClaim(input: { jurisdiction: string; model: string; inputHash: string; outputHash: string; regionAttestation: RegionAttestation; ts: string }) {
97
+ return buildResidencyClaim({ jurisdiction: input.jurisdiction, regionAttestation: input.regionAttestation, ts: input.ts, ref: `inference:${input.model}:${input.inputHash}:${input.outputHash}` });
98
+ }
99
+
100
+ /** Countries with an EU adequacy decision (the US only for Data Privacy Framework participants). Check for updates. */
101
+ export const EU_ADEQUACY = ['AD', 'AR', 'CA', 'FO', 'GG', 'IL', 'IM', 'JP', 'JE', 'NZ', 'KR', 'CH', 'GB', 'UY', 'US'];
102
+
103
+ export interface TransferBasis {
104
+ mechanism: 'adequacy' | 'scc' | 'bcr' | 'derogation';
105
+ reference: string;
106
+ /** For the US under adequacy: the recipient is a Data Privacy Framework participant. */
107
+ dpf?: boolean;
108
+ }
109
+
110
+ /** Every exit crossing needs a transfer basis (GDPR Chapter V). Returns the crossings without a valid one. */
111
+ export function assessTransfers(crossings: Array<{ ts: string; region: string; direction: 'exit' | 'return' }>, bases: Record<string, TransferBasis>) {
112
+ const issues = crossings.filter((c) => c.direction === 'exit').flatMap((c) => {
113
+ const b = bases[c.region];
114
+ if (!b) return [{ ...c, issue: 'no transfer basis' }];
115
+ if (b.mechanism === 'adequacy' && !EU_ADEQUACY.includes(c.region)) return [{ ...c, issue: `${c.region} has no adequacy decision` }];
116
+ if (b.mechanism === 'adequacy' && c.region === 'US' && !b.dpf) return [{ ...c, issue: 'US adequacy covers Data Privacy Framework participants only' }];
117
+ return [];
118
+ });
119
+ return { ok: issues.length === 0, issues };
120
+ }
121
+
122
+ /** Provider home jurisdictions and the foreign-access law that may reach data they hold abroad. */
123
+ export const PROVIDER_JURISDICTION: Record<string, { home: string; law?: string }> = {
124
+ aws: { home: 'US', law: 'US CLOUD Act' }, azure: { home: 'US', law: 'US CLOUD Act' }, gcp: { home: 'US', law: 'US CLOUD Act' }, oracle: { home: 'US', law: 'US CLOUD Act' },
125
+ core42: { home: 'AE' }, g42: { home: 'AE' }, alibaba: { home: 'CN', law: 'PRC National Intelligence Law' }, ovh: { home: 'FR' },
126
+ };
127
+
128
+ /** Flag providers headquartered outside the data's jurisdiction and subject to a foreign-access law. Informational, not legal advice. */
129
+ export function foreignAccessExposure(providers: string[], dataJurisdiction: string[]) {
130
+ return providers.map((p) => {
131
+ const j = PROVIDER_JURISDICTION[p.toLowerCase()];
132
+ return { provider: p, home: j?.home ?? null, law: j?.law ?? null, exposed: !!j?.law && !dataJurisdiction.includes(j.home), known: !!j };
133
+ });
134
+ }
135
+
136
+ // ------------------------------------------------------------------------------ //
137
+ // Copies, sub-processors, reporting
138
+ // ------------------------------------------------------------------------------ //
139
+
140
+ /** Primary, backup and DR copies must all be in the allowed set (the often-missed part). */
141
+ export function backupResidency(copies: Array<{ id: string; kind: 'primary' | 'backup' | 'dr' | 'replica'; region: string }>, allowed: string[]) {
142
+ const outside = copies.filter((c) => !allowed.includes(c.region));
143
+ return { ok: outside.length === 0, outside, kinds: [...new Set(copies.map((c) => c.kind))] };
144
+ }
145
+
146
+ /** Onward transfers: every sub-processor region must be allowed. */
147
+ export function subprocessorRegions(subprocessors: Array<{ name: string; regions: string[] }>, allowed: string[]) {
148
+ const onward = subprocessors.flatMap((s) => s.regions.filter((r) => !allowed.includes(r)).map((region) => ({ subprocessor: s.name, region })));
149
+ return { ok: onward.length === 0, onward };
150
+ }
151
+
152
+ /** Totals for a CISO view: checks by verified region, crossings and failures. */
153
+ export function residencyDashboard(checks: ResidencyCheck[]) {
154
+ const byRegion: Record<string, number> = {};
155
+ for (const c of checks) if (c.region) byRegion[c.region] = (byRegion[c.region] ?? 0) + 1;
156
+ return { total: checks.length, ok: checks.filter((c) => c.ok).length, crossed: checks.filter((c) => c.crossed).length, unverified: checks.filter((c) => !c.region).length, byRegion };
157
+ }
158
+
159
+ export type ResidencyCertificate = SignedObject<{ v: 1; type: 'residency.certificate'; jurisdiction: string; from: string; to: string; summary: ReturnType<typeof residencyDashboard>; ts: string }>;
160
+
161
+ /** A signed residency statement for a period, for a supervisor. It states counts; the underlying claims are the evidence. */
162
+ export function residencyCertificate(input: { jurisdiction: string; from: string; to: string; checks: ResidencyCheck[]; ts?: string }, privateKey: Uint8Array): ResidencyCertificate {
163
+ return signObject({ v: 1 as const, type: 'residency.certificate' as const, jurisdiction: input.jurisdiction, from: input.from, to: input.to, summary: residencyDashboard(input.checks), ts: input.ts ?? new Date().toISOString() }, privateKey);
164
+ }
165
+
166
+ export function verifyResidencyCertificate(c: ResidencyCertificate, trustedSigners?: string[]): boolean {
167
+ return verifySignedObject(c) && (!trustedSigners || trustedSigners.includes(c.signer));
168
+ }