@pithy-sh/core 0.11.0 → 0.12.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.
- package/dist/audit/recorder.d.ts +10 -2
- package/dist/audit/recorder.d.ts.map +1 -1
- package/dist/capability/capability.d.ts +12 -0
- package/dist/capability/capability.d.ts.map +1 -1
- package/dist/capability/capability.js +2 -0
- package/dist/capability/purge.d.ts +80 -0
- package/dist/capability/purge.d.ts.map +1 -0
- package/dist/capability/purge.js +76 -0
- package/dist/cli/commandCatalog.generated.d.ts +54 -2
- package/dist/cli/commandCatalog.generated.d.ts.map +1 -1
- package/dist/cli/commandCatalog.generated.js +55 -0
- package/dist/cli/commandFacts.d.ts +1 -0
- package/dist/cli/commandFacts.d.ts.map +1 -1
- package/dist/cli/commandFacts.js +1 -0
- package/dist/controlPlane/capability.d.ts.map +1 -1
- package/dist/controlPlane/capability.js +7 -0
- package/dist/controlPlane/data/connection.d.ts +2 -12
- package/dist/controlPlane/data/connection.d.ts.map +1 -1
- package/dist/controlPlane/data/connection.js +1 -1
- package/dist/controlPlane/discovery/adminRoute.d.ts +29 -0
- package/dist/controlPlane/discovery/adminRoute.d.ts.map +1 -1
- package/dist/controlPlane/discovery/adminRoute.js +3 -0
- package/dist/controlPlane/error/errors.d.ts +4 -3
- package/dist/controlPlane/error/errors.d.ts.map +1 -1
- package/dist/controlPlane/http/handlers.d.ts +79 -0
- package/dist/controlPlane/http/handlers.d.ts.map +1 -1
- package/dist/controlPlane/http/handlers.js +37 -3
- package/dist/controlPlane/http/responses.d.ts +98 -0
- package/dist/controlPlane/http/responses.d.ts.map +1 -1
- package/dist/controlPlane/http/responses.js +41 -1
- package/dist/controlPlane/http/routes.d.ts +1 -0
- package/dist/controlPlane/http/routes.d.ts.map +1 -1
- package/dist/controlPlane/http/routes.js +17 -3
- package/dist/controlPlane/scope/scope.d.ts +13 -3
- package/dist/controlPlane/scope/scope.d.ts.map +1 -1
- package/dist/controlPlane/scope/scope.js +14 -4
- package/dist/createBackend.d.ts.map +1 -1
- package/dist/createBackend.js +2 -0
- package/dist/crypto/envelope.d.ts +86 -0
- package/dist/crypto/envelope.d.ts.map +1 -0
- package/dist/crypto/envelope.js +129 -0
- package/dist/crypto/fieldKeys.d.ts +41 -0
- package/dist/crypto/fieldKeys.d.ts.map +1 -0
- package/dist/crypto/fieldKeys.js +56 -0
- package/dist/data/codecs.d.ts +23 -10
- package/dist/data/codecs.d.ts.map +1 -1
- package/dist/data/codecs.js +50 -36
- package/dist/error/extend.d.ts +6 -5
- package/dist/error/extend.d.ts.map +1 -1
- package/dist/error/http.d.ts +24 -0
- package/dist/error/http.d.ts.map +1 -1
- package/dist/error/payload.d.ts +48 -0
- package/dist/error/payload.d.ts.map +1 -1
- package/dist/error/payload.js +16 -0
- package/dist/error/pithyError.d.ts +18 -7
- package/dist/error/pithyError.d.ts.map +1 -1
- package/dist/error/pithyError.js +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/logger/logger.d.ts +12 -5
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/record.d.ts +14 -0
- package/dist/logger/record.d.ts.map +1 -1
- package/dist/privacy/blindIndex.d.ts +27 -0
- package/dist/privacy/blindIndex.d.ts.map +1 -0
- package/dist/privacy/blindIndex.js +57 -0
- package/dist/privacy/classes.d.ts +142 -0
- package/dist/privacy/classes.d.ts.map +1 -0
- package/dist/privacy/classes.js +209 -0
- package/dist/privacy/classify.d.ts +336 -0
- package/dist/privacy/classify.d.ts.map +1 -0
- package/dist/privacy/classify.js +1024 -0
- package/dist/privacy/encrypted.d.ts +210 -0
- package/dist/privacy/encrypted.d.ts.map +1 -0
- package/dist/privacy/encrypted.js +350 -0
- package/dist/privacy/encryptedColumns.d.ts +64 -0
- package/dist/privacy/encryptedColumns.d.ts.map +1 -0
- package/dist/privacy/encryptedColumns.js +134 -0
- package/dist/privacy/fieldRotation.d.ts +34 -0
- package/dist/privacy/fieldRotation.d.ts.map +1 -0
- package/dist/privacy/fieldRotation.js +186 -0
- package/dist/privacy/inventory.d.ts +12 -0
- package/dist/privacy/inventory.d.ts.map +1 -0
- package/dist/privacy/inventory.js +154 -0
- package/dist/privacy/posture.d.ts +114 -0
- package/dist/privacy/posture.d.ts.map +1 -0
- package/dist/privacy/posture.js +136 -0
- package/dist/privacy/redact.d.ts +7 -0
- package/dist/privacy/redact.d.ts.map +1 -0
- package/dist/privacy/redact.js +404 -0
- package/dist/privacy/report.d.ts +58 -0
- package/dist/privacy/report.d.ts.map +1 -0
- package/dist/privacy/report.js +15 -0
- package/dist/privacy/retirement.d.ts +68 -0
- package/dist/privacy/retirement.d.ts.map +1 -0
- package/dist/privacy/retirement.js +72 -0
- package/dist/privacy/sealed.d.ts +87 -0
- package/dist/privacy/sealed.d.ts.map +1 -0
- package/dist/privacy/sealed.js +221 -0
- package/dist/privacy/types.d.ts +559 -0
- package/dist/privacy/types.d.ts.map +1 -0
- package/dist/privacy/types.js +2 -0
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/package.json +1 -1
- package/src/audit/recorder.ts +10 -2
- package/src/capability/capability.ts +15 -0
- package/src/capability/purge.ts +124 -0
- package/src/cli/commandCatalog.generated.ts +59 -0
- package/src/cli/commandFacts.ts +1 -0
- package/src/controlPlane/capability.ts +11 -0
- package/src/controlPlane/discovery/adminRoute.ts +11 -0
- package/src/controlPlane/error/errors.ts +4 -3
- package/src/controlPlane/http/handlers.ts +57 -4
- package/src/controlPlane/http/responses.ts +100 -0
- package/src/controlPlane/http/routes.ts +31 -1
- package/src/controlPlane/scope/scope.ts +14 -3
- package/src/controlPlane/token/base64url.ts +1 -1
- package/src/createBackend.ts +4 -0
- package/src/crypto/envelope.ts +196 -0
- package/src/crypto/fieldKeys.ts +76 -0
- package/src/data/codecs.ts +69 -37
- package/src/error/extend.ts +6 -5
- package/src/error/payload.ts +42 -0
- package/src/error/pithyError.ts +21 -7
- package/src/index.ts +1 -0
- package/src/logger/logger.ts +12 -5
- package/src/privacy/blindIndex.ts +81 -0
- package/src/privacy/classes.ts +277 -0
- package/src/privacy/classify.ts +1447 -0
- package/src/privacy/encrypted.ts +513 -0
- package/src/privacy/encryptedColumns.ts +185 -0
- package/src/privacy/fieldRotation.ts +234 -0
- package/src/privacy/inventory.ts +147 -0
- package/src/privacy/posture.ts +205 -0
- package/src/privacy/redact.ts +423 -0
- package/src/privacy/report.ts +64 -0
- package/src/privacy/retirement.ts +102 -0
- package/src/privacy/sealed.ts +323 -0
- package/src/privacy/types.ts +804 -0
- package/src/version.generated.ts +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
import { defineCapability } from "../capability/capability.js";
|
|
4
|
+
import { readRetirement } from "../privacy/fieldRotation.js";
|
|
5
|
+
import { lazyPrivacyInventory } from "../privacy/inventory.js";
|
|
4
6
|
import { PACKAGE_NAME, PACKAGE_VERSION } from "../version.generated.js";
|
|
5
7
|
import "../worker/identity.js";
|
|
6
8
|
import { ControlPlaneConfig } from "./config/config.js";
|
|
@@ -87,6 +89,8 @@ function controlplane(options = {}) {
|
|
|
87
89
|
let composed = [];
|
|
88
90
|
let health = /* @__PURE__ */ new Map();
|
|
89
91
|
let migrationDatabases = [];
|
|
92
|
+
let composedCapabilities = [];
|
|
93
|
+
const privacy = lazyPrivacyInventory(() => composedCapabilities);
|
|
90
94
|
return {
|
|
91
95
|
...defineCapability({
|
|
92
96
|
name: "controlplane",
|
|
@@ -118,6 +122,7 @@ function controlplane(options = {}) {
|
|
|
118
122
|
}));
|
|
119
123
|
health = capabilityHealthSources(capabilities);
|
|
120
124
|
migrationDatabases = composeMigrationDatabases(capabilities);
|
|
125
|
+
composedCapabilities = [...capabilities];
|
|
121
126
|
},
|
|
122
127
|
middleware: [(app) => {
|
|
123
128
|
app.use("*", async (c, next) => {
|
|
@@ -145,6 +150,8 @@ function controlplane(options = {}) {
|
|
|
145
150
|
composedCapabilities: () => composed,
|
|
146
151
|
composedHealth: () => health,
|
|
147
152
|
composedMigrations: () => migrationDatabases,
|
|
153
|
+
privacyInventory: privacy,
|
|
154
|
+
retirement: (env) => readRetirement(env, composedCapabilities),
|
|
148
155
|
now
|
|
149
156
|
});
|
|
150
157
|
}
|
|
@@ -99,18 +99,8 @@ export declare const ControlPlaneConnection: z.ZodObject<{
|
|
|
99
99
|
script: "script";
|
|
100
100
|
}>>>;
|
|
101
101
|
purpose: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
102
|
-
scopes:
|
|
103
|
-
keys:
|
|
104
|
-
keyId: z.ZodString;
|
|
105
|
-
publicKey: z.ZodObject<{
|
|
106
|
-
kty: z.ZodLiteral<"OKP">;
|
|
107
|
-
crv: z.ZodLiteral<"Ed25519">;
|
|
108
|
-
x: z.ZodString;
|
|
109
|
-
}, z.core.$strip>;
|
|
110
|
-
validFrom: z.ZodCodec<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodDate]>, z.ZodDate>;
|
|
111
|
-
validUntil: z.ZodNullable<z.ZodCodec<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodDate]>, z.ZodDate>>;
|
|
112
|
-
revokedAt: z.ZodNullable<z.ZodCodec<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodDate]>, z.ZodDate>>;
|
|
113
|
-
}, z.core.$strip>>]>, z.ZodArray<z.ZodObject<{
|
|
102
|
+
scopes: import("../../data/codecs").SqliteJson<z.ZodArray<z.ZodString>>;
|
|
103
|
+
keys: import("../../data/codecs").SqliteJson<z.ZodArray<z.ZodObject<{
|
|
114
104
|
keyId: z.ZodString;
|
|
115
105
|
publicKey: z.ZodObject<{
|
|
116
106
|
kty: z.ZodLiteral<"OKP">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/data/connection.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;GASG;AAEH,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB;;;;iBAgBoF,CAAC;AAClH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;iBAoBoF,CAAC;AAC/G,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB;;;;EAI/B,CAAC;AACJ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE3E;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,YAK7B,CAAC;AACJ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEvE,8GAA8G;AAC9G,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAiB1C;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,aAW3B,CAAC;AACJ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/data/connection.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;GASG;AAEH,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB;;;;iBAgBoF,CAAC;AAClH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;iBAoBoF,CAAC;AAC/G,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB;;;;EAI/B,CAAC;AACJ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE3E;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,YAK7B,CAAC;AACJ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEvE,8GAA8G;AAC9G,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAiB1C;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,aAW3B,CAAC;AACJ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkEhC,CAAC;AACJ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC7E,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
import { ControlPlaneScope } from "../scope/scope.js";
|
|
4
3
|
import { JsonDate, SQLiteDate, sqliteJson } from "../../data/codecs.js";
|
|
4
|
+
import { ControlPlaneScope } from "../scope/scope.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
//#region src/controlPlane/data/connection.ts
|
|
7
7
|
/**
|
|
@@ -218,6 +218,35 @@ export declare const ControlPlaneManifest: z.ZodObject<{
|
|
|
218
218
|
environment: z.ZodString;
|
|
219
219
|
connectionId: z.ZodString;
|
|
220
220
|
version: z.ZodNullable<z.ZodString>;
|
|
221
|
+
versionCreatedAt: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
|
|
222
|
+
privacy: z.ZodOptional<z.ZodObject<{
|
|
223
|
+
declared: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
224
|
+
observed: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
225
|
+
counts: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
226
|
+
observedNotDeclared: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
227
|
+
declaredNotObserved: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
228
|
+
consoleGate: z.ZodEnum<{
|
|
229
|
+
enforced: "enforced";
|
|
230
|
+
not_required: "not_required";
|
|
231
|
+
unattested: "unattested";
|
|
232
|
+
unverifiable: "unverifiable";
|
|
233
|
+
}>;
|
|
234
|
+
consoleGateReason: z.ZodNullable<z.ZodString>;
|
|
235
|
+
attestedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
236
|
+
sources: z.ZodArray<z.ZodEnum<{
|
|
237
|
+
d1: "d1";
|
|
238
|
+
kv: "kv";
|
|
239
|
+
}>>;
|
|
240
|
+
retirement: z.ZodOptional<z.ZodObject<{
|
|
241
|
+
blocked: z.ZodBoolean;
|
|
242
|
+
reasons: z.ZodArray<z.ZodEnum<{
|
|
243
|
+
"incomplete-coverage": "incomplete-coverage";
|
|
244
|
+
stale: "stale";
|
|
245
|
+
unrotatable: "unrotatable";
|
|
246
|
+
}>>;
|
|
247
|
+
liveVersions: z.ZodNumber;
|
|
248
|
+
}, z.core.$strip>>;
|
|
249
|
+
}, z.core.$strip>>;
|
|
221
250
|
capabilities: z.ZodArray<z.ZodCodec<z.ZodObject<{
|
|
222
251
|
name: z.ZodString;
|
|
223
252
|
version: z.ZodNullable<z.ZodString>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adminRoute.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/discovery/adminRoute.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"adminRoute.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/discovery/adminRoute.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB;;;;;;;;;;;;;;;;;GAiBG;AAEH,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB;;;;;;EAE8B,CAAC;AAC5D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE,oFAAoF;AACpF,eAAO,MAAM,UAAU;;;;;;;;;;;iBAmBpB,CAAC;AACJ,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqD/B,CAAC;AACJ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAiD1E,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsC9B,CAAC;AACJ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiCkE,CAAC;AACpG,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
import { ControlPlaneScope } from "../scope/scope.js";
|
|
4
4
|
import { CapabilityHealthReport, HealthSummary, HealthSummaryKey, healthReport, healthWire } from "./healthSummary.js";
|
|
5
|
+
import { PrivacyPosture } from "../../privacy/posture.js";
|
|
5
6
|
import { ManifestConfigKey, ManifestConfigValues } from "./configuration.js";
|
|
6
7
|
import { z } from "zod";
|
|
7
8
|
//#region src/controlPlane/discovery/adminRoute.ts
|
|
@@ -138,6 +139,8 @@ const ControlPlaneManifest = z.object({
|
|
|
138
139
|
environment: z.string().describe("The environment this connection is bound to, echoed so a client can label what it is looking at."),
|
|
139
140
|
connectionId: z.string().describe("The connection this call authenticated as."),
|
|
140
141
|
version: z.string().nullable().describe("The Cloudflare version id of the build answering this call, from the `CF_VERSION_METADATA` binding, or null where the binding is absent. Opaque and per-deploy: it identifies which build is running, never which features it has. Null is honest — a Worker scaffolded before the binding was declared genuinely cannot say."),
|
|
142
|
+
versionCreatedAt: z.iso.datetime().nullable().optional().describe("When the version answering this call was uploaded, ISO-8601, from the same `CF_VERSION_METADATA` binding as `version` — or null where the binding is absent. The id alone cannot tell a deploy from a rollback: a rollback reactivates an existing version, so the id returns to one already seen while this moves backwards. Relayed, never interpreted. Absent from a Worker older than #132."),
|
|
143
|
+
privacy: PrivacyPosture.optional().describe("What this project declares about privacy and what its running code holds: classes and counts, never field names (`GET /control-plane/privacy` has those, behind `privacy:read`). Present on every Worker from #132, `declared` explicitly empty when nothing was declared; absent from an older Worker."),
|
|
141
144
|
capabilities: z.array(CapabilityDescriptor).describe("Every capability composed into this Worker, in composition order with the adopter's own app last. A capability absent here has no data to show, which is a fact the client discovers rather than a setting anybody maintains."),
|
|
142
145
|
grantedScopes: z.array(ControlPlaneScope).describe("Every scope this connection holds. Together with each route's own `scope`, this is what tells a client which operations to offer and which to hide.")
|
|
143
146
|
}).describe("What this Worker is, what it composes, and how to call the admin surface it exposes.");
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
import { PithyError } from "../../error/pithyError";
|
|
4
4
|
import type { MessageParams } from "../../i18n/catalog";
|
|
5
|
+
import type { UnmarkedString } from "../../privacy/types";
|
|
5
6
|
/**
|
|
6
7
|
* The `control-plane` strategy's throw sugar. The `controlplane/*` codes live in core's closed
|
|
7
8
|
* `KitErrorPayload` union (CLAUDE.md §Errors); these subclasses are the vehicles that set one.
|
|
@@ -16,9 +17,9 @@ import type { MessageParams } from "../../i18n/catalog";
|
|
|
16
17
|
* the response into an oracle that tells an attacker exactly how far they got.
|
|
17
18
|
*/
|
|
18
19
|
interface ControlPlaneErrorArgs {
|
|
19
|
-
message?:
|
|
20
|
-
action?:
|
|
21
|
-
detail?:
|
|
20
|
+
message?: UnmarkedString;
|
|
21
|
+
action?: UnmarkedString;
|
|
22
|
+
detail?: UnmarkedString;
|
|
22
23
|
/**
|
|
23
24
|
* Values a translating client interpolates into its own wording for this code. Client-facing, so —
|
|
24
25
|
* unlike `action` and `detail` — these cross the boundary with `message`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/error/errors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/error/errors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;;;;;;;;;GAYG;AAEH,UAAU,qBAAqB;IAC7B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,6BAA8B,SAAQ,UAAU;IAC3D,YAAY,IAAI,GAAE,qBAA0B,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAc1E;CACF;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,UAAU;IAChE,YAAY,IAAI,GAAE,qBAA0B,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAc1E;CACF;AAED,sEAAsE;AACtE,qBAAa,kCAAmC,SAAQ,UAAU;IAChE,YAAY,IAAI,GAAE,qBAA0B,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAc1E;CACF;AAED,0DAA0D;AAC1D,qBAAa,4BAA6B,SAAQ,UAAU;IAC1D,YAAY,IAAI,GAAE,qBAA0B,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAY1E;CACF;AAED;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,UAAU;IAC1D,YAAY,IAAI,GAAE,qBAA0B,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAY1E;CACF"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
import type { Context } from "hono";
|
|
4
4
|
import type { PithyHonoEnv } from "../../capability/capability";
|
|
5
|
+
import type { PrivacyInventory } from "../../privacy/report";
|
|
6
|
+
import type { RetirementVerdict } from "../../privacy/retirement";
|
|
5
7
|
import type { ControlPlaneConfig } from "../config/config";
|
|
6
8
|
import { type ControlPlaneDatabase } from "../data/tables";
|
|
7
9
|
import type { CapabilityDeclaration } from "../discovery/adminRoute";
|
|
@@ -37,6 +39,16 @@ export interface ControlPlaneHandlerDeps {
|
|
|
37
39
|
* `compose` hook through `collectMigrationSets`, the function `pithy migrate` composes with (#729).
|
|
38
40
|
*/
|
|
39
41
|
composedMigrations: () => readonly ComposedMigrationDatabase[];
|
|
42
|
+
/**
|
|
43
|
+
* The privacy inventory of every storage schema this Worker composed (#132), walked on the first call and
|
|
44
|
+
* cached for the isolate. A thunk, so a Worker whose control plane is never called never walks.
|
|
45
|
+
*/
|
|
46
|
+
privacyInventory: () => PrivacyInventory;
|
|
47
|
+
/**
|
|
48
|
+
* The field key's retirement verdict (#390): the guard over this Worker's encrypted columns, read through its own
|
|
49
|
+
* bindings. Never throws: whatever it cannot read is incomplete coverage.
|
|
50
|
+
*/
|
|
51
|
+
retirement: (env: Record<string, unknown>) => Promise<RetirementVerdict>;
|
|
40
52
|
/** The clock, injected so a test can stand at any instant. */
|
|
41
53
|
now: () => Date;
|
|
42
54
|
}
|
|
@@ -79,6 +91,25 @@ export declare function manifestHandler(deps: ControlPlaneHandlerDeps): (c: Cont
|
|
|
79
91
|
environment: string;
|
|
80
92
|
connectionId: string;
|
|
81
93
|
version: string | null;
|
|
94
|
+
versionCreatedAt: string | null;
|
|
95
|
+
privacy: {
|
|
96
|
+
declared: string[] | null;
|
|
97
|
+
observed: string[] | null;
|
|
98
|
+
counts: {
|
|
99
|
+
[x: string]: number;
|
|
100
|
+
} | null;
|
|
101
|
+
observedNotDeclared: string[] | null;
|
|
102
|
+
declaredNotObserved: string[] | null;
|
|
103
|
+
consoleGate: "enforced" | "not_required" | "unattested" | "unverifiable";
|
|
104
|
+
consoleGateReason: string | null;
|
|
105
|
+
attestedAt: string | null;
|
|
106
|
+
sources: ("d1" | "kv")[];
|
|
107
|
+
retirement: {
|
|
108
|
+
blocked: boolean;
|
|
109
|
+
reasons: ("incomplete-coverage" | "stale" | "unrotatable")[];
|
|
110
|
+
liveVersions: number;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
82
113
|
capabilities: {
|
|
83
114
|
health: import("../..").HealthSummary | null;
|
|
84
115
|
healthUnavailable: boolean;
|
|
@@ -239,4 +270,52 @@ export declare function expireKeyHandler(deps: ControlPlaneHandlerDeps): (c: Con
|
|
|
239
270
|
revokedAt: string | null;
|
|
240
271
|
}[];
|
|
241
272
|
}, import("hono/utils/http-status").ContentfulStatusCode, "json">>;
|
|
273
|
+
/**
|
|
274
|
+
* `GET /control-plane/privacy` — the full privacy inventory (#132).
|
|
275
|
+
*
|
|
276
|
+
* Every storage schema this Worker composed that holds a marked field, each field's path and class, and where it
|
|
277
|
+
* is stored — derived from the running code, so unmarking a field removes it on the next deploy with nothing in
|
|
278
|
+
* between. Behind `privacy:read`, because field names are the kind of thing an adopter may withhold from a client
|
|
279
|
+
* that has no business seeing them. Read-only.
|
|
280
|
+
*/
|
|
281
|
+
export declare function privacyHandler(deps: ControlPlaneHandlerDeps): (c: Context<PithyHonoEnv>) => Promise<Response & import("hono").TypedResponse<{
|
|
282
|
+
environment: string;
|
|
283
|
+
posture: {
|
|
284
|
+
declared: string[] | null;
|
|
285
|
+
observed: string[] | null;
|
|
286
|
+
counts: {
|
|
287
|
+
[x: string]: number;
|
|
288
|
+
} | null;
|
|
289
|
+
observedNotDeclared: string[] | null;
|
|
290
|
+
declaredNotObserved: string[] | null;
|
|
291
|
+
consoleGate: "enforced" | "not_required" | "unattested" | "unverifiable";
|
|
292
|
+
consoleGateReason: string | null;
|
|
293
|
+
attestedAt: string | null;
|
|
294
|
+
sources: ("d1" | "kv")[];
|
|
295
|
+
retirement: {
|
|
296
|
+
blocked: boolean;
|
|
297
|
+
reasons: ("incomplete-coverage" | "stale" | "unrotatable")[];
|
|
298
|
+
liveVersions: number;
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
schemasWalked: number;
|
|
302
|
+
schemas: {
|
|
303
|
+
capability: string;
|
|
304
|
+
storage: import("../../privacy/report").PrivacySource;
|
|
305
|
+
container: string;
|
|
306
|
+
name: string;
|
|
307
|
+
fields: {
|
|
308
|
+
path: string;
|
|
309
|
+
class: string;
|
|
310
|
+
truncated?: true;
|
|
311
|
+
sameAs?: string;
|
|
312
|
+
encryptedAtRest?: boolean;
|
|
313
|
+
unrotatable?: true;
|
|
314
|
+
}[];
|
|
315
|
+
encrypted: {
|
|
316
|
+
path: string;
|
|
317
|
+
unrotatable?: true;
|
|
318
|
+
}[];
|
|
319
|
+
}[];
|
|
320
|
+
}, import("hono/utils/http-status").ContentfulStatusCode, "json">>;
|
|
242
321
|
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/http/handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/http/handlers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAI3D,OAAO,EAAmC,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC5F,OAAO,KAAK,EAAE,qBAAqB,EAA4B,MAAM,yBAAyB,CAAC;AAC/F,OAAO,EAAE,KAAK,sBAAsB,EAAwB,MAAM,qBAAqB,CAAC;AAGxF,OAAO,EAAE,KAAK,yBAAyB,EAA0B,MAAM,kCAAkC,CAAC;AAU1G,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAuBvF,yGAAyG;AACzG,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,MAAM,EAAE,kBAAkB,CAAC;IAC3B,oEAAoE;IACpE,QAAQ,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,oBAAoB,CAAC;IAC7D;;;;;;;;OAQG;IACH,oBAAoB,EAAE,MAAM,SAAS,qBAAqB,EAAE,CAAC;IAC7D;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAClE;;;OAGG;IACH,kBAAkB,EAAE,MAAM,SAAS,yBAAyB,EAAE,CAAC;IAC/D;;;OAGG;IACH,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;IACzC;;;OAGG;IACH,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACzE,8DAA8D;IAC9D,GAAG,EAAE,MAAM,IAAI,CAAC;CACjB;AAgED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,uBAAuB,OAC5C,OAAO,CAAC,YAAY,CAAC;;;;;;kEAUjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,uBAAuB,OAC1C,OAAO,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAoCvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,uBAAuB,OAC5C,OAAO,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAgBvC;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,IAAI,EAAE,uBAAuB,OAC1C,OAAO,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;mEAcvC;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,uBAAuB,OAC7C,OAAO,CAAC,YAAY,CAAC,QAAQ,kBAAkB;;;;;;;;;;;;;;iBAoDjE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,OAC3C,OAAO,CAAC,YAAY,CAAC,UAAU,eAAe,QAAQ,gBAAgB;;;;;;;;;;;;;;mEA8CxF;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,uBAAuB,OACzC,OAAO,CAAC,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mEAiBvC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
import {
|
|
3
|
+
import { workerVersionMetadata } from "../../worker/identity.js";
|
|
4
4
|
import { ControlPlaneConnection } from "../data/connection.js";
|
|
5
5
|
import { CONTROL_PLANE_CONNECTIONS_TABLE } from "../data/tables.js";
|
|
6
6
|
import { healthWire } from "../discovery/healthSummary.js";
|
|
@@ -8,6 +8,7 @@ import { readCapabilityHealth } from "../discovery/health.js";
|
|
|
8
8
|
import { ControlPlaneAuditActions, safeEmit } from "../audit/actions.js";
|
|
9
9
|
import { ControlPlaneInvalidCredentialError, ControlPlaneKeyConflictError } from "../error/errors.js";
|
|
10
10
|
import { appendKey, expireKey, pruneKeys } from "../data/keyLifecycle.js";
|
|
11
|
+
import { privacyAttestation, privacyPosture } from "../../privacy/posture.js";
|
|
11
12
|
import { causeMessage } from "../../error/cause.js";
|
|
12
13
|
import { readDatabaseMigrations } from "../migrationState/migrationState.js";
|
|
13
14
|
//#region src/controlPlane/http/handlers.ts
|
|
@@ -114,10 +115,16 @@ function manifestHandler(deps) {
|
|
|
114
115
|
...declaration,
|
|
115
116
|
...healthWire(await readCapabilityHealth(sources.get(declaration.name), context.grantedScopes, (source) => source.read(c)))
|
|
116
117
|
})));
|
|
118
|
+
const build = workerVersionMetadata(c.env);
|
|
117
119
|
return c.json({
|
|
118
120
|
environment: context.environment,
|
|
119
121
|
connectionId: context.connectionId,
|
|
120
|
-
version:
|
|
122
|
+
version: build.id,
|
|
123
|
+
versionCreatedAt: build.createdAt,
|
|
124
|
+
privacy: {
|
|
125
|
+
...privacyPosture(privacyAttestation(c.env), deps.privacyInventory),
|
|
126
|
+
retirement: await deps.retirement(c.env)
|
|
127
|
+
},
|
|
121
128
|
capabilities,
|
|
122
129
|
grantedScopes: [...context.grantedScopes]
|
|
123
130
|
});
|
|
@@ -272,5 +279,32 @@ function expireKeyHandler(deps) {
|
|
|
272
279
|
});
|
|
273
280
|
};
|
|
274
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* `GET /control-plane/privacy` — the full privacy inventory (#132).
|
|
284
|
+
*
|
|
285
|
+
* Every storage schema this Worker composed that holds a marked field, each field's path and class, and where it
|
|
286
|
+
* is stored — derived from the running code, so unmarking a field removes it on the next deploy with nothing in
|
|
287
|
+
* between. Behind `privacy:read`, because field names are the kind of thing an adopter may withhold from a client
|
|
288
|
+
* that has no business seeing them. Read-only.
|
|
289
|
+
*/
|
|
290
|
+
function privacyHandler(deps) {
|
|
291
|
+
return async (c) => {
|
|
292
|
+
const context = caller(c);
|
|
293
|
+
const inventory = deps.privacyInventory();
|
|
294
|
+
return c.json({
|
|
295
|
+
environment: context.environment,
|
|
296
|
+
posture: {
|
|
297
|
+
...privacyPosture(privacyAttestation(c.env), () => inventory),
|
|
298
|
+
retirement: await deps.retirement(c.env)
|
|
299
|
+
},
|
|
300
|
+
schemasWalked: inventory.schemasWalked,
|
|
301
|
+
schemas: inventory.schemas.map((schema) => ({
|
|
302
|
+
...schema,
|
|
303
|
+
fields: schema.fields.map((field) => ({ ...field })),
|
|
304
|
+
encrypted: schema.encrypted.map((field) => ({ ...field }))
|
|
305
|
+
}))
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
}
|
|
275
309
|
//#endregion
|
|
276
|
-
export { expireKeyHandler, listKeysHandler, manifestHandler, migrationsHandler, pingHandler, registerKeyHandler };
|
|
310
|
+
export { expireKeyHandler, listKeysHandler, manifestHandler, migrationsHandler, pingHandler, privacyHandler, registerKeyHandler };
|
|
@@ -245,4 +245,102 @@ export declare const ControlPlaneMigrationsResponse: z.ZodObject<{
|
|
|
245
245
|
}, z.core.$strip>], "state">>;
|
|
246
246
|
}, z.core.$strip>;
|
|
247
247
|
export type ControlPlaneMigrationsResponse = z.output<typeof ControlPlaneMigrationsResponse>;
|
|
248
|
+
/**
|
|
249
|
+
* One marked field, as `GET {basePath}/privacy` reports it (#132).
|
|
250
|
+
*
|
|
251
|
+
* **The per-field record.** Since #390 it says whether the field rests encrypted beside `class`, so "which of
|
|
252
|
+
* your PHI fields are encrypted" is a derivation over this list rather than a second inventory to keep.
|
|
253
|
+
*/
|
|
254
|
+
export declare const PrivacyFieldView: z.ZodObject<{
|
|
255
|
+
path: z.ZodString;
|
|
256
|
+
class: z.ZodString;
|
|
257
|
+
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
258
|
+
sameAs: z.ZodOptional<z.ZodString>;
|
|
259
|
+
encryptedAtRest: z.ZodOptional<z.ZodBoolean>;
|
|
260
|
+
unrotatable: z.ZodOptional<z.ZodLiteral<true>>;
|
|
261
|
+
}, z.core.$strip>;
|
|
262
|
+
export type PrivacyFieldView = z.output<typeof PrivacyFieldView>;
|
|
263
|
+
/** One storage schema holding at least one marked field. */
|
|
264
|
+
export declare const PrivacySchemaView: z.ZodObject<{
|
|
265
|
+
capability: z.ZodString;
|
|
266
|
+
storage: z.ZodEnum<{
|
|
267
|
+
d1: "d1";
|
|
268
|
+
kv: "kv";
|
|
269
|
+
}>;
|
|
270
|
+
container: z.ZodString;
|
|
271
|
+
name: z.ZodString;
|
|
272
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
273
|
+
path: z.ZodString;
|
|
274
|
+
class: z.ZodString;
|
|
275
|
+
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
276
|
+
sameAs: z.ZodOptional<z.ZodString>;
|
|
277
|
+
encryptedAtRest: z.ZodOptional<z.ZodBoolean>;
|
|
278
|
+
unrotatable: z.ZodOptional<z.ZodLiteral<true>>;
|
|
279
|
+
}, z.core.$strip>>;
|
|
280
|
+
encrypted: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
281
|
+
path: z.ZodString;
|
|
282
|
+
unrotatable: z.ZodOptional<z.ZodLiteral<true>>;
|
|
283
|
+
}, z.core.$strip>>>;
|
|
284
|
+
}, z.core.$strip>;
|
|
285
|
+
export type PrivacySchemaView = z.output<typeof PrivacySchemaView>;
|
|
286
|
+
/**
|
|
287
|
+
* `GET /control-plane/privacy` — the full inventory, behind `privacy:read` (#132).
|
|
288
|
+
*
|
|
289
|
+
* Derived at runtime from the schemas this Worker composed, walked once per isolate. The manifest's `privacy`
|
|
290
|
+
* block is the headline; this is the detail, and it names fields, which is why it has a scope of its own.
|
|
291
|
+
*/
|
|
292
|
+
export declare const ControlPlanePrivacyResponse: z.ZodObject<{
|
|
293
|
+
environment: z.ZodString;
|
|
294
|
+
posture: z.ZodObject<{
|
|
295
|
+
declared: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
296
|
+
observed: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
297
|
+
counts: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
298
|
+
observedNotDeclared: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
299
|
+
declaredNotObserved: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
300
|
+
consoleGate: z.ZodEnum<{
|
|
301
|
+
enforced: "enforced";
|
|
302
|
+
not_required: "not_required";
|
|
303
|
+
unattested: "unattested";
|
|
304
|
+
unverifiable: "unverifiable";
|
|
305
|
+
}>;
|
|
306
|
+
consoleGateReason: z.ZodNullable<z.ZodString>;
|
|
307
|
+
attestedAt: z.ZodNullable<z.ZodISODateTime>;
|
|
308
|
+
sources: z.ZodArray<z.ZodEnum<{
|
|
309
|
+
d1: "d1";
|
|
310
|
+
kv: "kv";
|
|
311
|
+
}>>;
|
|
312
|
+
retirement: z.ZodOptional<z.ZodObject<{
|
|
313
|
+
blocked: z.ZodBoolean;
|
|
314
|
+
reasons: z.ZodArray<z.ZodEnum<{
|
|
315
|
+
"incomplete-coverage": "incomplete-coverage";
|
|
316
|
+
stale: "stale";
|
|
317
|
+
unrotatable: "unrotatable";
|
|
318
|
+
}>>;
|
|
319
|
+
liveVersions: z.ZodNumber;
|
|
320
|
+
}, z.core.$strip>>;
|
|
321
|
+
}, z.core.$strip>;
|
|
322
|
+
schemasWalked: z.ZodNumber;
|
|
323
|
+
schemas: z.ZodArray<z.ZodObject<{
|
|
324
|
+
capability: z.ZodString;
|
|
325
|
+
storage: z.ZodEnum<{
|
|
326
|
+
d1: "d1";
|
|
327
|
+
kv: "kv";
|
|
328
|
+
}>;
|
|
329
|
+
container: z.ZodString;
|
|
330
|
+
name: z.ZodString;
|
|
331
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
332
|
+
path: z.ZodString;
|
|
333
|
+
class: z.ZodString;
|
|
334
|
+
truncated: z.ZodOptional<z.ZodLiteral<true>>;
|
|
335
|
+
sameAs: z.ZodOptional<z.ZodString>;
|
|
336
|
+
encryptedAtRest: z.ZodOptional<z.ZodBoolean>;
|
|
337
|
+
unrotatable: z.ZodOptional<z.ZodLiteral<true>>;
|
|
338
|
+
}, z.core.$strip>>;
|
|
339
|
+
encrypted: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
340
|
+
path: z.ZodString;
|
|
341
|
+
unrotatable: z.ZodOptional<z.ZodLiteral<true>>;
|
|
342
|
+
}, z.core.$strip>>>;
|
|
343
|
+
}, z.core.$strip>>;
|
|
344
|
+
}, z.core.$strip>;
|
|
345
|
+
export type ControlPlanePrivacyResponse = z.output<typeof ControlPlanePrivacyResponse>;
|
|
248
346
|
//# sourceMappingURL=responses.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/http/responses.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/http/responses.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,aAAa;;;;;;;;;;iBAcmF,CAAC;AAC9G,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB;;;;;;iBAQwB,CAAC;AAC9D,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEjF,+FAA+F;AAC/F,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;iBAuBwE,CAAC;AAC9G,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEjF,mFAAmF;AACnF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;iBAQyB,CAAC;AAC1D,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEvE,gGAAgG;AAChG,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;iBAM6B,CAAC;AAC5D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;iBAU+C,CAAC;AAC1E,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAE3D,iFAAiF;AACjF,eAAO,MAAM,0BAA0B;;;;;;;;;4BAyBkE,CAAC;AAC1G,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAErF,kFAAkF;AAClF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;iBAW8C,CAAC;AAC9E,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAErE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BA+BwE,CAAC;AAC3G,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE3E;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAO+D,CAAC;AAC3G,MAAM,MAAM,8BAA8B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAE7F;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;;;;;;iBAmCiB,CAAC;AAC/C,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEjE,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;iBA0BmC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAerC,CAAC;AACJ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
+
import { PRIVACY_SOURCES } from "../../privacy/report.js";
|
|
3
4
|
import { ConnectionPrincipal, ConnectionPurpose, ControlPlaneActorKind, Ed25519PublicJwk } from "../data/connection.js";
|
|
5
|
+
import { PrivacyPosture } from "../../privacy/posture.js";
|
|
4
6
|
import { z } from "zod";
|
|
5
7
|
//#region src/controlPlane/http/responses.ts
|
|
6
8
|
/**
|
|
@@ -118,5 +120,43 @@ const ControlPlaneMigrationsResponse = z.object({
|
|
|
118
120
|
environment: z.string().describe("The environment this Worker answers for."),
|
|
119
121
|
databases: z.array(MigrationDatabaseView).describe("One entry per database this Worker binds, sorted by database name. One unreadable costs only itself.")
|
|
120
122
|
}).describe("What is applied, pending and undeclared in each bound database, and which run put it there.");
|
|
123
|
+
/**
|
|
124
|
+
* One marked field, as `GET {basePath}/privacy` reports it (#132).
|
|
125
|
+
*
|
|
126
|
+
* **The per-field record.** Since #390 it says whether the field rests encrypted beside `class`, so "which of
|
|
127
|
+
* your PHI fields are encrypted" is a derivation over this list rather than a second inventory to keep.
|
|
128
|
+
*/
|
|
129
|
+
const PrivacyFieldView = z.object({
|
|
130
|
+
path: z.string().describe("Where the field sits. A D1 column path (`email`, `address.line1`, `profile.phone` inside a JSON column), or a KV entry's part first (`key.email`, `value.token`, `metadata.ip`, or `value` for a whole marked value). An array element is `[]`, a record's value `*`."),
|
|
131
|
+
class: z.string().describe("The privacy class it is marked with: `secret`, `pii`, `phi`, `pci`, or an adopter's own."),
|
|
132
|
+
truncated: z.literal(true).optional().describe("Set where the class is assumed rather than found: a read ran out of its budget there, or the schema could not be read at all, so any class may be marked below it. Absent where the schema was read to the end."),
|
|
133
|
+
sameAs: z.string().optional().describe("Set on a reference: the path this field's position was first listed under, once the list reached its cap on paths. The class is marked somewhere beneath both, and the paths beneath this one are those beneath that one."),
|
|
134
|
+
encryptedAtRest: z.boolean().optional().describe("Whether the field rests encrypted (#390). Absent where the core cannot say — an assumed class, a reference, or a core older than encrypted fields — and never defaulted to false."),
|
|
135
|
+
unrotatable: z.literal(true).optional().describe("Set on an encrypted field whose storage is not D1: it can never be rotated, and it blocks retirement.")
|
|
136
|
+
}).describe("One marked field and its class.");
|
|
137
|
+
/** One storage schema holding at least one marked field. */
|
|
138
|
+
const PrivacySchemaView = z.object({
|
|
139
|
+
capability: z.string().describe("The capability that declared the schema, as the manifest's `capabilities[]` names it."),
|
|
140
|
+
storage: z.enum(PRIVACY_SOURCES).describe("Where it is stored: a `d1` table or a `kv` store."),
|
|
141
|
+
container: z.string().describe("The D1 database name or the KV namespace name it lives in."),
|
|
142
|
+
name: z.string().describe("The table name, or the KV store name."),
|
|
143
|
+
fields: z.array(PrivacyFieldView).describe("Every marked field in it, in schema order."),
|
|
144
|
+
encrypted: z.array(z.object({
|
|
145
|
+
path: z.string().describe("Where the encrypted field sits, on the same paths as `fields[].path`."),
|
|
146
|
+
unrotatable: z.literal(true).optional().describe("Set where the storage is not D1, so the field can never be rotated.")
|
|
147
|
+
}).describe("One encrypted field.")).optional().describe("Every field marked encrypted at rest, classed or not (#390). Absent on a Worker whose core predates encrypted fields.")
|
|
148
|
+
}).describe("One storage schema and the marked fields it holds.");
|
|
149
|
+
/**
|
|
150
|
+
* `GET /control-plane/privacy` — the full inventory, behind `privacy:read` (#132).
|
|
151
|
+
*
|
|
152
|
+
* Derived at runtime from the schemas this Worker composed, walked once per isolate. The manifest's `privacy`
|
|
153
|
+
* block is the headline; this is the detail, and it names fields, which is why it has a scope of its own.
|
|
154
|
+
*/
|
|
155
|
+
const ControlPlanePrivacyResponse = z.object({
|
|
156
|
+
environment: z.string().describe("The environment this Worker answers for."),
|
|
157
|
+
posture: PrivacyPosture.describe("The declared and observed classes, the delta, and the console gate."),
|
|
158
|
+
schemasWalked: z.number().int().nonnegative().describe("How many storage schemas were walked, marked or not, across the sources `posture.sources` names."),
|
|
159
|
+
schemas: z.array(PrivacySchemaView).describe("Every schema holding a marked field, in composition order. A schema with none is not listed.")
|
|
160
|
+
}).describe("Every schema this Worker stores that holds a marked field, each field's path and class, and where it lives.");
|
|
121
161
|
//#endregion
|
|
122
|
-
export { ControlPlaneKeysResponse, ControlPlaneMigrationsResponse, ControlPlanePingResponse, ExpireKeyResponse, MigrationDatabaseView, MigrationGroupPositionView, MigrationGroupView, MigrationView, PublicKeyView, RegisterKeyResponse };
|
|
162
|
+
export { ControlPlaneKeysResponse, ControlPlaneMigrationsResponse, ControlPlanePingResponse, ControlPlanePrivacyResponse, ExpireKeyResponse, MigrationDatabaseView, MigrationGroupPositionView, MigrationGroupView, MigrationView, PrivacyFieldView, PrivacySchemaView, PublicKeyView, RegisterKeyResponse };
|
|
@@ -13,6 +13,7 @@ import { type ControlPlaneHandlerDeps } from "./handlers";
|
|
|
13
13
|
* POST /control-plane/keys → register a key (keys:rotate)
|
|
14
14
|
* POST /control-plane/keys/:keyId/expire → retire a superseded key (keys:rotate)
|
|
15
15
|
* GET /control-plane/migrations → where each database stands (migrations:read)
|
|
16
|
+
* GET /control-plane/privacy → what each schema holds (privacy:read)
|
|
16
17
|
*
|
|
17
18
|
* Every one is `control-plane` and default-denied — with no connection registered they all answer 403,
|
|
18
19
|
* and that is the shipped state of a Worker nobody has connected.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/http/routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,EAAE,KAAK,UAAU,EAAwB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/http/routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,OAAO,EAAE,KAAK,UAAU,EAAwB,MAAM,yBAAyB,CAAC;AAShF,OAAO,EACL,KAAK,uBAAuB,EAQ7B,MAAM,YAAY,CAAC;AAWpB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE,CA+C3E;AAED,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,IAAI,CAAC,YAAY,CAAC,EACvB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,uBAAuB,GAC5B,IAAI,CA2FN"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
import { ANY_VERIFIED_CALLER, KEYS_ROTATE_SCOPE, MANIFEST_READ_SCOPE, MIGRATIONS_READ_SCOPE } from "../scope/scope.js";
|
|
3
|
+
import { ANY_VERIFIED_CALLER, KEYS_ROTATE_SCOPE, MANIFEST_READ_SCOPE, MIGRATIONS_READ_SCOPE, PRIVACY_READ_SCOPE } from "../scope/scope.js";
|
|
4
4
|
import { requireControlPlane } from "./guard.js";
|
|
5
5
|
import { describeRoute } from "../../http/routeSpec.js";
|
|
6
6
|
import { validate } from "../../http/validation.js";
|
|
7
7
|
import { ControlPlaneManifest } from "../discovery/adminRoute.js";
|
|
8
|
-
import { expireKeyHandler, listKeysHandler, manifestHandler, migrationsHandler, pingHandler, registerKeyHandler } from "./handlers.js";
|
|
9
|
-
import { ControlPlaneKeysResponse, ControlPlaneMigrationsResponse, ControlPlanePingResponse, ExpireKeyResponse, RegisterKeyResponse } from "./responses.js";
|
|
8
|
+
import { expireKeyHandler, listKeysHandler, manifestHandler, migrationsHandler, pingHandler, privacyHandler, registerKeyHandler } from "./handlers.js";
|
|
9
|
+
import { ControlPlaneKeysResponse, ControlPlaneMigrationsResponse, ControlPlanePingResponse, ControlPlanePrivacyResponse, ExpireKeyResponse, RegisterKeyResponse } from "./responses.js";
|
|
10
10
|
import { ExpireKeyParams, ExpireKeyRequest, RegisterKeyRequest } from "./schemas.js";
|
|
11
11
|
//#region src/controlPlane/http/routes.ts
|
|
12
12
|
/**
|
|
@@ -18,6 +18,7 @@ import { ExpireKeyParams, ExpireKeyRequest, RegisterKeyRequest } from "./schemas
|
|
|
18
18
|
* POST /control-plane/keys → register a key (keys:rotate)
|
|
19
19
|
* POST /control-plane/keys/:keyId/expire → retire a superseded key (keys:rotate)
|
|
20
20
|
* GET /control-plane/migrations → where each database stands (migrations:read)
|
|
21
|
+
* GET /control-plane/privacy → what each schema holds (privacy:read)
|
|
21
22
|
*
|
|
22
23
|
* Every one is `control-plane` and default-denied — with no connection registered they all answer 403,
|
|
23
24
|
* and that is the shipped state of a Worker nobody has connected.
|
|
@@ -80,6 +81,12 @@ function controlPlaneRouteDescriptors(basePath) {
|
|
|
80
81
|
path: `${basePath}/migrations`,
|
|
81
82
|
scope: MIGRATIONS_READ_SCOPE,
|
|
82
83
|
summary: "What each bound database has applied, what is pending, what is undeclared, and which run put it there. Undeclared is relative to this Worker."
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
method: "GET",
|
|
87
|
+
path: `${basePath}/privacy`,
|
|
88
|
+
scope: PRIVACY_READ_SCOPE,
|
|
89
|
+
summary: "Every stored schema holding a privacy-marked field, each field's path and class, and where it lives. Derived from the running code."
|
|
83
90
|
}
|
|
84
91
|
];
|
|
85
92
|
}
|
|
@@ -121,6 +128,13 @@ function registerControlPlaneRoutes(app, basePath, deps) {
|
|
|
121
128
|
scopes: [MIGRATIONS_READ_SCOPE],
|
|
122
129
|
responses: { 200: ControlPlaneMigrationsResponse }
|
|
123
130
|
}), requireControlPlane(MIGRATIONS_READ_SCOPE), migrationsHandler(deps));
|
|
131
|
+
app.get(`${basePath}/privacy`, describeRoute({
|
|
132
|
+
summary: "Report every stored field marked with a privacy class.",
|
|
133
|
+
description: "Every D1 table and KV store this Worker composed that holds a privacy-marked field, with each field's path, its class and where it is stored, beside the declared-and-observed posture. Derived at runtime from the deployed schemas. Read-only.",
|
|
134
|
+
verification: "control-plane",
|
|
135
|
+
scopes: [PRIVACY_READ_SCOPE],
|
|
136
|
+
responses: { 200: ControlPlanePrivacyResponse }
|
|
137
|
+
}), requireControlPlane(PRIVACY_READ_SCOPE), privacyHandler(deps));
|
|
124
138
|
}
|
|
125
139
|
//#endregion
|
|
126
140
|
export { controlPlaneRouteDescriptors, registerControlPlaneRoutes };
|
|
@@ -56,13 +56,23 @@ export declare const KEYS_ROTATE_SCOPE: ControlPlaneScope;
|
|
|
56
56
|
* manifest entry sit behind it too, so a connection without it gets no number rather than a zero.
|
|
57
57
|
*/
|
|
58
58
|
export declare const MIGRATIONS_READ_SCOPE: ControlPlaneScope;
|
|
59
|
+
/**
|
|
60
|
+
* Read this Worker's full privacy inventory: every storage schema holding a marked field, each marked field's
|
|
61
|
+
* path, its class, and where it is stored (#132). Read-only — the one route behind it is a `GET`.
|
|
62
|
+
*
|
|
63
|
+
* **Its own scope rather than `manifest:read`**, because field names are the kind of thing an adopter may
|
|
64
|
+
* reasonably withhold from a client that has no business seeing them. The manifest's privacy block carries
|
|
65
|
+
* classes and counts only, so a connection without this one still sees the posture headline.
|
|
66
|
+
*/
|
|
67
|
+
export declare const PRIVACY_READ_SCOPE: ControlPlaneScope;
|
|
59
68
|
/**
|
|
60
69
|
* The seam's base grant — what `pithy dashboard connect` grants whatever the Worker composes. Ping is absent
|
|
61
70
|
* because it is not grantable; see {@link ANY_VERIFIED_CALLER}.
|
|
62
71
|
*
|
|
63
|
-
* **{@link MIGRATIONS_READ_SCOPE}
|
|
64
|
-
* — so `connect` derives it from the seam's `adminRoutes` the way it
|
|
65
|
-
* base exists for `keys:rotate`, which is not a read and would
|
|
72
|
+
* **{@link MIGRATIONS_READ_SCOPE} and {@link PRIVACY_READ_SCOPE} are absent on purpose.** Each is a read —
|
|
73
|
+
* every route requiring it is a `GET` — so `connect` derives it from the seam's `adminRoutes` the way it
|
|
74
|
+
* derives every capability's reads. The base exists for `keys:rotate`, which is not a read and would
|
|
75
|
+
* otherwise drop out.
|
|
66
76
|
*/
|
|
67
77
|
export declare const SEAM_SCOPES: readonly ControlPlaneScope[];
|
|
68
78
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/scope/scope.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,aAQ3B,CAAC;AACJ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEnE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,EAAE,OAAO,MAA2D,CAAC;AAErG;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG,OAAO,mBAAmB,CAAC;AAErF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,iBAAmC,CAAC;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBAAiC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,iBAAqC,CAAC;AAE1E;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,iBAAiB,EAA6C,CAAC;AAElG;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAIrH"}
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/controlPlane/scope/scope.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAexB;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,aAQ3B,CAAC;AACJ,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEnE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,EAAE,OAAO,MAA2D,CAAC;AAErG;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG,OAAO,mBAAmB,CAAC;AAErF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,iBAAmC,CAAC;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBAAiC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,iBAAqC,CAAC;AAE1E;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,iBAAkC,CAAC;AAEpE;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,iBAAiB,EAA6C,CAAC;AAElG;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAIrH"}
|