@envseal/protocol 0.1.5 → 0.1.6
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/errors.d.ts +1 -1
- package/dist/errors.js +6 -0
- package/dist/schemas.d.ts +70 -0
- package/dist/schemas.js +39 -0
- package/package.json +1 -1
package/dist/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const SEP_ERROR_CODES: readonly ["SEP_UNKNOWN_KEY", "SEP_NOT_DECLARED", "SEP_NO_INTERACTIVE_SURFACE", "SEP_TICKET_EXPIRED", "SEP_TICKET_UNKNOWN", "SEP_USER_CANCELLED", "SEP_FORMAT_INVALID", "SEP_SINK_UNAVAILABLE", "SEP_SINK_WRITE_FAILED", "SEP_PROBE_NOT_APPROVED", "SEP_VALUE_IN_REQUEST", "SEP_GITIGNORE_UNSAFE", "SEP_CONFIRMATION_DENIED", "SEP_RATE_LIMITED", "SEP_TARGET_CHANGED", "SEP_PATTERN_UNSAFE", "SEP_KEYS_MISSING"];
|
|
1
|
+
export declare const SEP_ERROR_CODES: readonly ["SEP_UNKNOWN_KEY", "SEP_NOT_DECLARED", "SEP_NO_INTERACTIVE_SURFACE", "SEP_TICKET_EXPIRED", "SEP_TICKET_UNKNOWN", "SEP_USER_CANCELLED", "SEP_FORMAT_INVALID", "SEP_SINK_UNAVAILABLE", "SEP_SINK_WRITE_FAILED", "SEP_PROBE_NOT_APPROVED", "SEP_VALUE_IN_REQUEST", "SEP_GITIGNORE_UNSAFE", "SEP_CONFIRMATION_DENIED", "SEP_RATE_LIMITED", "SEP_TARGET_CHANGED", "SEP_EGRESS_DENIED", "SEP_PATTERN_UNSAFE", "SEP_KEYS_MISSING"];
|
|
2
2
|
export type SepErrorCode = (typeof SEP_ERROR_CODES)[number];
|
|
3
3
|
export interface SepErrorDefaults {
|
|
4
4
|
retriable: boolean;
|
package/dist/errors.js
CHANGED
|
@@ -14,6 +14,7 @@ export const SEP_ERROR_CODES = [
|
|
|
14
14
|
'SEP_CONFIRMATION_DENIED',
|
|
15
15
|
'SEP_RATE_LIMITED',
|
|
16
16
|
'SEP_TARGET_CHANGED',
|
|
17
|
+
'SEP_EGRESS_DENIED',
|
|
17
18
|
'SEP_PATTERN_UNSAFE',
|
|
18
19
|
'SEP_KEYS_MISSING',
|
|
19
20
|
];
|
|
@@ -79,6 +80,11 @@ export const SEP_ERROR_DEFAULTS = {
|
|
|
79
80
|
userMessage: 'The program to run changed on disk after you approved it. Nothing was executed. ' +
|
|
80
81
|
'Re-run the command to review the current content and approve it again.',
|
|
81
82
|
},
|
|
83
|
+
SEP_EGRESS_DENIED: {
|
|
84
|
+
retriable: false,
|
|
85
|
+
userMessage: 'This project uses an egress allowlist, and the command targets a host that is not on it. ' +
|
|
86
|
+
'Nothing was executed or sent. To allow the host, add it to policy.egress.allow in env.schema.jsonc.',
|
|
87
|
+
},
|
|
82
88
|
SEP_PATTERN_UNSAFE: {
|
|
83
89
|
retriable: false,
|
|
84
90
|
userMessage: 'The declared format.pattern is unsafe or too complex. Use a shorter, bounded pattern (for example ^sk-[A-Za-z0-9]{20,80}$).',
|
package/dist/schemas.d.ts
CHANGED
|
@@ -188,6 +188,36 @@ export declare const ManifestEntry: z.ZodEffects<z.ZodObject<{
|
|
|
188
188
|
} | undefined;
|
|
189
189
|
}>;
|
|
190
190
|
export type ManifestEntry = z.infer<typeof ManifestEntry>;
|
|
191
|
+
/**
|
|
192
|
+
* policy.egress — declarative egress restriction for env_use (SEP/1 minor
|
|
193
|
+
* addition). mode 'warn' (default when policy is absent) preserves historical
|
|
194
|
+
* behavior: network-touching commands draw an extra warning in the consent
|
|
195
|
+
* dialog. mode 'allowlist' hard-refuses any network command whose target host
|
|
196
|
+
* is not listed, BEFORE any dialog opens. The override path is deliberately
|
|
197
|
+
* editing this file rather than clicking a dialog: a prompt-injected agent
|
|
198
|
+
* cannot talk the user past a control that does not exist mid-flow.
|
|
199
|
+
*
|
|
200
|
+
* Allow entries are hostnames or single-label wildcards ('*.openai.com').
|
|
201
|
+
* URLs, ports, and schemes are rejected here so the enforcement layer can
|
|
202
|
+
* trust entries blindly.
|
|
203
|
+
*/
|
|
204
|
+
export declare const EgressPolicy: z.ZodEffects<z.ZodObject<{
|
|
205
|
+
mode: z.ZodEnum<["warn", "allowlist"]>;
|
|
206
|
+
allow: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
207
|
+
}, "strict", z.ZodTypeAny, {
|
|
208
|
+
mode: "warn" | "allowlist";
|
|
209
|
+
allow: string[];
|
|
210
|
+
}, {
|
|
211
|
+
mode: "warn" | "allowlist";
|
|
212
|
+
allow?: string[] | undefined;
|
|
213
|
+
}>, {
|
|
214
|
+
mode: "warn" | "allowlist";
|
|
215
|
+
allow: string[];
|
|
216
|
+
}, {
|
|
217
|
+
mode: "warn" | "allowlist";
|
|
218
|
+
allow?: string[] | undefined;
|
|
219
|
+
}>;
|
|
220
|
+
export type EgressPolicy = z.infer<typeof EgressPolicy>;
|
|
191
221
|
export declare const Manifest: z.ZodObject<{
|
|
192
222
|
$schema: z.ZodOptional<z.ZodString>;
|
|
193
223
|
version: z.ZodLiteral<1>;
|
|
@@ -375,6 +405,34 @@ export declare const Manifest: z.ZodObject<{
|
|
|
375
405
|
maxAgeDays: number;
|
|
376
406
|
} | undefined;
|
|
377
407
|
}>, "many">>;
|
|
408
|
+
policy: z.ZodOptional<z.ZodObject<{
|
|
409
|
+
egress: z.ZodEffects<z.ZodObject<{
|
|
410
|
+
mode: z.ZodEnum<["warn", "allowlist"]>;
|
|
411
|
+
allow: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
412
|
+
}, "strict", z.ZodTypeAny, {
|
|
413
|
+
mode: "warn" | "allowlist";
|
|
414
|
+
allow: string[];
|
|
415
|
+
}, {
|
|
416
|
+
mode: "warn" | "allowlist";
|
|
417
|
+
allow?: string[] | undefined;
|
|
418
|
+
}>, {
|
|
419
|
+
mode: "warn" | "allowlist";
|
|
420
|
+
allow: string[];
|
|
421
|
+
}, {
|
|
422
|
+
mode: "warn" | "allowlist";
|
|
423
|
+
allow?: string[] | undefined;
|
|
424
|
+
}>;
|
|
425
|
+
}, "strict", z.ZodTypeAny, {
|
|
426
|
+
egress: {
|
|
427
|
+
mode: "warn" | "allowlist";
|
|
428
|
+
allow: string[];
|
|
429
|
+
};
|
|
430
|
+
}, {
|
|
431
|
+
egress: {
|
|
432
|
+
mode: "warn" | "allowlist";
|
|
433
|
+
allow?: string[] | undefined;
|
|
434
|
+
};
|
|
435
|
+
}>>;
|
|
378
436
|
}, "strict", z.ZodTypeAny, {
|
|
379
437
|
entries: {
|
|
380
438
|
key: string;
|
|
@@ -408,6 +466,12 @@ export declare const Manifest: z.ZodObject<{
|
|
|
408
466
|
}[];
|
|
409
467
|
version: 1;
|
|
410
468
|
$schema?: string | undefined;
|
|
469
|
+
policy?: {
|
|
470
|
+
egress: {
|
|
471
|
+
mode: "warn" | "allowlist";
|
|
472
|
+
allow: string[];
|
|
473
|
+
};
|
|
474
|
+
} | undefined;
|
|
411
475
|
}, {
|
|
412
476
|
version: 1;
|
|
413
477
|
entries?: {
|
|
@@ -441,6 +505,12 @@ export declare const Manifest: z.ZodObject<{
|
|
|
441
505
|
} | undefined;
|
|
442
506
|
}[] | undefined;
|
|
443
507
|
$schema?: string | undefined;
|
|
508
|
+
policy?: {
|
|
509
|
+
egress: {
|
|
510
|
+
mode: "warn" | "allowlist";
|
|
511
|
+
allow?: string[] | undefined;
|
|
512
|
+
};
|
|
513
|
+
} | undefined;
|
|
444
514
|
}>;
|
|
445
515
|
export type Manifest = z.infer<typeof Manifest>;
|
|
446
516
|
export declare const KeyStatus: z.ZodObject<{
|
package/dist/schemas.js
CHANGED
|
@@ -253,11 +253,50 @@ export const ManifestEntry = z
|
|
|
253
253
|
});
|
|
254
254
|
}
|
|
255
255
|
});
|
|
256
|
+
/**
|
|
257
|
+
* policy.egress — declarative egress restriction for env_use (SEP/1 minor
|
|
258
|
+
* addition). mode 'warn' (default when policy is absent) preserves historical
|
|
259
|
+
* behavior: network-touching commands draw an extra warning in the consent
|
|
260
|
+
* dialog. mode 'allowlist' hard-refuses any network command whose target host
|
|
261
|
+
* is not listed, BEFORE any dialog opens. The override path is deliberately
|
|
262
|
+
* editing this file rather than clicking a dialog: a prompt-injected agent
|
|
263
|
+
* cannot talk the user past a control that does not exist mid-flow.
|
|
264
|
+
*
|
|
265
|
+
* Allow entries are hostnames or single-label wildcards ('*.openai.com').
|
|
266
|
+
* URLs, ports, and schemes are rejected here so the enforcement layer can
|
|
267
|
+
* trust entries blindly.
|
|
268
|
+
*/
|
|
269
|
+
export const EgressPolicy = z
|
|
270
|
+
.object({
|
|
271
|
+
mode: z.enum(['warn', 'allowlist']),
|
|
272
|
+
allow: z.array(z.string()).default([]),
|
|
273
|
+
})
|
|
274
|
+
.strict()
|
|
275
|
+
.superRefine((policy, ctx) => {
|
|
276
|
+
if (policy.mode === 'allowlist' && policy.allow.length === 0) {
|
|
277
|
+
ctx.addIssue({
|
|
278
|
+
code: z.ZodIssueCode.custom,
|
|
279
|
+
path: ['allow'],
|
|
280
|
+
message: 'mode "allowlist" requires at least one entry in allow',
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
const HOST_PATTERN = /^(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
|
|
284
|
+
for (const [i, entry] of policy.allow.entries()) {
|
|
285
|
+
if (!HOST_PATTERN.test(entry)) {
|
|
286
|
+
ctx.addIssue({
|
|
287
|
+
code: z.ZodIssueCode.custom,
|
|
288
|
+
path: ['allow', i],
|
|
289
|
+
message: 'allow entries must be hostnames or "*.suffix" wildcards — no URLs, ports, schemes, or paths',
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
});
|
|
256
294
|
export const Manifest = z
|
|
257
295
|
.object({
|
|
258
296
|
$schema: z.string().optional(),
|
|
259
297
|
version: z.literal(1),
|
|
260
298
|
entries: z.array(ManifestEntry).default([]),
|
|
299
|
+
policy: z.object({ egress: EgressPolicy }).strict().optional(),
|
|
261
300
|
})
|
|
262
301
|
.strict();
|
|
263
302
|
export const KeyStatus = z
|