@tangle-network/cli-agent-registry 0.15.17 → 0.15.18

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.
@@ -44,4 +44,4 @@ declare function isBackendType(value: string): value is BackendType;
44
44
  declare function parseBackendType(value: string): BackendType;
45
45
  //#endregion
46
46
  export { isBackendType as a, backendTypeSchema as i, BACKEND_TYPE as n, parseBackendType as o, BackendType as r, ALL_BACKEND_TYPES as t };
47
- //# sourceMappingURL=backend-types-DRmLR1e0.d.mts.map
47
+ //# sourceMappingURL=backend-types-BZoSzUzQ.d.mts.map
@@ -1,2 +1,2 @@
1
- import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-DRmLR1e0.mjs";
1
+ import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-BZoSzUzQ.mjs";
2
2
  export { ALL_BACKEND_TYPES, BACKEND_TYPE, BackendType, backendTypeSchema, isBackendType, parseBackendType };
@@ -48,4 +48,4 @@ declare function assertCliAuthReferenceSupported(backendType: string, model: {
48
48
  declare function resolveCliAuthReference(backendType: string, model: Parameters<typeof assertCliAuthReferenceSupported>[1], environment: Readonly<Record<string, string | undefined>>): CliAuthMaterial | undefined;
49
49
  //#endregion
50
50
  export { assertCliAuthReferenceSupported as a, resolveCliAuthReference as c, LocalCliAuthFile as i, CliAuthReference as l, CLI_AUTH_REFERENCE_ENV_VAR as n, cliAuthFilesSchema as o, CliAuthMaterial as r, materializeCliAuthBundle as s, AUTH_BUNDLE_PATHS as t, cliAuthReferenceSchema as u };
51
- //# sourceMappingURL=cli-auth-bundle-CwAaH0Ap.d.mts.map
51
+ //# sourceMappingURL=cli-auth-bundle-BIABHp5D.d.mts.map
@@ -1,2 +1,2 @@
1
- import { a as assertCliAuthReferenceSupported, c as resolveCliAuthReference, i as LocalCliAuthFile, l as CliAuthReference, n as CLI_AUTH_REFERENCE_ENV_VAR, o as cliAuthFilesSchema, r as CliAuthMaterial, s as materializeCliAuthBundle, t as AUTH_BUNDLE_PATHS, u as cliAuthReferenceSchema } from "./cli-auth-bundle-CwAaH0Ap.mjs";
1
+ import { a as assertCliAuthReferenceSupported, c as resolveCliAuthReference, i as LocalCliAuthFile, l as CliAuthReference, n as CLI_AUTH_REFERENCE_ENV_VAR, o as cliAuthFilesSchema, r as CliAuthMaterial, s as materializeCliAuthBundle, t as AUTH_BUNDLE_PATHS, u as cliAuthReferenceSchema } from "./cli-auth-bundle-BIABHp5D.mjs";
2
2
  export { AUTH_BUNDLE_PATHS, CLI_AUTH_REFERENCE_ENV_VAR, CliAuthMaterial, CliAuthReference, LocalCliAuthFile, assertCliAuthReferenceSupported, cliAuthFilesSchema, cliAuthReferenceSchema, materializeCliAuthBundle, resolveCliAuthReference };
@@ -1,54 +1,28 @@
1
- import { l as CliAuthReference, r as CliAuthMaterial } from "./cli-auth-bundle-CwAaH0Ap.mjs";
2
- import { z } from "zod";
1
+ import { l as CliAuthReference, r as CliAuthMaterial } from "./cli-auth-bundle-BIABHp5D.mjs";
2
+ import { ProxySecretBinding, ProxySecretPresentation } from "@tangle-network/agent-interface";
3
3
 
4
4
  //#region src/cli-auth-placeholder.d.ts
5
- declare const metadataSchema: z.ZodObject<{
6
- accountId: z.ZodOptional<z.ZodString>;
7
- planType: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
8
- free: "free";
9
- plus: "plus";
10
- pro: "pro";
11
- business: "business";
12
- enterprise: "enterprise";
13
- edu: "edu";
14
- team: "team";
15
- }>, z.ZodEnum<{
16
- free: "free";
17
- pro: "pro";
18
- enterprise: "enterprise";
19
- team: "team";
20
- max: "max";
21
- }>]>>;
22
- accessTokenExpiresAt: z.ZodOptional<z.ZodNumber>;
23
- hasRefreshToken: z.ZodBoolean;
24
- }, z.core.$strict>;
25
- /** Routing/display hints only; these fields do not verify an account principal. */
26
- type CliAuthPlaceholderMetadata = z.infer<typeof metadataSchema>;
27
- type PlaceholderInput = {
28
- backendType: string;
29
- reference: CliAuthReference; /** The existing egress owner supplies this sandbox's declared-slot token. */
30
- placeholder: string; /** CLI compatibility timestamp, never an assertion of provider validity. */
31
- now: Date;
32
- metadata: CliAuthPlaceholderMetadata;
33
- };
34
- /** Build sandbox-safe native material without accepting any provider token. */
35
- declare function buildCliAuthPlaceholderMaterial(input: PlaceholderInput): CliAuthMaterial;
5
+ /** The box env name that holds a Codex seat's account-id placeholder. */
6
+ declare function nativeAccountEnv(secretEnv: string): string;
7
+ declare function isCliAuthPlaceholder(value: string | undefined): value is string;
8
+ /** The egress bindings that hold a native seat at the proxy; none: unholdable (#15834). */
9
+ declare function nativeProxyBindings(harness: string, reference: CliAuthReference): ProxySecretBinding[] | undefined;
36
10
  /**
37
- * TRUSTED OWNER ONLY. The explicit proxyAccessToken result must reach only the
38
- * host's existing egress holder. Only nativeMaterial may enter the sandbox.
39
- * The uploaded bundle, ID token and refresh token are never returned.
11
+ * TRUSTED OWNER ONLY: the value a proxy slot holds. A native bundle projects
12
+ * to its access token (bearer) or account id (header); every other value
13
+ * passes through; undefined refuses. Refresh and ID tokens never reach a slot.
40
14
  */
41
- declare function resolveCliAuthPlaceholder(input: {
15
+ declare function nativeProxyValue(raw: string, presentation: ProxySecretPresentation): string | undefined;
16
+ /** Sandbox-side native material built from placeholders only, never a provider token. */
17
+ declare function buildCliAuthPlaceholderMaterial(input: {
42
18
  backendType: string;
43
19
  reference: CliAuthReference;
44
- secretValue: string;
45
- placeholder: string;
20
+ placeholders: {
21
+ access: string;
22
+ account?: string;
23
+ };
46
24
  now: Date;
47
- }): {
48
- proxyAccessToken: string;
49
- nativeMaterial: CliAuthMaterial;
50
- metadata: CliAuthPlaceholderMetadata;
51
- };
25
+ }): CliAuthMaterial;
52
26
  //#endregion
53
- export { CliAuthPlaceholderMetadata, buildCliAuthPlaceholderMaterial, resolveCliAuthPlaceholder };
27
+ export { buildCliAuthPlaceholderMaterial, isCliAuthPlaceholder, nativeAccountEnv, nativeProxyBindings, nativeProxyValue };
54
28
  //# sourceMappingURL=cli-auth-placeholder.d.mts.map
