@namzu/sandbox 12.0.1 → 14.0.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 (67) hide show
  1. package/CHANGELOG.md +393 -0
  2. package/README.md +151 -0
  3. package/dist/backends/firecracker/protocol.d.ts +22 -0
  4. package/dist/backends/firecracker/protocol.d.ts.map +1 -1
  5. package/dist/backends/firecracker/protocol.js.map +1 -1
  6. package/dist/backends/firecracker/transport.d.ts +104 -9
  7. package/dist/backends/firecracker/transport.d.ts.map +1 -1
  8. package/dist/backends/firecracker/transport.js +139 -13
  9. package/dist/backends/firecracker/transport.js.map +1 -1
  10. package/dist/backends/kubernetes/egress-policy.d.ts +219 -0
  11. package/dist/backends/kubernetes/egress-policy.d.ts.map +1 -0
  12. package/dist/backends/kubernetes/egress-policy.js +314 -0
  13. package/dist/backends/kubernetes/egress-policy.js.map +1 -0
  14. package/dist/backends/kubernetes/index.d.ts +374 -0
  15. package/dist/backends/kubernetes/index.d.ts.map +1 -0
  16. package/dist/backends/kubernetes/index.js +671 -0
  17. package/dist/backends/kubernetes/index.js.map +1 -0
  18. package/dist/backends/kubernetes/k8s-client.d.ts +125 -0
  19. package/dist/backends/kubernetes/k8s-client.d.ts.map +1 -0
  20. package/dist/backends/kubernetes/k8s-client.js +246 -0
  21. package/dist/backends/kubernetes/k8s-client.js.map +1 -0
  22. package/dist/backends/kubernetes/lease.d.ts +119 -0
  23. package/dist/backends/kubernetes/lease.d.ts.map +1 -0
  24. package/dist/backends/kubernetes/lease.js +151 -0
  25. package/dist/backends/kubernetes/lease.js.map +1 -0
  26. package/dist/backends/kubernetes/objects.d.ts +282 -0
  27. package/dist/backends/kubernetes/objects.d.ts.map +1 -0
  28. package/dist/backends/kubernetes/objects.js +156 -0
  29. package/dist/backends/kubernetes/objects.js.map +1 -0
  30. package/dist/backends/kubernetes/privilege-probe.d.ts +136 -0
  31. package/dist/backends/kubernetes/privilege-probe.d.ts.map +1 -0
  32. package/dist/backends/kubernetes/privilege-probe.js +185 -0
  33. package/dist/backends/kubernetes/privilege-probe.js.map +1 -0
  34. package/dist/backends/kubernetes/sandbox.d.ts +123 -0
  35. package/dist/backends/kubernetes/sandbox.d.ts.map +1 -0
  36. package/dist/backends/kubernetes/sandbox.js +299 -0
  37. package/dist/backends/kubernetes/sandbox.js.map +1 -0
  38. package/dist/backends/kubernetes/transport.d.ts +122 -0
  39. package/dist/backends/kubernetes/transport.d.ts.map +1 -0
  40. package/dist/backends/kubernetes/transport.js +197 -0
  41. package/dist/backends/kubernetes/transport.js.map +1 -0
  42. package/dist/backends/kubernetes/workspace.d.ts +381 -0
  43. package/dist/backends/kubernetes/workspace.d.ts.map +1 -0
  44. package/dist/backends/kubernetes/workspace.js +1064 -0
  45. package/dist/backends/kubernetes/workspace.js.map +1 -0
  46. package/dist/index.d.ts +132 -2
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +102 -34
  49. package/dist/index.js.map +1 -1
  50. package/dist/testing/sandbox-conformance.d.ts +193 -0
  51. package/dist/testing/sandbox-conformance.d.ts.map +1 -0
  52. package/dist/testing/sandbox-conformance.js +465 -0
  53. package/dist/testing/sandbox-conformance.js.map +1 -0
  54. package/package.json +5 -4
  55. package/src/backends/firecracker/protocol.ts +27 -0
  56. package/src/backends/firecracker/transport.ts +199 -28
  57. package/src/backends/kubernetes/egress-policy.ts +437 -0
  58. package/src/backends/kubernetes/index.ts +1012 -0
  59. package/src/backends/kubernetes/k8s-client.ts +352 -0
  60. package/src/backends/kubernetes/lease.ts +198 -0
  61. package/src/backends/kubernetes/objects.ts +363 -0
  62. package/src/backends/kubernetes/privilege-probe.ts +261 -0
  63. package/src/backends/kubernetes/sandbox.ts +395 -0
  64. package/src/backends/kubernetes/transport.ts +286 -0
  65. package/src/backends/kubernetes/workspace.ts +1386 -0
  66. package/src/index.ts +257 -35
  67. package/src/testing/sandbox-conformance.ts +667 -0
