@veris-ai/daytona 0.2.0 → 0.3.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/README.md +254 -14
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +2099 -0
- package/dist/cli.js.map +1 -0
- package/dist/control-plane.d.ts +13 -5
- package/dist/daytona-key.d.ts +28 -0
- package/dist/daytona.d.ts +86 -10
- package/dist/exec.d.ts +15 -0
- package/dist/gateway.d.ts +35 -1
- package/dist/index.cjs +580 -110
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -5
- package/dist/index.js +555 -109
- package/dist/index.js.map +1 -1
- package/dist/network.d.ts +50 -38
- package/dist/profile.d.ts +70 -0
- package/dist/provision.d.ts +100 -0
- package/dist/push.d.ts +11 -0
- package/dist/receipt.d.ts +25 -3
- package/dist/run-receipt.d.ts +13 -0
- package/dist/run.d.ts +87 -0
- package/dist/service-control.d.ts +8 -0
- package/dist/teardown.d.ts +52 -0
- package/dist/trust.d.ts +110 -6
- package/dist/veris-api.d.ts +58 -0
- package/package.json +7 -1
package/dist/trust.d.ts
CHANGED
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
export declare const CA_CERT_PATH = "/usr/local/share/ca-certificates/veris-ca.crt";
|
|
5
5
|
/** The distribution's own bundle, when it has one. */
|
|
6
6
|
export declare const SYSTEM_BUNDLE = "/etc/ssl/certs/ca-certificates.crt";
|
|
7
|
-
/**
|
|
8
|
-
* Our CA alone, world-readable, written before anything needs it.
|
|
9
|
-
* NODE_EXTRA_CA_CERTS is additive by design and takes this.
|
|
10
|
-
*/
|
|
7
|
+
/** Our CA alone, world-readable, written before anything needs it. */
|
|
11
8
|
export declare const VERIS_CA_FILE = "/tmp/veris-ca.crt";
|
|
12
9
|
/**
|
|
13
10
|
* The public roots plus ours, concatenated by us.
|
|
@@ -28,10 +25,117 @@ export declare const VERIS_BUNDLE = "/tmp/veris-ca-bundle.crt";
|
|
|
28
25
|
* certificate validation.
|
|
29
26
|
*
|
|
30
27
|
* Every var is path-valued and points at VERIS_BUNDLE (public roots + ours, so
|
|
31
|
-
* passthrough hosts keep verifying)
|
|
32
|
-
* additive
|
|
28
|
+
* passthrough hosts keep verifying) — NODE_EXTRA_CA_CERTS included. That var is
|
|
29
|
+
* additive, but only to Node's BAKED-IN Mozilla roots, never to the system
|
|
30
|
+
* store — and on Daytona the leaf a client actually validates is signed by
|
|
31
|
+
* Daytona's proxy CA (its proxy terminates TLS; see installCa's comment), which
|
|
32
|
+
* lives in the system store and nowhere in Mozilla's roots. Point Node at the
|
|
33
|
+
* single Veris cert and it can verify neither that leaf nor a directly served
|
|
34
|
+
* gateway one behind it: UNABLE_TO_VERIFY_LEAF_SIGNATURE on every vendor call.
|
|
35
|
+
* The bundle carries the system store (Daytona's CA with it) plus ours, so it
|
|
36
|
+
* is the one file that works in both worlds.
|
|
33
37
|
*/
|
|
34
38
|
export declare function vendoredTrustEnv(): Record<string, string>;
|
|
39
|
+
/**
|
|
40
|
+
* The same variables as one POSIX `export` prelude, to prefix a command with.
|
|
41
|
+
*
|
|
42
|
+
* The map above is the right shape when you control the process's environment.
|
|
43
|
+
* A caller that does not — anything handing a command to a shell whose env it
|
|
44
|
+
* did not build — has nowhere to put a map, and the command inherits Daytona's
|
|
45
|
+
* overwritten SSL_CERT_FILE / REQUESTS_CA_BUNDLE / CURL_CA_BUNDLE /
|
|
46
|
+
* NODE_EXTRA_CA_CERTS instead. Measured with the inherited value: `uv sync`
|
|
47
|
+
* dies with "invalid peer certificate: UnknownIssuer". Prefixing this makes
|
|
48
|
+
* the command's own shell put the Veris bundle back:
|
|
49
|
+
*
|
|
50
|
+
* sandbox.process.executeCommand(`${trustPrelude()} ${yourCommand}`)
|
|
51
|
+
*
|
|
52
|
+
* Values are single-quoted, so the string stays one safe command line whatever
|
|
53
|
+
* the control plane served.
|
|
54
|
+
*/
|
|
55
|
+
export declare function trustPrelude(env?: Record<string, string>): string;
|
|
56
|
+
/**
|
|
57
|
+
* CA bundles that SDKs ship INSIDE the code under test, as slash-anchored path
|
|
58
|
+
* suffixes.
|
|
59
|
+
*
|
|
60
|
+
* No trust variable reaches these. stripe-python passes
|
|
61
|
+
* `verify=stripe.ca_bundle_path` explicitly, so all eighteen variables above
|
|
62
|
+
* are irrelevant to it and the first Stripe call dies with "Could not verify
|
|
63
|
+
* Stripe's SSL certificate" — the gateway's forged leaf is signed by a CA that
|
|
64
|
+
* file has never heard of. Appending our CA to the file keeps the SDK on the
|
|
65
|
+
* code path that ships; the bundle merely holds one more root.
|
|
66
|
+
*
|
|
67
|
+
* The table is the veris CLI's (internal/bundlescan), for the reason it gives
|
|
68
|
+
* there: matched as a path SUFFIX because site-packages prefixes vary per
|
|
69
|
+
* image and the tail does not, and deliberately with no bare `cacert.pem`
|
|
70
|
+
* rule, because that filename also names test fixtures and client-auth
|
|
71
|
+
* material that must not quietly gain a root.
|
|
72
|
+
*/
|
|
73
|
+
export declare const BUNDLED_CA_FILES: readonly {
|
|
74
|
+
sdk: string;
|
|
75
|
+
suffix: string;
|
|
76
|
+
}[];
|
|
77
|
+
/** Where the patch script is written inside the sandbox, so anything that can
|
|
78
|
+
* run a shell command — a test harness, an agent, a person over ssh — can
|
|
79
|
+
* re-run it after installing dependencies without holding this SDK. */
|
|
80
|
+
export declare const BUNDLED_CA_PATCH_SCRIPT = "/tmp/veris-patch-bundled-cas.sh";
|
|
81
|
+
/**
|
|
82
|
+
* What the script prints per patched file, so the caller can report what
|
|
83
|
+
* happened rather than infer it from an exit code.
|
|
84
|
+
*
|
|
85
|
+
* A sentence rather than a machine marker, because both routes to this script
|
|
86
|
+
* are read by a person. `provision` tells a caller to run `sh
|
|
87
|
+
* /tmp/veris-patch-bundled-cas.sh` themselves, and whatever the script prints
|
|
88
|
+
* is what they see — a bare `__VERIS_PATCHED__ /path` reads as debug output
|
|
89
|
+
* that escaped. `patchBundledCas()` parses the paths back off this same
|
|
90
|
+
* constant, and cli.ts prints the same sentence for the SDK route, so the
|
|
91
|
+
* prose a human reads and the list a program gets cannot drift apart.
|
|
92
|
+
*/
|
|
93
|
+
export declare const BUNDLED_CA_PATCHED_MARKER = "the Veris CA was appended to ";
|
|
94
|
+
/**
|
|
95
|
+
* The script that finds those bundles and appends the Veris CA to each.
|
|
96
|
+
*
|
|
97
|
+
* Meant to run AFTER dependencies are installed, and to be re-run: the bundles
|
|
98
|
+
* do not exist at create time, and an agent installs more of them mid-session,
|
|
99
|
+
* so there is no create-time moment that covers either. Idempotent by
|
|
100
|
+
* construction — a file already carrying our certificate is skipped, matched
|
|
101
|
+
* on a line of its base64 body rather than on the BEGIN line every certificate
|
|
102
|
+
* shares.
|
|
103
|
+
*
|
|
104
|
+
* Appending in place, where the CLI over-mounts a patched copy: a Daytona
|
|
105
|
+
* sandbox offers no bind mounts and the container is disposable, so editing
|
|
106
|
+
* the file is the equivalent move. Unwritable files are skipped rather than
|
|
107
|
+
* sudo'd — a root-owned bundle in the system Python is rarely the one the
|
|
108
|
+
* application's virtualenv reads, and silently rewriting system trust is a
|
|
109
|
+
* larger act than this warrants.
|
|
110
|
+
*/
|
|
111
|
+
export declare function bundledCaPatchScript(): string;
|
|
112
|
+
/**
|
|
113
|
+
* Node is the one runtime the trust variables above cannot reach.
|
|
114
|
+
*
|
|
115
|
+
* Daytona overwrites NODE_EXTRA_CA_CERTS and SSL_CERT_FILE inside the sandbox
|
|
116
|
+
* with its own CA file — right for clients that go through its proxy, which
|
|
117
|
+
* terminates TLS with that CA. Node is not such a client: it ignores
|
|
118
|
+
* HTTPS_PROXY, is forwarded to the gateway end to end, and the leaf it
|
|
119
|
+
* validates is signed by the Veris CA, which Daytona's file lacks. Seen live:
|
|
120
|
+
* plain `node` failed against a vendor host with UNABLE_TO_VERIFY_LEAF_SIGNATURE.
|
|
121
|
+
*/
|
|
122
|
+
/**
|
|
123
|
+
* Node's trust flag. NODE_EXTRA_CA_CERTS is Daytona's, and Node's baked-in
|
|
124
|
+
* Mozilla roots know neither CA — so switch Node to OpenSSL's store:
|
|
125
|
+
* --use-openssl-ca loads SSL_CERT_FILE (Daytona's file) AND the system
|
|
126
|
+
* certificate directory, where CA_INSTALL_CMD puts our CA and the distribution
|
|
127
|
+
* keeps the public roots. Injected as NODE_OPTIONS, which Daytona leaves alone.
|
|
128
|
+
*
|
|
129
|
+
* Verified live on Daytona's default image (uid 1001, passwordless sudo,
|
|
130
|
+
* update-ca-certificates present): 200 from plain `node` with the flag and
|
|
131
|
+
* our CA in /etc/ssl/certs; UNABLE_TO_VERIFY_LEAF_SIGNATURE without the flag.
|
|
132
|
+
* So this leans on the store install succeeding. There is no second route:
|
|
133
|
+
* Daytona's CA file is on a read-only mount, so appending our CA to it — the
|
|
134
|
+
* obvious alternative — fails for root too.
|
|
135
|
+
*/
|
|
136
|
+
export declare const NODE_TRUST_FLAG = "--use-openssl-ca";
|
|
137
|
+
/** NODE_OPTIONS with the trust flag appended to whatever the caller set. */
|
|
138
|
+
export declare function nodeOptionsWithTrust(existing?: string): string;
|
|
35
139
|
/**
|
|
36
140
|
* The store-based install, for stacks that read a trust store rather than an
|
|
37
141
|
* env var — a Java client honours no CA variable at all. Rebuilds the system
|
package/dist/veris-api.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ReceiptBaseline } from './run-receipt';
|
|
2
|
+
import type { ControlOptions, ControlResource } from './service-control';
|
|
1
3
|
import type { Sandbox } from '@daytona/sdk';
|
|
2
4
|
import type { ControlPlane, ServiceInfo } from './control-plane';
|
|
3
5
|
import type { Receipt, ReceiptEntry } from './receipt';
|
|
@@ -13,6 +15,13 @@ export interface VerisContext {
|
|
|
13
15
|
canaryHost: string;
|
|
14
16
|
/** Whether this twin is owned (delete removes it) or attached (caller owns it). */
|
|
15
17
|
ownsTwin: boolean;
|
|
18
|
+
/** Newest request id per service when this run began, so a receipt counts
|
|
19
|
+
* what the run caused rather than what an attached twin already held. Set by
|
|
20
|
+
* create(); a sandbox rehydrated by get() has none and reads the log from
|
|
21
|
+
* the start, as the receipt always did. Not persisted in a label on
|
|
22
|
+
* purpose — the sandbox can rewrite its own labels, and a watermark it
|
|
23
|
+
* chose would let it hide its own traffic from the receipt. */
|
|
24
|
+
watermarks?: Record<string, number>;
|
|
16
25
|
}
|
|
17
26
|
/** Narrow assertTouched to specific requests. All fields AND together. */
|
|
18
27
|
export interface TouchMatcher {
|
|
@@ -23,17 +32,32 @@ export interface TouchMatcher {
|
|
|
23
32
|
minRequests?: number;
|
|
24
33
|
}
|
|
25
34
|
export interface VerisApi {
|
|
35
|
+
/** Whether provider teardown owns this twin. */
|
|
36
|
+
readonly ownsTwin: boolean;
|
|
26
37
|
/** The Veris twin's sandbox id — NOT the Daytona sandbox id. */
|
|
27
38
|
readonly sandboxId: string;
|
|
39
|
+
/** The Veris environment the twin was deployed from. Every control-plane
|
|
40
|
+
* route that acts on a twin is scoped to it, so a caller that wants to talk
|
|
41
|
+
* to the twin itself needs it and has nowhere else to read it from. */
|
|
42
|
+
readonly environmentId: string;
|
|
28
43
|
readonly mode: 'gateway';
|
|
29
44
|
services(): Promise<ServiceInfo[]>;
|
|
30
45
|
/** The service's own manual: what it models and how its data is shaped. */
|
|
31
46
|
manual(service: string): Promise<string>;
|
|
47
|
+
receiptBaseline(): Promise<ReceiptBaseline>;
|
|
48
|
+
receiptSince(baseline: ReceiptBaseline, service?: string): Promise<Receipt>;
|
|
49
|
+
control(service: string, resource: ControlResource, options?: ControlOptions): Promise<unknown>;
|
|
32
50
|
receipt(): Promise<Receipt>;
|
|
33
51
|
receipt(service: string): Promise<ReceiptEntry>;
|
|
34
52
|
assertTouched(service: string, match?: TouchMatcher): Promise<void>;
|
|
35
53
|
getDataPlaneEnv(): Promise<Record<string, string>>;
|
|
36
54
|
getTrustEnv(): Record<string, string>;
|
|
55
|
+
/** The same trust variables as a shell `export` prelude, for a caller that
|
|
56
|
+
* can only prefix a command line. */
|
|
57
|
+
trustPrelude(): string;
|
|
58
|
+
/** Append the Veris CA to the CA bundles SDKs ship with them. Run it after
|
|
59
|
+
* installing dependencies; returns the files it changed. */
|
|
60
|
+
patchBundledCas(): Promise<string[]>;
|
|
37
61
|
deliverTo(port: number, opts?: DeliverToOpts): Promise<string>;
|
|
38
62
|
deliverTo(url: string | null, opts?: DeliverToOpts): Promise<string | null>;
|
|
39
63
|
}
|
|
@@ -45,7 +69,9 @@ export interface DeliverToOpts {
|
|
|
45
69
|
export declare class VerisApiImpl implements VerisApi {
|
|
46
70
|
private readonly ctx;
|
|
47
71
|
constructor(ctx: VerisContext);
|
|
72
|
+
get ownsTwin(): boolean;
|
|
48
73
|
get sandboxId(): string;
|
|
74
|
+
get environmentId(): string;
|
|
49
75
|
get mode(): 'gateway';
|
|
50
76
|
services(): Promise<ServiceInfo[]>;
|
|
51
77
|
/** Resolve a service by name. A typo and a service that exists but saw
|
|
@@ -60,10 +86,42 @@ export declare class VerisApiImpl implements VerisApi {
|
|
|
60
86
|
* ride around it — named rather than rounded off.
|
|
61
87
|
*/
|
|
62
88
|
private leaks;
|
|
89
|
+
/** Where this service's log was when the run began. 0 reads all of it. */
|
|
90
|
+
private watermark;
|
|
91
|
+
private verifyIntegrity;
|
|
92
|
+
receiptBaseline(): Promise<ReceiptBaseline>;
|
|
93
|
+
receiptSince(baseline: ReceiptBaseline, service?: string): Promise<Receipt>;
|
|
94
|
+
control(service: string, resource: ControlResource, options?: ControlOptions): Promise<unknown>;
|
|
63
95
|
assertTouched(service: string, match?: TouchMatcher): Promise<void>;
|
|
64
96
|
getDataPlaneEnv(): Promise<Record<string, string>>;
|
|
65
97
|
/** The CA trust vars injected at create, for callers building their own env. */
|
|
66
98
|
getTrustEnv(): Record<string, string>;
|
|
99
|
+
/**
|
|
100
|
+
* The same variables as a shell prelude, for a caller that has no env map to
|
|
101
|
+
* fill — anything running a command through a session or a shell it did not
|
|
102
|
+
* build the environment for. Daytona resets SSL_CERT_FILE,
|
|
103
|
+
* REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE and NODE_EXTRA_CA_CERTS to its own CA
|
|
104
|
+
* file inside the sandbox, and that file cannot verify the gateway's leaf, so
|
|
105
|
+
* a command that inherits them fails on certificate validation:
|
|
106
|
+
* `uv sync` dies with "invalid peer certificate: UnknownIssuer".
|
|
107
|
+
*
|
|
108
|
+
* sbx.process.executeCommand(`${sbx.veris.trustPrelude()} uv sync`)
|
|
109
|
+
*/
|
|
110
|
+
trustPrelude(): string;
|
|
111
|
+
/**
|
|
112
|
+
* Append the Veris CA to the CA bundles the code under test's own SDKs ship.
|
|
113
|
+
*
|
|
114
|
+
* The variables above reach every client that reads one. stripe-python does
|
|
115
|
+
* not: it passes `verify=stripe.ca_bundle_path`, so the first Stripe call
|
|
116
|
+
* fails with "Could not verify Stripe's SSL certificate" in a sandbox where
|
|
117
|
+
* curl, Node and `requests` all succeed. This patches the file itself, which
|
|
118
|
+
* is the Daytona-shaped version of the veris CLI's --patch-bundled-cas.
|
|
119
|
+
*
|
|
120
|
+
* Call it AFTER installing dependencies — the bundles arrive with them, so
|
|
121
|
+
* there is nothing to patch at create time. Safe to call again; it returns
|
|
122
|
+
* only the files it actually changed.
|
|
123
|
+
*/
|
|
124
|
+
patchBundledCas(): Promise<string[]>;
|
|
67
125
|
/**
|
|
68
126
|
* Point every mocked vendor's callbacks/webhooks at this sandbox.
|
|
69
127
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veris-ai/daytona",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Veris twin interception for Daytona: a drop-in @daytona/sdk whose sandboxes come up with a Veris twin already answering their vendor API calls. Unmodified code, real hostnames, receipts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"require": "./dist/index.cjs"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"veris-daytona": "./dist/cli.js"
|
|
18
|
+
},
|
|
16
19
|
"sideEffects": false,
|
|
17
20
|
"files": [
|
|
18
21
|
"dist",
|
|
@@ -28,6 +31,9 @@
|
|
|
28
31
|
"prepublishOnly": "npm run build",
|
|
29
32
|
"dev": "tsup --watch"
|
|
30
33
|
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"yaml": "^2.9.0"
|
|
36
|
+
},
|
|
31
37
|
"peerDependencies": {
|
|
32
38
|
"@daytona/sdk": ">=0.204.1 <1"
|
|
33
39
|
},
|