@@ -1,118 +1,125 @@
1
- import { o as resolveCliAuthReference, r as assertCliAuthReferenceSupported, t as AUTH_BUNDLE_PATHS } from "./cli-auth-bundle-C6DtK7GX.mjs";
2
- import { i as baseProxyToken, r as declaredSecretSlotTokens } from "./harness-D1fTxnDD.mjs";
1
+ import { i as cliAuthFilesSchema, o as resolveCliAuthReference, r as assertCliAuthReferenceSupported, t as AUTH_BUNDLE_PATHS } from "./cli-auth-bundle-C6DtK7GX.mjs";
3
2
  import { z } from "zod";
4
3
  //#region src/cli-auth-placeholder.ts
5
- const identity = z.string().regex(/^[A-Za-z0-9_-]{1,256}$/);
6
4
  const token = z.string().min(8).max(64 * 1024).regex(/^[^\s\0]+$/);
7
- const expiry = z.number().int().positive().max(864e13);
8
- const codexPlan = z.enum([
9
- "free",
10
- "plus",
11
- "pro",
12
- "business",
13
- "enterprise",
14
- "edu",
15
- "team"
16
- ]);
17
- const claudePlan = z.enum([
18
- "free",
19
- "pro",
20
- "max",
21
- "team",
22
- "enterprise"
23
- ]);
24
- const metadataSchema = z.object({
25
- accountId: identity.optional(),
26
- planType: z.union([codexPlan, claudePlan]).optional(),
27
- accessTokenExpiresAt: expiry.optional(),
28
- hasRefreshToken: z.boolean()
29
- }).strict();
30
5
  const codexBundle = z.object({ tokens: z.object({
31
6
  access_token: token,
32
- refresh_token: z.union([token, z.literal("")]).optional(),
33
- id_token: token,
34
- account_id: identity.nullable().optional()
35
- }) });
36
- const codexClaims = z.object({ "https://api.openai.com/auth": z.object({
37
- chatgpt_account_id: identity.optional(),
38
- chatgpt_plan_type: codexPlan.optional(),
39
- chatgpt_account_is_fedramp: z.boolean().optional()
40
- }).optional() });
41
- const claudeBundle = z.object({ claudeAiOauth: z.object({
42
- accessToken: token,
43
- refreshToken: token.nullable().optional(),
44
- expiresAt: expiry.nullable().optional(),
45
- subscriptionType: claudePlan.nullable().optional()
7
+ account_id: z.string().regex(/^[A-Za-z0-9_-]{1,256}$/).nullable().optional()
46
8
  }) });
9
+ const claudeBundle = z.object({ claudeAiOauth: z.object({ accessToken: token }) });
10
+ const jwtHeader = btoa(JSON.stringify({
11
+ alg: "HS256",
12
+ typ: "JWT"
13
+ }));
14
+ const placeholderPattern = new RegExp(`^(?:proxy-declared-\\d+-token-|${jwtHeader}\\.[\\w-]+\\.)[\\w-]{43}$`);
47
15
  function invalidMaterial() {
48
16
  throw new Error("Unsupported or invalid native credential material");
49
17
  }