@@ -0,0 +1,314 @@
1
+ /**
2
+ * Egress policy translation for the Kubernetes backend, and the
3
+ * verify-not-trust check that stops a misconfigured cluster from silently
4
+ * running unenforced.
5
+ *
6
+ * Mirrors two existing shapes rather than inventing a third:
7
+ *
8
+ * - `../firecracker/index.ts`'s `resolveNetworkPolicy` — a pure(ish) mapping
9
+ * from the shared {@link EgressPolicy} union to what one specific
10
+ * enforcement point can actually carry, with an exhaustive switch that
11
+ * refuses an unknown kind instead of defaulting to open.
12
+ * - `../docker/index.ts`'s `assertNetworkCarriesThePolicy` — the refusal
13
+ * discipline. That function does not trust a docker network's NAME to
14
+ * mean "internal"; it inspects the daemon's own `{{.Internal}}` flag. The
15
+ * same principle drives {@link verifyEgressPolicyApplied} here: this
16
+ * backend does not trust that an operator applied the right
17
+ * `NetworkPolicy` because a name matches — it GETs the live object and
18
+ * compares its shape.
19
+ *
20
+ * ## What core `NetworkPolicy` can and cannot express
21
+ *
22
+ * Core Kubernetes `NetworkPolicy` has exactly three ways to name a
23
+ * destination: `ipBlock` (CIDR), `podSelector` and `namespaceSelector`. There
24
+ * is no hostname or FQDN concept anywhere in the resource. So of the four
25
+ * {@link EgressPolicy} kinds:
26
+ *
27
+ * - `deny-all` and `allow-all` are fully expressible — neither needs a
28
+ * hostname.
29
+ * - `static` and `resolver` are hostname allowlists and are NOT expressible
30
+ * under core `NetworkPolicy` at all. {@link assertEgressPolicyIsEnforceable}
31
+ * throws a named error for both, rather than silently downgrading to an
32
+ * `HTTP_PROXY`/`HTTPS_PROXY` environment variable the way the container
33
+ * tier's open allowlist gap does (`#398`) — a workload that ignores a
34
+ * proxy variable bypasses it entirely, and repeating that mistake behind a
35
+ * Kubernetes-shaped manifest would not fix it.
36
+ *
37
+ * `KubernetesEgressConfig.engine: 'cilium'` is the one escape hatch, and it
38
+ * is opt-in: a cluster that actually runs Cilium can express a hostname
39
+ * allowlist as a `CiliumNetworkPolicy` with `toFQDNs`, so declaring the
40
+ * engine turns the refusal into an emission. No other engine is supported in
41
+ * this batch — Calico's `HostEndpoint`/`GlobalNetworkPolicy` and any other
42
+ * FQDN-capable CNI would need their own translation, added as their own
43
+ * `engine` value with their own resource shape, not folded into this one by
44
+ * guessing.
45
+ *
46
+ * ## Why a NetworkPolicy always allows the cluster's own DNS
47
+ *
48
+ * agent-sandbox's OWN managed `NetworkPolicy`
49
+ * (`SandboxTemplateSpec.networkPolicy` /
50
+ * `networkPolicyManagement: Managed`, the CRD's default) already leaves the
51
+ * cluster's own name service reachable — the upstream reference deployment
52
+ * (kubernetes-sigs/agent-sandbox `examples/kata-aks/sandboxtemplate.yaml`)
53
+ * ships exactly "ingress from the router only, egress limited to DNS (53)
54
+ * and TCP/443". {@link CLUSTER_DNS_EGRESS_RULE} matches that convention
55
+ * (CoreDNS/kube-dns lives in the `kube-system` namespace on every cluster
56
+ * this was checked against) rather than inventing a different one.
57
+ *
58
+ * This is not a case of one policy overriding another: the Kubernetes API
59
+ * server UNIONS every `NetworkPolicy` selecting a pod — traffic is allowed if
60
+ * ANY matching policy's rule allows it, never the intersection — so this
61
+ * rule does not need to duplicate the managed policy to avoid "fighting" it
62
+ * in the sense of narrowing anything. It exists so THIS backend's own
63
+ * translated policy is self-sufficient: on a cluster where an operator left
64
+ * `networkPolicyManagement: Unmanaged`, or copied the managed shape
65
+ * imperfectly, `deny-all` still means "the cluster's own name service,
66
+ * nothing else" instead of a pod that cannot even resolve
67
+ * `kubernetes.default`.
68
+ *
69
+ * ## Never a proxy environment variable
70
+ *
71
+ * No code path in this module emits `HTTP_PROXY`, `HTTPS_PROXY` or any other
72
+ * proxy variable, and none of the module's own string constants contain
73
+ * those substrings either — a dedicated test scans both. Proxy variables are
74
+ * advisory: a process that does not read them is not bounded by them. The
75
+ * boundary here is the `NetworkPolicy` object itself, enforced by the CNI in
76
+ * the kernel, not by the workload's cooperation.
77
+ */
78
+ import { isDeepStrictEqual } from 'node:util';
79
+ import { KubernetesAlreadyGoneError } from './k8s-client.js';
80
+ import { CILIUM_NETWORK_POLICY_API_GROUP, CILIUM_NETWORK_POLICY_API_VERSION, CORE_NETWORK_POLICY_API_GROUP, CORE_NETWORK_POLICY_API_VERSION, ciliumNetworkPolicyPath, networkPolicyPath, sandboxTemplateLabel, } from './objects.js';
81
+ /** `${sandboxTemplateName}-egress`, the name {@link KubernetesEgressConfig.networkPolicyName} defaults to. */
82
+ export function defaultEgressPolicyName(sandboxTemplateName) {
83
+ return `${sandboxTemplateName}-egress`;
84
+ }
85
+ /**
86
+ * Named refusal for a hostname allowlist with no FQDN-capable engine
87
+ * declared. Thrown SYNCHRONOUSLY from `buildKubernetesBackend` — see
88
+ * {@link assertEgressPolicyIsEnforceable} — so a misconfiguration surfaces
89
+ * during host wiring, the same moment `assertRuntimeClassIsApplicable` and
90
+ * the readiness-bounds validation do, rather than on the first `create()`.
91
+ */
92
+ export class KubernetesUnenforceableEgressPolicyError extends Error {
93
+ policyKind;
94
+ name = 'KubernetesUnenforceableEgressPolicyError';
95
+ constructor(policyKind) {
96
+ super(`The kubernetes sandbox backend cannot enforce an egress policy of kind '${policyKind}' as a NetworkPolicy: core Kubernetes NetworkPolicy has only ipBlock, podSelector and namespaceSelector — it has no hostname/FQDN concept at all. This cluster needs an FQDN-capable policy engine: set config.egress.engine to 'cilium' if the target cluster actually runs it (see docs/sdk/kubernetes-sandbox.md's egress section), or configure an egress policy of 'deny-all' or 'allow-all' instead. Refusing rather than silently downgrading to an HTTP_PROXY/HTTPS_PROXY environment variable an uncooperative process can ignore.`);
97
+ this.policyKind = policyKind;
98
+ }
99
+ }
100
+ /**
101
+ * Synchronous, no-I/O precondition: can `policy.kind` be enforced under
102
+ * `engine` at all. Deliberately decided from the KIND alone — a `resolver`
103
+ * policy's `resolve()` is never invoked here, both because calling it just to
104
+ * prove a refusal would be wasted work (and possibly a side effect the host
105
+ * did not expect yet) and because this has to stay callable synchronously
106
+ * from `buildKubernetesBackend`, which contacts nothing.
107
+ */
108
+ export function assertEgressPolicyIsEnforceable(policy, engine) {
109
+ if ((policy.kind === 'static' || policy.kind === 'resolver') && engine !== 'cilium') {
110
+ throw new KubernetesUnenforceableEgressPolicyError(policy.kind);
111
+ }
112
+ }
113
+ /**
114
+ * The cluster DNS egress rule every translated `NetworkPolicy` carries,
115
+ * including on `deny-all`. See the module doc's "Why a NetworkPolicy always
116
+ * allows the cluster's own DNS" section.
117
+ */
118
+ const CLUSTER_DNS_EGRESS_RULE = {
119
+ to: [{ namespaceSelector: { matchLabels: { 'kubernetes.io/metadata.name': 'kube-system' } } }],
120
+ ports: [
121
+ { protocol: 'UDP', port: 53 },
122
+ { protocol: 'TCP', port: 53 },
123
+ ],
124
+ };
125
+ /**
126
+ * Cilium requires DNS lookups to be explicitly allowed AND made visible to
127
+ * the agent before `toFQDNs` enforcement can match anything a name resolves
128
+ * to: without a preceding rule granting DNS and turning on visibility, the
129
+ * sandbox's own lookups for the allowed hosts are invisible to Cilium's
130
+ * FQDN-to-IP mapping and `toFQDNs` matches nothing, which would make a
131
+ * `static`/`resolver` policy fail closed for every host rather than only the
132
+ * disallowed ones.
133
+ *
134
+ * Shape verified against Cilium's own worked example — the `toFQDNs`
135
+ * `CiliumNetworkPolicy` at https://docs.cilium.io/en/stable/security/dns/
136
+ * (the "DNS Based" policy walkthrough) allows egress to `kube-dns` on port 53
137
+ * with `rules.dns: [{ matchPattern: "*" }]` alongside its own `toFQDNs` rule
138
+ * — this constant reproduces that DNS-allow rule verbatim, including the
139
+ * `k8s:` label-source prefix on both `toEndpoints` selector keys (an
140
+ * unprefixed key defaults to label source `any`, a superset that would still
141
+ * match, but `any` is not what the cited example uses).
142
+ */
143
+ const CILIUM_DNS_VISIBILITY_RULE = {
144
+ toEndpoints: [
145
+ {
146
+ matchLabels: {
147
+ 'k8s:io.kubernetes.pod.namespace': 'kube-system',
148
+ 'k8s:k8s-app': 'kube-dns',
149
+ },
150
+ },
151
+ ],
152
+ toPorts: [
153
+ {
154
+ ports: [{ port: '53', protocol: 'ANY' }],
155
+ rules: { dns: [{ matchPattern: '*' }] },
156
+ },
157
+ ],
158
+ };
159
+ function buildCoreNetworkPolicy(target, egress) {
160
+ return {
161
+ kind: 'NetworkPolicy',
162
+ namespace: target.namespace,
163
+ name: target.name,
164
+ manifest: {
165
+ apiVersion: `${CORE_NETWORK_POLICY_API_GROUP}/${CORE_NETWORK_POLICY_API_VERSION}`,
166
+ kind: 'NetworkPolicy',
167
+ metadata: { name: target.name, namespace: target.namespace },
168
+ spec: {
169
+ podSelector: { matchLabels: sandboxTemplateLabel(target.sandboxTemplateName) },
170
+ policyTypes: ['Egress'],
171
+ egress,
172
+ },
173
+ },
174
+ };
175
+ }
176
+ function buildCiliumNetworkPolicy(target, allowedHosts) {
177
+ return {
178
+ kind: 'CiliumNetworkPolicy',
179
+ namespace: target.namespace,
180
+ name: target.name,
181
+ manifest: {
182
+ apiVersion: `${CILIUM_NETWORK_POLICY_API_GROUP}/${CILIUM_NETWORK_POLICY_API_VERSION}`,
183
+ kind: 'CiliumNetworkPolicy',
184
+ metadata: { name: target.name, namespace: target.namespace },
185
+ spec: {
186
+ endpointSelector: { matchLabels: sandboxTemplateLabel(target.sandboxTemplateName) },
187
+ egress: [
188
+ CILIUM_DNS_VISIBILITY_RULE,
189
+ { toFQDNs: allowedHosts.map((host) => ({ matchName: host })) },
190
+ ],
191
+ },
192
+ },
193
+ };
194
+ }
195
+ /**
196
+ * The pure translation: an {@link EgressPolicy} plus the declared
197
+ * {@link KubernetesEgressEngine} in, the concrete manifest this backend can
198
+ * ask an operator to apply out. Async only because `resolver` carries an
199
+ * async `resolve()` — `deny-all`, `allow-all` and `static` never await
200
+ * anything.
201
+ *
202
+ * `resolver` is resolved ONCE here (at whatever call site first needs the
203
+ * manifest — `buildKubernetesBackend`'s first `create()`, in practice), not
204
+ * once per `create()` the way the docker and Firecracker backends re-resolve
205
+ * a PER-SANDBOX `resolver` policy on every call. That is a deliberate
206
+ * difference, not a shortcut: the enforcement point here is one
207
+ * `NetworkPolicy`/`CiliumNetworkPolicy` object shared by every sandbox this
208
+ * backend produces, so there is exactly one manifest to compare the resolved
209
+ * hosts against, and re-resolving on every `create()` would only produce a
210
+ * value nothing downstream re-applies to the cluster.
211
+ */
212
+ export async function translateEgressPolicy(policy, engine, target) {
213
+ assertEgressPolicyIsEnforceable(policy, engine);
214
+ switch (policy.kind) {
215
+ case 'deny-all':
216
+ return buildCoreNetworkPolicy(target, [CLUSTER_DNS_EGRESS_RULE]);
217
+ case 'allow-all':
218
+ // No `to`/`ports` on an egress rule matches every destination and
219
+ // every port. `CLUSTER_DNS_EGRESS_RULE` is a strict subset of this,
220
+ // so it is folded in rather than listed twice.
221
+ return buildCoreNetworkPolicy(target, [{}]);
222
+ case 'static':
223
+ // `assertEgressPolicyIsEnforceable` already threw above unless
224
+ // `engine === 'cilium'`, so reaching here means it did not.
225
+ return buildCiliumNetworkPolicy(target, policy.allowedHosts);
226
+ case 'resolver': {
227
+ const allowedHosts = await policy.resolve();
228
+ return buildCiliumNetworkPolicy(target, allowedHosts);
229
+ }
230
+ default: {
231
+ const exhaustive = policy;
232
+ throw new Error(`kubernetes: unhandled egress policy kind ${JSON.stringify(exhaustive)}. Refusing rather than defaulting to unrestricted network access.`);
233
+ }
234
+ }
235
+ }
236
+ /**
237
+ * Raised by {@link verifyEgressPolicyApplied} when the named object does not
238
+ * exist at all. This backend never CREATES the policy itself — like the
239
+ * docker backend's network, the boundary is operator-applied so it gets
240
+ * reviewed outside the hot create path, by whoever has cluster-admin rather
241
+ * than by whatever created the ServiceAccount token this backend runs with.
242
+ */
243
+ export class KubernetesEgressPolicyNotAppliedError extends Error {
244
+ resourceKind;
245
+ path;
246
+ name = 'KubernetesEgressPolicyNotAppliedError';
247
+ constructor(resourceKind, path) {
248
+ super(`kubernetes: config.egress is set but no ${resourceKind} exists at ${path}. This backend never creates the egress policy itself — apply the manifest it computed (see docs/sdk/kubernetes-sandbox.md's egress section) before creating a sandbox with an egress policy configured. Refusing rather than creating a sandbox with no enforced network boundary.`);
249
+ this.resourceKind = resourceKind;
250
+ this.path = path;
251
+ }
252
+ }
253
+ /** Raised when the applied object exists but does not match the translation. */
254
+ export class KubernetesEgressPolicyMismatchError extends Error {
255
+ resourceKind;
256
+ path;
257
+ reason;
258
+ name = 'KubernetesEgressPolicyMismatchError';
259
+ constructor(resourceKind, path, reason) {
260
+ super(`kubernetes: the ${resourceKind} at ${path} does not match the egress policy config.egress computed: ${reason}. Re-apply the manifest this backend translated rather than hand-editing the cluster object — a policy that has drifted from config silently changes what a sandbox can reach without config saying so.`);
261
+ this.resourceKind = resourceKind;
262
+ this.path = path;
263
+ this.reason = reason;
264
+ }
265
+ }
266
+ /**
267
+ * Verify-not-trust: GET the object {@link translateEgressPolicy} named and
268
+ * assert its shape actually matches, rather than trusting that an object
269
+ * with the right name does what config says. Mirrors
270
+ * `../docker/index.ts`'s `assertNetworkCarriesThePolicy`, which inspects the
271
+ * daemon's own `{{.Internal}}` flag instead of trusting a network's name.
272
+ *
273
+ * Checks exactly three things, each named separately in a mismatch so an
274
+ * operator sees which one to fix:
275
+ * - the selector (`podSelector` for `NetworkPolicy`, `endpointSelector` for
276
+ * `CiliumNetworkPolicy`) carries the expected template label:
277
+ * - `NetworkPolicy` additionally declares `policyTypes` including
278
+ * `'Egress'` — a `NetworkPolicy` with an `egress` array but no `'Egress'`
279
+ * in `policyTypes` enforces nothing on egress at all;
280
+ * - the `egress` rule array matches the translation exactly.
281
+ *
282
+ * Never mutates and never creates — a 404/410 is refused, not repaired.
283
+ */
284
+ export async function verifyEgressPolicyApplied(client, translated, signal) {
285
+ const path = translated.kind === 'CiliumNetworkPolicy'
286
+ ? ciliumNetworkPolicyPath(translated.namespace, translated.name)
287
+ : networkPolicyPath(translated.namespace, translated.name);
288
+ let resource;
289
+ try {
290
+ resource = await client.request('GET', path, undefined, signal);
291
+ }
292
+ catch (err) {
293
+ if (err instanceof KubernetesAlreadyGoneError) {
294
+ throw new KubernetesEgressPolicyNotAppliedError(translated.kind, path);
295
+ }
296
+ throw err;
297
+ }
298
+ const expectedSpec = translated.manifest.spec;
299
+ const actualSpec = resource?.spec ?? {};
300
+ const selectorKey = translated.kind === 'CiliumNetworkPolicy' ? 'endpointSelector' : 'podSelector';
301
+ if (!isDeepStrictEqual(actualSpec[selectorKey], expectedSpec[selectorKey])) {
302
+ throw new KubernetesEgressPolicyMismatchError(translated.kind, path, `spec.${selectorKey} is ${JSON.stringify(actualSpec[selectorKey])}, expected ${JSON.stringify(expectedSpec[selectorKey])} — the label every Sandbox this backend creates carries`);
303
+ }
304
+ if (translated.kind === 'NetworkPolicy') {
305
+ const policyTypes = actualSpec.policyTypes;
306
+ if (!Array.isArray(policyTypes) || !policyTypes.includes('Egress')) {
307
+ throw new KubernetesEgressPolicyMismatchError(translated.kind, path, `spec.policyTypes is ${JSON.stringify(policyTypes)}, expected an array containing 'Egress' — without it, spec.egress enforces nothing`);
308
+ }
309
+ }
310
+ if (!isDeepStrictEqual(actualSpec.egress, expectedSpec.egress)) {
311
+ throw new KubernetesEgressPolicyMismatchError(translated.kind, path, `spec.egress is ${JSON.stringify(actualSpec.egress)}, expected ${JSON.stringify(expectedSpec.egress)}`);
312
+ }
313
+ }
314
+ //# sourceMappingURL=egress-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"egress-policy.js","sourceRoot":"","sources":["../../../src/backends/kubernetes/egress-policy.ts"],"names":[],"mappings":"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"}