50
- function parseJson(raw) {
51
- try {
52
- return JSON.parse(raw);
53
- } catch {
54
- return invalidMaterial();
55
- }
18
+ const ACCOUNT_HEADER = "ChatGPT-Account-Id";
19
+ const isAccountHeader = (presentation) => presentation.type === "header" && presentation.name.toLowerCase() === ACCOUNT_HEADER.toLowerCase();
20
+ /** The box env name that holds a Codex seat's account-id placeholder. */
21
+ function nativeAccountEnv(secretEnv) {
22
+ return `${secretEnv}_ACCOUNT_ID`;
23
+ }
24
+ function isCliAuthPlaceholder(value) {
25
+ return value !== void 0 && placeholderPattern.test(value);
56
26
  }
57
- function jwtClaims(raw) {
58
- const parts = raw.split(".");
59
- if (parts.length !== 3 || parts.some((part) => !part)) return invalidMaterial();
27
+ /** The egress bindings that hold a native seat at the proxy; none: unholdable (#15834). */
28
+ function nativeProxyBindings(harness, reference) {
29
+ const secretRef = {
30
+ kind: "secret-ref",
31
+ key: reference.secretEnv
32
+ };
33
+ if (harness === "claude-code") return [{
34
+ envName: reference.secretEnv,
35
+ secretRef,
36
+ hosts: ["api.anthropic.com"],
37
+ presentation: { type: "bearer" },
38
+ placeholderFormat: "opaque"
39
+ }];
40
+ if (harness !== "codex") return void 0;
41
+ return [{
42
+ envName: reference.secretEnv,
43
+ secretRef,
44
+ hosts: ["chatgpt.com", "auth.openai.com"],
45
+ presentation: { type: "bearer" },
46
+ placeholderFormat: "jwt"
47
+ }, {
48
+ envName: nativeAccountEnv(reference.secretEnv),
49
+ secretRef,
50
+ hosts: ["chatgpt.com"],
51
+ presentation: {
52
+ type: "header",
53
+ name: ACCOUNT_HEADER
54
+ },
55
+ placeholderFormat: "opaque"
56
+ }];
57
+ }
58
+ function nativeBundle(raw) {
59
+ let value;
60
60
  try {
61
- const payload = (parts[1] ?? "").replaceAll("-", "+").replaceAll("_", "/");
62
- const bytes = Uint8Array.from(atob(payload), (value) => value.charCodeAt(0));
63
- return parseJson(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
61
+ value = JSON.parse(raw);
64
62
  } catch {
65
- return invalidMaterial();
63
+ return;
64
+ }
65
+ if (Array.isArray(value)) {
66
+ const auth = cliAuthFilesSchema.safeParse(value).data?.find(({ path }) => path === AUTH_BUNDLE_PATHS.codex || path === AUTH_BUNDLE_PATHS["claude-code"]);
67
+ return auth ? nativeBundle(auth.content) : void 0;
66
68
  }
69
+ const codex = codexBundle.safeParse(value);
70
+ if (codex.success) return {
71
+ access: codex.data.tokens.access_token,
72
+ account: codex.data.tokens.account_id ?? void 0
73
+ };
74
+ const claude = claudeBundle.safeParse(value);
75
+ return claude.success ? { access: claude.data.claudeAiOauth.accessToken } : void 0;
67
76
  }
68
- function accessTokenExpiry(value) {
69
- if (value.split(".").length !== 3) return void 0;
70
- const parsed = z.object({ exp: z.number().int().positive().optional() }).safeParse(jwtClaims(value));
71
- if (!parsed.success) return invalidMaterial();
72
- if (parsed.data.exp === void 0) return void 0;
73
- const result = expiry.safeParse(parsed.data.exp * 1e3);
74
- if (!result.success) return invalidMaterial();
75
- return result.data;
77
+ /**
78
+ * TRUSTED OWNER ONLY: the value a proxy slot holds. A native bundle projects
79
+ * to its access token (bearer) or account id (header); every other value
80
+ * passes through; undefined refuses. Refresh and ID tokens never reach a slot.
81
+ */
82
+ function nativeProxyValue(raw, presentation) {
83
+ const bundle = nativeBundle(raw);
84
+ if (!bundle) return isAccountHeader(presentation) ? void 0 : raw;
85
+ return presentation.type === "bearer" ? bundle.access : presentation.type === "header" ? bundle.account : void 0;
76
86
  }
77
- /** Build sandbox-safe native material without accepting any provider token. */
87
+ /** Sandbox-side native material built from placeholders only, never a provider token. */
78
88
  function buildCliAuthPlaceholderMaterial(input) {
79
89
  const reference = assertCliAuthReferenceSupported(input.backendType, { cliAuth: input.reference });
80
- const metadata = metadataSchema.safeParse(input.metadata);
81
- const declaredTokens = Object.values(declaredSecretSlotTokens());
82
- if (!reference || !metadata.success || !Number.isFinite(input.now.getTime()) || !declaredTokens.includes(baseProxyToken(input.placeholder)) || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(input.placeholder)) return invalidMaterial();
83
- if (input.backendType !== "codex" && input.backendType !== "claude-code") return invalidMaterial();
84
- if (input.backendType === "codex" && reference.format === "token") return invalidMaterial();
85
- const { accountId, planType, accessTokenExpiresAt, hasRefreshToken } = metadata.data;
90
+ const { access, account } = input.placeholders;
91
+ if (!reference || !isCliAuthPlaceholder(access) || account !== void 0 && !isCliAuthPlaceholder(account) || !Number.isFinite(input.now.getTime())) return invalidMaterial();
92
+ if (input.backendType === "claude-code" && reference.format === "token") return resolveCliAuthReference(input.backendType, { cliAuth: reference }, { [reference.secretEnv]: access }) ?? invalidMaterial();
86
93
  let content;
87
94
  if (input.backendType === "codex") {
88
- if (planType !== void 0 && !codexPlan.safeParse(planType).success) return invalidMaterial();
89
- const claims = {
90
- sub: input.placeholder,
91
- aud: "tangle-sandbox",
92
- exp: Math.floor(input.now.getTime() / 1e3)
93
- };
95
+ const [, payload] = access.split(".");
96
+ if (!payload) return invalidMaterial();
97
+ const base64 = payload.replaceAll("-", "+").replaceAll("_", "/");
98
+ const { exp } = z.object({ exp: z.number().int().positive() }).parse(JSON.parse(atob(base64)));
94
99
  content = {
95
100
  auth_mode: "chatgpt",
96
101
  OPENAI_API_KEY: null,
97
102
  tokens: {
98
- id_token: `e30.${btoa(JSON.stringify(claims)).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "")}.tangle-placeholder`,
99
- access_token: input.placeholder,
100
- refresh_token: hasRefreshToken ? input.placeholder : "",
101
- ...accountId ? { account_id: accountId } : {}
103
+ id_token: `e30.${btoa(JSON.stringify({
104
+ sub: "sandbox-placeholder",
105
+ aud: "tangle-sandbox",
106
+ exp
107
+ })).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "")}.tangle-placeholder`,
108
+ access_token: access,
109
+ refresh_token: "",
110
+ ...account ? { account_id: account } : {}
102
111
  },
103
112
  last_refresh: input.now.toISOString()
104
113
  };
105
- } else {
106
- if (planType !== void 0 && !claudePlan.safeParse(planType).success) return invalidMaterial();
107
- content = { claudeAiOauth: {
108
- accessToken: input.placeholder,
109
- refreshToken: hasRefreshToken ? input.placeholder : null,
110
- expiresAt: accessTokenExpiresAt ?? null,
111
- scopes: ["user:inference"],
112
- subscriptionType: planType ?? null,
113
- rateLimitTier: null
114
- } };
115
- }
114
+ } else if (input.backendType === "claude-code") content = { claudeAiOauth: {
115
+ accessToken: access,
116
+ refreshToken: null,
117
+ expiresAt: null,
118
+ scopes: ["user:inference"],
119
+ subscriptionType: null,
120
+ rateLimitTier: null
121
+ } };
122
+ else return invalidMaterial();
116
123
  return {
117
124
  reference,
118
125
  authFiles: [{
@@ -123,78 +130,7 @@ function buildCliAuthPlaceholderMaterial(input) {
123
130
  tokenEnvironment: {}
124
131
  };
125
132
  }
126
- /**
127
- * TRUSTED OWNER ONLY. The explicit proxyAccessToken result must reach only the
128
- * host's existing egress holder. Only nativeMaterial may enter the sandbox.
129
- * The uploaded bundle, ID token and refresh token are never returned.
130
- */
131
- function resolveCliAuthPlaceholder(input) {
132
- if (input.secretValue.length > 1024 * 1024) return invalidMaterial();
133
- const material = resolveCliAuthReference(input.backendType, { cliAuth: input.reference }, { [input.reference.secretEnv]: input.secretValue });
134
- if (!material) return invalidMaterial();
135
- let proxyAccessToken;
136
- let metadata;
137
- let credentials;
138
- if (input.backendType === "claude-code" && material.reference.format === "token") {
139
- const parsed = token.safeParse(Object.values(material.tokenEnvironment)[0]);
140
- if (!parsed.success) return invalidMaterial();
141
- proxyAccessToken = parsed.data;
142
- credentials = [proxyAccessToken];
143
- metadata = { hasRefreshToken: false };
144
- } else {
145
- const expectedPath = input.backendType === "codex" ? AUTH_BUNDLE_PATHS.codex : AUTH_BUNDLE_PATHS["claude-code"];
146
- if (material.authFiles.length !== 1 || material.authFiles[0]?.path !== expectedPath) return invalidMaterial();
147
- const bundle = parseJson(material.authFiles[0].content);
148
- if (input.backendType === "codex") {
149
- const parsed = codexBundle.safeParse(bundle);
150
- if (!parsed.success) return invalidMaterial();
151
- const tokens = parsed.data.tokens;
152
- const parsedClaims = codexClaims.safeParse(jwtClaims(tokens.id_token));
153
- if (!parsedClaims.success) return invalidMaterial();
154
- const claims = parsedClaims.data["https://api.openai.com/auth"];
155
- if (claims?.chatgpt_account_is_fedramp) return invalidMaterial();
156
- if (tokens.account_id && claims?.chatgpt_account_id && tokens.account_id !== claims.chatgpt_account_id) return invalidMaterial();
157
- proxyAccessToken = tokens.access_token;
158
- credentials = [
159
- proxyAccessToken,
160
- tokens.id_token,
161
- tokens.refresh_token ?? ""
162
- ];
163
- metadata = {
164
- accountId: tokens.account_id ?? claims?.chatgpt_account_id,
165
- planType: claims?.chatgpt_plan_type,
166
- accessTokenExpiresAt: accessTokenExpiry(proxyAccessToken),
167
- hasRefreshToken: Boolean(tokens.refresh_token)
168
- };
169
- } else if (input.backendType === "claude-code") {
170
- const parsed = claudeBundle.safeParse(bundle);
171
- if (!parsed.success) return invalidMaterial();
172
- const oauth = parsed.data.claudeAiOauth;
173
- proxyAccessToken = oauth.accessToken;
174
- credentials = [proxyAccessToken, oauth.refreshToken ?? ""];
175
- metadata = {
176
- planType: oauth.subscriptionType ?? void 0,
177
- accessTokenExpiresAt: oauth.expiresAt ?? void 0,
178
- hasRefreshToken: Boolean(oauth.refreshToken)
179
- };
180
- } else return invalidMaterial();
181
- }
182
- const nativeMaterial = buildCliAuthPlaceholderMaterial({
183
- ...input,
184
- metadata
185
- });
186
- const publicOutput = JSON.stringify({
187
- nativeMaterial,
188
- metadata
189
- });
190
- if (credentials.some((value) => value && publicOutput.includes(value))) return invalidMaterial();
191
- return {
192
- proxyAccessToken,
193
- nativeMaterial,
194
- metadata
195
- };
196
- }
197
133
  //#endregion
198
- export { buildCliAuthPlaceholderMaterial, resolveCliAuthPlaceholder };
134
+ export { buildCliAuthPlaceholderMaterial, isCliAuthPlaceholder, nativeAccountEnv, nativeProxyBindings, nativeProxyValue };
199
135
 
200
136
  //# sourceMappingURL=cli-auth-placeholder.mjs.map
@@ -1,6 +1,183 @@
1
+ import { n as HARNESS_WARM_TRANSPORT_ENV } from "./harness-contracts-BZoECCMc.mjs";
1
2
  import { l as getSpec } from "./specs-BBF55TnM.mjs";
2
3
  import { i as cliAuthFilesSchema, n as CLI_AUTH_REFERENCE_ENV_VAR, o as resolveCliAuthReference, s as cliAuthReferenceSchema } from "./cli-auth-bundle-C6DtK7GX.mjs";
3
- import { n as isSafeEnvVarName, t as isForbiddenEnvVarName } from "./harness-D1fTxnDD.mjs";
4
+ import { ProxySecretBindingSchema, ProxySecretGrantSchema, ProxySecretReceiptSchema, ProxySecretUpdateControlsSchema, ProxySecretsSchema, isProxySecretScopeAttenuation, ownPropertyRecordSchema, proxySecretPresentationsEqual } from "@tangle-network/agent-interface";
5
+ import { z } from "zod";
6
+ //#region ../runtime-contracts/dist/model-key-proxy.js
7
+ const MODEL_PROXY_TOKENS = {
8
+ OPENCODE_MODEL_API_KEY: "proxy-model-token",
9
+ OPENAI_API_KEY: "proxy-openai-token",
10
+ ANTHROPIC_API_KEY: "proxy-anthropic-token",
11
+ OPENROUTER_API_KEY: "proxy-openrouter-token",
12
+ TANGLE_INFERENCE_KEY: "proxy-openai-token",
13
+ ZAI_API_KEY: "proxy-zai-token",
14
+ ZHIPU_API_KEY: "proxy-zai-token"
15
+ };
16
+ new Set(Object.values(MODEL_PROXY_TOKENS));
17
+ new Set([
18
+ ...Object.keys(MODEL_PROXY_TOKENS),
19
+ "TANGLE_API_KEY",
20
+ "GITHUB_TOKEN",
21
+ "GH_TOKEN"
22
+ ]);
23
+ /** True for a slot name, which exists at the proxy and never in a box env. */
24
+ function isDeclaredSecretSlotEnvVar(name) {
25
+ return /^TANGLE_DECLARED_SLOT_\d+$/.test(name);
26
+ }
27
+ //#endregion
28
+ //#region ../runtime-contracts/dist/proxy-secret-materialization.js
29
+ const syntheticHeader = {
30
+ alg: "HS256",
31
+ typ: "JWT"
32
+ };
33
+ const encode = (value) => btoa(value instanceof Uint8Array ? String.fromCharCode(...value) : JSON.stringify(value)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
34
+ function placeholderPrefix(slot, format, expiresAt) {
35
+ return format === "jwt" ? `${encode(syntheticHeader)}.${encode({
36
+ sub: "sandbox-placeholder",
37
+ aud: "proxy-secret-placeholder",
38
+ exp: Math.floor(Date.parse(expiresAt) / 1e3)
39
+ })}.` : `proxy-declared-${slot.slice(21)}-token-`;
40
+ }
41
+ function isSyntheticPlaceholder(material) {
42
+ const prefix = placeholderPrefix(material.slot, material.grant.placeholderFormat, material.issuerExpiresAt);
43
+ return material.placeholder.startsWith(prefix) && /^[A-Za-z0-9_-]{43}$/.test(material.placeholder.slice(prefix.length));
44
+ }
45
+ z.array(z.strictObject({
46
+ binding: ProxySecretBindingSchema,
47
+ grant: ProxySecretGrantSchema,
48
+ placeholder: z.string().min(1),
49
+ slot: z.string().refine(isDeclaredSecretSlotEnvVar),
50
+ issuerExpiresAt: z.iso.datetime()
51
+ })).superRefine((materials, ctx) => {
52
+ const bindings = ProxySecretsSchema.safeParse(materials.map((m) => m.binding));
53
+ const unique = (values) => new Set(values).size === values.length;
54
+ if (!bindings.success || !unique(materials.map((m) => m.slot)) || !unique(materials.map((m) => m.placeholder)) || !unique(materials.map((m) => m.grant.grantId)) || new Set(materials.map((m) => m.grant.epoch)).size > 1 || new Set(materials.map((m) => m.grant.sandboxId)).size > 1 || materials.some((material) => !isSyntheticPlaceholder(material)) || materials.some(({ binding, grant, issuerExpiresAt }) => !isProxySecretScopeAttenuation(binding, grant.scope) || !proxySecretPresentationsEqual(binding.presentation, grant.presentation) || (binding.placeholderFormat ?? "opaque") !== grant.placeholderFormat || Date.parse(grant.expiresAt) > Date.parse(issuerExpiresAt))) ctx.addIssue({
55
+ code: "custom",
56
+ message: "Invalid proxy secret materialization"
57
+ });
58
+ });
59
+ ProxySecretUpdateControlsSchema.extend({
60
+ resolvedSecrets: ownPropertyRecordSchema(z.string().min(1), { maxEntries: Number.MAX_SAFE_INTEGER }).default({}),
61
+ proxySecretGrants: ProxySecretReceiptSchema.options[0].shape.bindings,
62
+ expectedProxySecretGeneration: ProxySecretUpdateControlsSchema.shape.expectedProxySecretGeneration.unwrap()
63
+ }).strict().refine((body) => new Set(body.proxySecretGrants.map((b) => b.envName)).size === body.proxySecretGrants.length);
64
+ //#endregion
65
+ //#region ../runtime-contracts/dist/runtime-environment.js
66
+ const SAFE_ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
67
+ function isSafeEnvVarName(name) {
68
+ if (typeof name !== "string") return false;
69
+ if (name.length === 0 || name.length > 256) return false;
70
+ return SAFE_ENV_VAR_NAME_RE.test(name);
71
+ }
72
+ /** Client proxy URLs first, then bypass names. */
73
+ const EGRESS_PROXY_ENV_NAMES = [
74
+ "HTTPS_PROXY",
75
+ "https_proxy",
76
+ "HTTP_PROXY",
77
+ "http_proxy",
78
+ "NO_PROXY",
79
+ "no_proxy"
80
+ ];
81
+ const CA_TRUST_ENV_NAMES = [
82
+ "NODE_EXTRA_CA_CERTS",
83
+ "SSL_CERT_FILE",
84
+ "CURL_CA_BUNDLE",
85
+ "GIT_SSL_CAINFO",
86
+ "NIX_SSL_CERT_FILE"
87
+ ];
88
+ [...EGRESS_PROXY_ENV_NAMES, ...CA_TRUST_ENV_NAMES];
89
+ const FORBIDDEN_ENV_VAR_NAMES = new Set([
90
+ "LD_PRELOAD",
91
+ "LD_LIBRARY_PATH",
92
+ "LD_AUDIT",
93
+ "DYLD_INSERT_LIBRARIES",
94
+ "DYLD_LIBRARY_PATH",
95
+ "DYLD_FALLBACK_LIBRARY_PATH",
96
+ "NODE_OPTIONS",
97
+ "NODE_PATH",
98
+ "NODE_TLS_REJECT_UNAUTHORIZED",
99
+ "PYTHONPATH",
100
+ "PYTHONSTARTUP",
101
+ "PERL5OPT",
102
+ "PERL5LIB",
103
+ "RUBYOPT",
104
+ "RUBYLIB",
105
+ "PATH",
106
+ "NIX_BIN_PATH",
107
+ "EGRESS_EDGE_POOL_ENABLED",
108
+ "EDGE_BIND_ID",
109
+ "PRIVACY_EGRESS",
110
+ "LOG_REDACT",
111
+ "IFS",
112
+ "BASH_ENV",
113
+ "ENV",
114
+ "SHELL",
115
+ "SHELLOPTS",
116
+ "PROMPT_COMMAND",
117
+ "HOME",
118
+ "XDG_CONFIG_HOME",
119
+ "XDG_DATA_HOME",
120
+ "XDG_CACHE_HOME",
121
+ "XDG_STATE_HOME",
122
+ "XDG_RUNTIME_DIR",
123
+ "HTTPS_PROXY",
124
+ "HTTP_PROXY",
125
+ "ALL_PROXY",
126
+ "NO_PROXY",
127
+ "https_proxy",
128
+ "http_proxy",
129
+ "all_proxy",
130
+ "no_proxy",
131
+ "SSL_CERT_FILE",
132
+ "SSL_CERT_DIR",
133
+ "REQUESTS_CA_BUNDLE",
134
+ "CURL_CA_BUNDLE",
135
+ "NODE_EXTRA_CA_CERTS",
136
+ "HOSTNAME",
137
+ "CONTAINER_ID",
138
+ "AGENT_WORKSPACE_ROOT",
139
+ "WORKSPACE_PATH",
140
+ "STORAGE_PATH",
141
+ "WORKSPACE_FILE_API_ROOT_ONLY",
142
+ "WORKSPACE_ALLOWED_ABSOLUTE_PATHS",
143
+ "TANGLE_PLAN_CALLBACK_ALLOWED_ORIGINS"
144
+ ]);
145
+ const FORBIDDEN_ENV_VAR_PREFIXES = [
146
+ "SIDECAR_",
147
+ "ORCHESTRATOR_",
148
+ "AGENT_INTERNAL_",
149
+ "SANDBOX_DEV_",
150
+ "AGENT_SUBPROCESS_",
151
+ "TEE_ATTESTATION_"
152
+ ];
153
+ const RUNTIME_CALLER_ALLOWED_ENV_NAMES = new Set(["SIDECAR_CAPABILITIES", "SIDECAR_PLATFORM_CONTROL_RUNTIME"]);
154
+ new Set(Object.values(HARNESS_WARM_TRANSPORT_ENV).flatMap(({ warmServer, prewarm }) => [warmServer, prewarm]));
155
+ function isForbiddenEnvVarName(name) {
156
+ if (RUNTIME_CALLER_ALLOWED_ENV_NAMES.has(name)) return false;
157
+ if (FORBIDDEN_ENV_VAR_NAMES.has(name)) return true;
158
+ for (const prefix of FORBIDDEN_ENV_VAR_PREFIXES) if (name.startsWith(prefix)) return true;
159
+ return false;
160
+ }
161
+ /**
162
+ * POSIX names for caller-owned container env. Runtime process.env merges must additionally enforce
163
+ * isForbiddenEnvVarName, including project provisioning and Sidecar config.
164
+ */
165
+ const safeEnvRecordSchema = ownPropertyRecordSchema(z.string(), { maxEntries: Number.MAX_SAFE_INTEGER }).refine((value) => Object.keys(value).every(isSafeEnvVarName), { message: "invalid env var name" });
166
+ /** Names only: the caller must keep a separate source and pass values to resume({ env }). */
167
+ const sandboxEnvRecoverySchema = z.object({ callerResupplies: z.array(z.string().max(256).refine(isSafeEnvVarName, { message: "invalid env var name" })).max(128).refine((keys) => new Set(keys).size === keys.length, { message: "callerResupplies must contain unique keys" }) }).strict();
168
+ z.object({
169
+ envRecovery: sandboxEnvRecoverySchema,
170
+ dryRun: z.boolean().optional()
171
+ }).strict();
172
+ z.object({
173
+ envRecovery: sandboxEnvRecoverySchema,
174
+ eligibleCallerResupplyKeys: z.array(z.string()),
175
+ requiredOnColdResumeKeys: z.array(z.string()),
176
+ automaticCredentialRecovery: z.literal(false),
177
+ dryRun: z.boolean()
178
+ }).strict();
179
+ safeEnvRecordSchema.refine((value) => Object.keys(value).every((key) => !isForbiddenEnvVarName(key) && !key.startsWith("SIDECAR_")), { message: "runtime-owned env var name cannot be set by callers" });
180
+ //#endregion
4
181
  //#region src/cli-backend-auth-env.ts
5
182
  /** The narrow credential leg shared by the host and sidecar rebind boundary. */
6
183
  function assertCliBackendAuthEnv(backendType, authEnv) {
@@ -1,4 +1,4 @@
1
- import { r as BackendType } from "./backend-types-DRmLR1e0.mjs";
1
+ import { r as BackendType } from "./backend-types-BZoSzUzQ.mjs";
2
2
  //#region src/default-backend.d.ts
3
3
  /**
4
4
  * Platform-wide default agent backend, read from `DEFAULT_AGENT_BACKEND`.
@@ -1,5 +1,5 @@
1
- import { o as CliAgentEnvVars } from "./spec-CcvTM7-j.mjs";
2
- import { o as NativeSessionStore } from "./session-contract-BhzcbPRW.mjs";
1
+ import { o as CliAgentEnvVars } from "./spec-0SzopzVq.mjs";
2
+ import { o as NativeSessionStore } from "./session-contract-ChAfXj67.mjs";
3
3
 
4
4
  //#region src/host-contracts.d.ts
5
5
  type HostStore = Omit<NativeSessionStore, "format"> & {
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-DRmLR1e0.mjs";
2
- import { i as LocalCliAuthFile, s as materializeCliAuthBundle } from "./cli-auth-bundle-CwAaH0Ap.mjs";
3
- import { C as mergeCliDirLayout, S as DEFAULT_CLI_DIR_LAYOUT, _ as harnessModelSupportFor, a as CliAgentEnvExtraRole, b as CliDirLayout, c as CliAgentRuntimeSpec, d as HarnessSpecCapabilities, f as ProviderLogger, g as cliAgentEnvRoleName, h as cliAgentClaimEnvVarNames, i as CliAgentEnvExtraParser, l as CliAgentSpec, m as canonicalModelSlug, n as CliAgentBuiltinTool, o as CliAgentEnvVars, p as ProviderPhase, r as CliAgentEnvExtra, s as CliAgentModelWire, t as AdapterFactory, u as CliAuthHome, v as harnessModelWire, x as CliDirLayoutAdditions, y as SYNTHETIC_ROUTER_MODEL } from "./spec-CcvTM7-j.mjs";
4
- import { _ as substituteNativeSessionId, a as NativeSessionIdentity, c as SessionFormatId, d as assertStoreLocationHonoursSessionContract, f as compileSessionStoreGlob, g as sessionStoreForPath, h as sessionContractProblems, i as HarnessSessionEvidence, l as assertArgvHonoursSessionContract, m as normalizePosixPath, n as HarnessSessionContractError, o as NativeSessionStore, p as forbiddenArgViolations, r as HarnessSessionContractErrorCode, s as SESSION_FORMAT_IDS, t as HarnessSessionContract, u as assertFlagsHonourSessionContract } from "./session-contract-BhzcbPRW.mjs";
1
+ import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-BZoSzUzQ.mjs";
2
+ import { i as LocalCliAuthFile, s as materializeCliAuthBundle } from "./cli-auth-bundle-BIABHp5D.mjs";
3
+ import { C as mergeCliDirLayout, S as DEFAULT_CLI_DIR_LAYOUT, _ as harnessModelSupportFor, a as CliAgentEnvExtraRole, b as CliDirLayout, c as CliAgentRuntimeSpec, d as HarnessSpecCapabilities, f as ProviderLogger, g as cliAgentEnvRoleName, h as cliAgentClaimEnvVarNames, i as CliAgentEnvExtraParser, l as CliAgentSpec, m as canonicalModelSlug, n as CliAgentBuiltinTool, o as CliAgentEnvVars, p as ProviderPhase, r as CliAgentEnvExtra, s as CliAgentModelWire, t as AdapterFactory, u as CliAuthHome, v as harnessModelWire, x as CliDirLayoutAdditions, y as SYNTHETIC_ROUTER_MODEL } from "./spec-0SzopzVq.mjs";
4
+ import { _ as substituteNativeSessionId, a as NativeSessionIdentity, c as SessionFormatId, d as assertStoreLocationHonoursSessionContract, f as compileSessionStoreGlob, g as sessionStoreForPath, h as sessionContractProblems, i as HarnessSessionEvidence, l as assertArgvHonoursSessionContract, m as normalizePosixPath, n as HarnessSessionContractError, o as NativeSessionStore, p as forbiddenArgViolations, r as HarnessSessionContractErrorCode, s as SESSION_FORMAT_IDS, t as HarnessSessionContract, u as assertFlagsHonourSessionContract } from "./session-contract-ChAfXj67.mjs";
5
5
  import { AGENT_BACKEND_ENV_VAR, CLI_AGENT_SPECS, MANAGED_MODEL_KEY_ENV_VAR, MANAGED_MODEL_KEY_NAME_ENV_VAR, agentProfileSchema, claimDeliverableEnvVarNames, cliAgentEnvVarNamesByRole, cliAgentHostPassthroughEnvVarNames, getSpec, messageStorageDirOf } from "./specs.mjs";
6
6
  import { resolveDefaultBackend } from "./default-backend.mjs";
7
7
  import { describeLocalCliAuthExpectation, discoverLocalCliAuthFiles } from "./local-cli-auth.mjs";
@@ -1,4 +1,4 @@
1
- import { i as LocalCliAuthFile } from "./cli-auth-bundle-CwAaH0Ap.mjs";
1
+ import { i as LocalCliAuthFile } from "./cli-auth-bundle-BIABHp5D.mjs";
2
2
 
3
3
  //#region src/local-cli-auth.d.ts
4
4
  type LocalCliAuthBackend = "codex" | "claude-code";
@@ -1,4 +1,4 @@
1
- import { o as NativeSessionStore } from "./session-contract-BhzcbPRW.mjs";
1
+ import { o as NativeSessionStore } from "./session-contract-ChAfXj67.mjs";
2
2
 
3
3
  //#region src/native-session-contracts.d.ts
4
4
  /** Native session contracts. A receipt proves each pin. There is no pending list. */
@@ -94,4 +94,4 @@ declare function sessionStoreForPath(contract: Pick<HarnessSessionContract, "sto
94
94
  declare function sessionContractProblems(contract: HarnessSessionContract): string[];
95
95
  //#endregion
96
96
  export { substituteNativeSessionId as _, NativeSessionIdentity as a, SessionFormatId as c, assertStoreLocationHonoursSessionContract as d, compileSessionStoreGlob as f, sessionStoreForPath as g, sessionContractProblems as h, HarnessSessionEvidence as i, assertArgvHonoursSessionContract as l, normalizePosixPath as m, HarnessSessionContractError as n, NativeSessionStore as o, forbiddenArgViolations as p, HarnessSessionContractErrorCode as r, SESSION_FORMAT_IDS as s, HarnessSessionContract as t, assertFlagsHonourSessionContract as u };
97
- //# sourceMappingURL=session-contract-BhzcbPRW.d.mts.map
97
+ //# sourceMappingURL=session-contract-ChAfXj67.d.mts.map
@@ -1,2 +1,2 @@
1
- import { _ as substituteNativeSessionId, a as NativeSessionIdentity, c as SessionFormatId, d as assertStoreLocationHonoursSessionContract, f as compileSessionStoreGlob, g as sessionStoreForPath, h as sessionContractProblems, i as HarnessSessionEvidence, l as assertArgvHonoursSessionContract, m as normalizePosixPath, n as HarnessSessionContractError, o as NativeSessionStore, p as forbiddenArgViolations, r as HarnessSessionContractErrorCode, s as SESSION_FORMAT_IDS, t as HarnessSessionContract, u as assertFlagsHonourSessionContract } from "./session-contract-BhzcbPRW.mjs";
1
+ import { _ as substituteNativeSessionId, a as NativeSessionIdentity, c as SessionFormatId, d as assertStoreLocationHonoursSessionContract, f as compileSessionStoreGlob, g as sessionStoreForPath, h as sessionContractProblems, i as HarnessSessionEvidence, l as assertArgvHonoursSessionContract, m as normalizePosixPath, n as HarnessSessionContractError, o as NativeSessionStore, p as forbiddenArgViolations, r as HarnessSessionContractErrorCode, s as SESSION_FORMAT_IDS, t as HarnessSessionContract, u as assertFlagsHonourSessionContract } from "./session-contract-ChAfXj67.mjs";
2
2
  export { HarnessSessionContract, HarnessSessionContractError, HarnessSessionContractErrorCode, HarnessSessionEvidence, NativeSessionIdentity, NativeSessionStore, SESSION_FORMAT_IDS, SessionFormatId, assertArgvHonoursSessionContract, assertFlagsHonourSessionContract, assertStoreLocationHonoursSessionContract, compileSessionStoreGlob, forbiddenArgViolations, normalizePosixPath, sessionContractProblems, sessionStoreForPath, substituteNativeSessionId };
@@ -1,4 +1,4 @@
1
- import { t as HarnessSessionContract } from "./session-contract-BhzcbPRW.mjs";
1
+ import { t as HarnessSessionContract } from "./session-contract-ChAfXj67.mjs";
2
2
  import { SdkProviderAdapter, WellKnownInteractionKind } from "@tangle-network/agent-interface";
3
3
  import { HarnessModelSupport, HarnessModelSupportOptions } from "@tangle-network/agent-interface/harness-capabilities";
4
4
 
@@ -343,4 +343,4 @@ type ProviderLogger = {
343
343
  };
344
344
  //#endregion
345
345
  export { mergeCliDirLayout as C, DEFAULT_CLI_DIR_LAYOUT as S, harnessModelSupportFor as _, CliAgentEnvExtraRole as a, CliDirLayout as b, CliAgentRuntimeSpec as c, HarnessSpecCapabilities as d, ProviderLogger as f, cliAgentEnvRoleName as g, cliAgentClaimEnvVarNames as h, CliAgentEnvExtraParser as i, CliAgentSpec as l, canonicalModelSlug as m, CliAgentBuiltinTool as n, CliAgentEnvVars as o, ProviderPhase as p, CliAgentEnvExtra as r, CliAgentModelWire as s, AdapterFactory as t, CliAuthHome as u, harnessModelWire as v, CliDirLayoutAdditions as x, SYNTHETIC_ROUTER_MODEL as y };
346
- //# sourceMappingURL=spec-CcvTM7-j.d.mts.map
346
+ //# sourceMappingURL=spec-0SzopzVq.d.mts.map
package/dist/specs.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-DRmLR1e0.mjs";
2
- import { _ as harnessModelSupportFor, h as cliAgentClaimEnvVarNames, l as CliAgentSpec, m as canonicalModelSlug, s as CliAgentModelWire, v as harnessModelWire } from "./spec-CcvTM7-j.mjs";
1
+ import { a as isBackendType, i as backendTypeSchema, n as BACKEND_TYPE, o as parseBackendType, r as BackendType, t as ALL_BACKEND_TYPES } from "./backend-types-BZoSzUzQ.mjs";
2
+ import { _ as harnessModelSupportFor, h as cliAgentClaimEnvVarNames, l as CliAgentSpec, m as canonicalModelSlug, s as CliAgentModelWire, v as harnessModelWire } from "./spec-0SzopzVq.mjs";
3
3
  import { agentProfileSchema } from "@tangle-network/agent-interface";
4
4
 
5
5
  //#region src/specs.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/cli-agent-registry",
3
- "version": "0.15.17",
3
+ "version": "0.15.18",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./cli-backend-auth-env": {
@@ -72,12 +72,12 @@
72
72
  "tsdown": "^0.21.10",
73
73
  "typescript": "^6.0.3",
74
74
  "vitest": "^4.1.12",
75
- "@tangle-network/runtime-contracts": "0.20.0",
76
- "@repo/airgap-guard": "0.0.0"
75
+ "@repo/airgap-guard": "0.0.0",
76
+ "@tangle-network/runtime-contracts": "0.20.0"
77
77
  },
78
78
  "tangleRelease": {
79
- "sourceSha": "973885fb1b534df359ea87b20d9899795cb8e86d",
80
- "mergedAt": "2026-11-04T17:23:46-08:00"
79
+ "sourceSha": "43c80a52416594589d8f5b17345dcff37f0fd2ae",
80
+ "mergedAt": "2026-11-04T17:58:22-08:00"
81
81
  },
82
82
  "scripts": {
83
83
  "build": "tsdown && node scripts/export-host-contracts.mjs --write",
@@ -1,199 +0,0 @@
1
- import { n as HARNESS_WARM_TRANSPORT_ENV } from "./harness-contracts-BZoECCMc.mjs";
2
- import { ProxySecretBindingSchema, ProxySecretGrantSchema, ProxySecretReceiptSchema, ProxySecretUpdateControlsSchema, ProxySecretsSchema, isProxySecretScopeAttenuation, ownPropertyRecordSchema, proxySecretPresentationsEqual } from "@tangle-network/agent-interface";
3
- import { z } from "zod";
4
- function baseProxyToken(token) {
5
- const i = token.indexOf(".");
6
- return i === -1 ? token : token.slice(0, i);
7
- }
8
- const MODEL_PROXY_TOKENS = {
9
- OPENCODE_MODEL_API_KEY: "proxy-model-token",
10
- OPENAI_API_KEY: "proxy-openai-token",
11
- ANTHROPIC_API_KEY: "proxy-anthropic-token",
12
- OPENROUTER_API_KEY: "proxy-openrouter-token",
13
- TANGLE_INFERENCE_KEY: "proxy-openai-token",
14
- ZAI_API_KEY: "proxy-zai-token",
15
- ZHIPU_API_KEY: "proxy-zai-token"
16
- };
17
- new Set(Object.values(MODEL_PROXY_TOKENS));
18
- new Set([
19
- ...Object.keys(MODEL_PROXY_TOKENS),
20
- "TANGLE_API_KEY",
21
- "GITHUB_TOKEN",
22
- "GH_TOKEN"
23
- ]);
24
- /** Proxy-private slot names shared by legacy and canonical bindings. */
25
- function declaredSecretSlotEnvVar(index) {
26
- return `TANGLE_DECLARED_SLOT_${index}`;
27
- }
28
- /** True for a slot name, which exists at the proxy and never in a box env. */
29
- function isDeclaredSecretSlotEnvVar(name) {
30
- return /^TANGLE_DECLARED_SLOT_\d+$/.test(name);
31
- }
32
- /** The base placeholder for the slot at `index`; the box holds it salted. */
33
- function declaredSecretBaseToken(index) {
34
- return `proxy-declared-${index}-token`;
35
- }
36
- /** Every slot name mapped to its base placeholder. */
37
- function declaredSecretSlotTokens() {
38
- const slots = {};
39
- for (let index = 0; index < 16; index++) slots[declaredSecretSlotEnvVar(index)] = declaredSecretBaseToken(index);
40
- return slots;
41
- }
42
- //#endregion
43
- //#region ../runtime-contracts/dist/proxy-secret-materialization.js
44
- const syntheticHeader = {
45
- alg: "HS256",
46
- typ: "JWT"
47
- };
48
- const encode = (value) => btoa(value instanceof Uint8Array ? String.fromCharCode(...value) : JSON.stringify(value)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
49
- function placeholderPrefix(slot, format, expiresAt) {
50
- return format === "jwt" ? `${encode(syntheticHeader)}.${encode({
51
- sub: "sandbox-placeholder",
52
- aud: "proxy-secret-placeholder",
53
- exp: Math.floor(Date.parse(expiresAt) / 1e3)
54
- })}.` : `proxy-declared-${slot.slice(21)}-token-`;
55
- }
56
- function isSyntheticPlaceholder(material) {
57
- const prefix = placeholderPrefix(material.slot, material.grant.placeholderFormat, material.issuerExpiresAt);
58
- return material.placeholder.startsWith(prefix) && /^[A-Za-z0-9_-]{43}$/.test(material.placeholder.slice(prefix.length));
59
- }
60
- z.array(z.strictObject({
61
- binding: ProxySecretBindingSchema,
62
- grant: ProxySecretGrantSchema,
63
- placeholder: z.string().min(1),
64
- slot: z.string().refine(isDeclaredSecretSlotEnvVar),
65
- issuerExpiresAt: z.iso.datetime(),
66
- native: z.unknown().optional()
67
- })).superRefine((materials, ctx) => {
68
- const bindings = ProxySecretsSchema.safeParse(materials.map((m) => m.binding));
69
- const unique = (values) => new Set(values).size === values.length;
70
- if (!bindings.success || !unique(materials.map((m) => m.slot)) || !unique(materials.map((m) => m.placeholder)) || !unique(materials.map((m) => m.grant.grantId)) || new Set(materials.map((m) => m.grant.epoch)).size > 1 || new Set(materials.map((m) => m.grant.sandboxId)).size > 1 || materials.some((material) => !isSyntheticPlaceholder(material)) || materials.some(({ binding, grant, issuerExpiresAt }) => !isProxySecretScopeAttenuation(binding, grant.scope) || !proxySecretPresentationsEqual(binding.presentation, grant.presentation) || (binding.placeholderFormat ?? "opaque") !== grant.placeholderFormat || Date.parse(grant.expiresAt) > Date.parse(issuerExpiresAt))) ctx.addIssue({
71
- code: "custom",
72
- message: "Invalid proxy secret materialization"
73
- });
74
- });
75
- ProxySecretUpdateControlsSchema.extend({
76
- resolvedSecrets: ownPropertyRecordSchema(z.string().min(1), { maxEntries: Number.MAX_SAFE_INTEGER }).default({}),
77
- proxySecretGrants: ProxySecretReceiptSchema.options[0].shape.bindings,
78
- expectedProxySecretGeneration: ProxySecretUpdateControlsSchema.shape.expectedProxySecretGeneration.unwrap()
79
- }).strict().refine((body) => new Set(body.proxySecretGrants.map((b) => b.envName)).size === body.proxySecretGrants.length);
80
- //#endregion
81
- //#region ../runtime-contracts/dist/runtime-environment.js
82
- const SAFE_ENV_VAR_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
83
- function isSafeEnvVarName(name) {
84
- if (typeof name !== "string") return false;
85
- if (name.length === 0 || name.length > 256) return false;
86
- return SAFE_ENV_VAR_NAME_RE.test(name);
87
- }
88
- /** Client proxy URLs first, then bypass names. */
89
- const EGRESS_PROXY_ENV_NAMES = [
90
- "HTTPS_PROXY",
91
- "https_proxy",
92
- "HTTP_PROXY",
93
- "http_proxy",
94
- "NO_PROXY",
95
- "no_proxy"
96
- ];
97
- const CA_TRUST_ENV_NAMES = [
98
- "NODE_EXTRA_CA_CERTS",
99
- "SSL_CERT_FILE",
100
- "CURL_CA_BUNDLE",
101
- "GIT_SSL_CAINFO",
102
- "NIX_SSL_CERT_FILE"
103
- ];
104
- [...EGRESS_PROXY_ENV_NAMES, ...CA_TRUST_ENV_NAMES];
105
- const FORBIDDEN_ENV_VAR_NAMES = new Set([
106
- "LD_PRELOAD",
107
- "LD_LIBRARY_PATH",
108
- "LD_AUDIT",
109
- "DYLD_INSERT_LIBRARIES",
110
- "DYLD_LIBRARY_PATH",
111
- "DYLD_FALLBACK_LIBRARY_PATH",
112
- "NODE_OPTIONS",
113
- "NODE_PATH",
114
- "NODE_TLS_REJECT_UNAUTHORIZED",
115
- "PYTHONPATH",
116
- "PYTHONSTARTUP",
117
- "PERL5OPT",
118
- "PERL5LIB",
119
- "RUBYOPT",
120
- "RUBYLIB",
121
- "PATH",
122
- "NIX_BIN_PATH",
123
- "EGRESS_EDGE_POOL_ENABLED",
124
- "EDGE_BIND_ID",
125
- "PRIVACY_EGRESS",
126
- "LOG_REDACT",
127
- "IFS",
128
- "BASH_ENV",
129
- "ENV",
130
- "SHELL",
131
- "SHELLOPTS",
132
- "PROMPT_COMMAND",
133
- "HOME",
134
- "XDG_CONFIG_HOME",
135
- "XDG_DATA_HOME",
136
- "XDG_CACHE_HOME",
137
- "XDG_STATE_HOME",
138
- "XDG_RUNTIME_DIR",
139
- "HTTPS_PROXY",
140
- "HTTP_PROXY",
141
- "ALL_PROXY",
142
- "NO_PROXY",
143
- "https_proxy",
144
- "http_proxy",
145
- "all_proxy",
146
- "no_proxy",
147
- "SSL_CERT_FILE",
148
- "SSL_CERT_DIR",
149
- "REQUESTS_CA_BUNDLE",
150
- "CURL_CA_BUNDLE",
151
- "NODE_EXTRA_CA_CERTS",
152
- "HOSTNAME",
153
- "CONTAINER_ID",
154
- "AGENT_WORKSPACE_ROOT",
155
- "WORKSPACE_PATH",
156
- "STORAGE_PATH",
157
- "WORKSPACE_FILE_API_ROOT_ONLY",
158
- "WORKSPACE_ALLOWED_ABSOLUTE_PATHS",
159
- "TANGLE_PLAN_CALLBACK_ALLOWED_ORIGINS"
160
- ]);
161
- const FORBIDDEN_ENV_VAR_PREFIXES = [
162
- "SIDECAR_",
163
- "ORCHESTRATOR_",
164
- "AGENT_INTERNAL_",
165
- "SANDBOX_DEV_",
166
- "AGENT_SUBPROCESS_",
167
- "TEE_ATTESTATION_"
168
- ];
169
- const RUNTIME_CALLER_ALLOWED_ENV_NAMES = new Set(["SIDECAR_CAPABILITIES", "SIDECAR_PLATFORM_CONTROL_RUNTIME"]);
170
- new Set(Object.values(HARNESS_WARM_TRANSPORT_ENV).flatMap(({ warmServer, prewarm }) => [warmServer, prewarm]));
171
- function isForbiddenEnvVarName(name) {
172
- if (RUNTIME_CALLER_ALLOWED_ENV_NAMES.has(name)) return false;
173
- if (FORBIDDEN_ENV_VAR_NAMES.has(name)) return true;
174
- for (const prefix of FORBIDDEN_ENV_VAR_PREFIXES) if (name.startsWith(prefix)) return true;
175
- return false;
176
- }
177
- /**
178
- * POSIX names for caller-owned container env. Runtime process.env merges must additionally enforce
179
- * isForbiddenEnvVarName, including project provisioning and Sidecar config.
180
- */
181
- const safeEnvRecordSchema = ownPropertyRecordSchema(z.string(), { maxEntries: Number.MAX_SAFE_INTEGER }).refine((value) => Object.keys(value).every(isSafeEnvVarName), { message: "invalid env var name" });
182
- /** Names only: the caller must keep a separate source and pass values to resume({ env }). */
183
- const sandboxEnvRecoverySchema = z.object({ callerResupplies: z.array(z.string().max(256).refine(isSafeEnvVarName, { message: "invalid env var name" })).max(128).refine((keys) => new Set(keys).size === keys.length, { message: "callerResupplies must contain unique keys" }) }).strict();
184
- z.object({
185
- envRecovery: sandboxEnvRecoverySchema,
186
- dryRun: z.boolean().optional()
187
- }).strict();
188
- z.object({
189
- envRecovery: sandboxEnvRecoverySchema,
190
- eligibleCallerResupplyKeys: z.array(z.string()),
191
- requiredOnColdResumeKeys: z.array(z.string()),
192
- automaticCredentialRecovery: z.literal(false),
193
- dryRun: z.boolean()
194
- }).strict();
195
- safeEnvRecordSchema.refine((value) => Object.keys(value).every((key) => !isForbiddenEnvVarName(key) && !key.startsWith("SIDECAR_")), { message: "runtime-owned env var name cannot be set by callers" });
196
- //#endregion
197
- export { baseProxyToken as i, isSafeEnvVarName as n, declaredSecretSlotTokens as r, isForbiddenEnvVarName as t };
198
-
199
- //# sourceMappingURL=harness-D1fTxnDD.mjs.map