mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Add browser and computer use configuration (#40018)
## What changed - Add typed `browser_use` settings for history access and per-origin access, download, upload, and full CDP policies. - Add typed `computer_use` settings for default app access, macOS bundle IDs, Windows AUMIDs, and Windows executable identities. - Expose the merged settings through app-server config reads and generated Rust, TypeScript, and JSON schemas. ## Testing - Cover TOML serialization round trips, layered config reads with origin metadata, and app-server batch writes. GitOrigin-RevId: 78065f6fec990602071fc81ff639ff97f7ad8cd5
This commit is contained in:
+192
@@ -7569,6 +7569,36 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"BrowserUseConfig": {
|
||||
"properties": {
|
||||
"allow_history_access": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"default_origin_policy": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/BrowserUseOriginPolicyConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"origins": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/v2/BrowserUseOriginPolicyConfig"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseOriginPolicy": {
|
||||
"properties": {
|
||||
"access": {
|
||||
@@ -7640,6 +7670,51 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseOriginPolicyConfig": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"downloads": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"full_cdp_access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"uploads": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseRequirements": {
|
||||
"properties": {
|
||||
"allowGlobalPersistentApproval": {
|
||||
@@ -8481,6 +8556,55 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseConfig": {
|
||||
"properties": {
|
||||
"default_app_access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"macos": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ComputerUseMacosConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"windows": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ComputerUseWindowsConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseMacosConfig": {
|
||||
"properties": {
|
||||
"bundle_ids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseMacosRequirements": {
|
||||
"properties": {
|
||||
"bundleIds": {
|
||||
@@ -8542,6 +8666,54 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsConfig": {
|
||||
"properties": {
|
||||
"aumids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"exes": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/ComputerUseWindowsExeConfig"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsExeConfig": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/v2/AllowDenyRequirement"
|
||||
},
|
||||
"binary_name": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"product_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"publisher_name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"product_name",
|
||||
"publisher_name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsExeRequirement": {
|
||||
"properties": {
|
||||
"access": {
|
||||
@@ -8624,12 +8796,32 @@
|
||||
],
|
||||
"description": "[UNSTABLE] Optional default for where approval requests are routed for review."
|
||||
},
|
||||
"browser_use": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/BrowserUseConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"compact_prompt": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computer_use": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ComputerUseConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"desktop": {
|
||||
"additionalProperties": true,
|
||||
"type": [
|
||||
|
||||
+192
@@ -1294,6 +1294,36 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"BrowserUseConfig": {
|
||||
"properties": {
|
||||
"allow_history_access": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"default_origin_policy": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BrowserUseOriginPolicyConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"origins": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/BrowserUseOriginPolicyConfig"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseOriginPolicy": {
|
||||
"properties": {
|
||||
"access": {
|
||||
@@ -1365,6 +1395,51 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseOriginPolicyConfig": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"downloads": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"full_cdp_access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"uploads": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseRequirements": {
|
||||
"properties": {
|
||||
"allowGlobalPersistentApproval": {
|
||||
@@ -4519,6 +4594,55 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseConfig": {
|
||||
"properties": {
|
||||
"default_app_access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"macos": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ComputerUseMacosConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"windows": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ComputerUseWindowsConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseMacosConfig": {
|
||||
"properties": {
|
||||
"bundle_ids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseMacosRequirements": {
|
||||
"properties": {
|
||||
"bundleIds": {
|
||||
@@ -4580,6 +4704,54 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsConfig": {
|
||||
"properties": {
|
||||
"aumids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"exes": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ComputerUseWindowsExeConfig"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsExeConfig": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
"binary_name": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"product_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"publisher_name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"product_name",
|
||||
"publisher_name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsExeRequirement": {
|
||||
"properties": {
|
||||
"access": {
|
||||
@@ -4662,12 +4834,32 @@
|
||||
],
|
||||
"description": "[UNSTABLE] Optional default for where approval requests are routed for review."
|
||||
},
|
||||
"browser_use": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BrowserUseConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"compact_prompt": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computer_use": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ComputerUseConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"desktop": {
|
||||
"additionalProperties": true,
|
||||
"type": [
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
|
||||
"type": "string"
|
||||
},
|
||||
"AllowDenyRequirement": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AnalyticsConfig": {
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
@@ -237,6 +244,178 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"BrowserUseConfig": {
|
||||
"properties": {
|
||||
"allow_history_access": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"default_origin_policy": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BrowserUseOriginPolicyConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"origins": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/BrowserUseOriginPolicyConfig"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseOriginPolicyConfig": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"downloads": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"full_cdp_access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"uploads": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseConfig": {
|
||||
"properties": {
|
||||
"default_app_access": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"macos": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ComputerUseMacosConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"windows": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ComputerUseWindowsConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseMacosConfig": {
|
||||
"properties": {
|
||||
"bundle_ids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsConfig": {
|
||||
"properties": {
|
||||
"aumids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"exes": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ComputerUseWindowsExeConfig"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsExeConfig": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/AllowDenyRequirement"
|
||||
},
|
||||
"binary_name": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"product_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"publisher_name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"product_name",
|
||||
"publisher_name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Config": {
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
@@ -271,12 +450,32 @@
|
||||
],
|
||||
"description": "[UNSTABLE] Optional default for where approval requests are routed for review."
|
||||
},
|
||||
"browser_use": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BrowserUseConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"compact_prompt": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computer_use": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ComputerUseConfig"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"desktop": {
|
||||
"additionalProperties": true,
|
||||
"type": [
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { BrowserUseOriginPolicyConfig } from "./BrowserUseOriginPolicyConfig";
|
||||
|
||||
export type BrowserUseConfig = { allow_history_access: boolean | null, default_origin_policy: BrowserUseOriginPolicyConfig | null, origins: { [key in string]?: BrowserUseOriginPolicyConfig } | null, };
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AllowDenyRequirement } from "./AllowDenyRequirement";
|
||||
|
||||
export type BrowserUseOriginPolicyConfig = { access: AllowDenyRequirement | null, downloads: AllowDenyRequirement | null, uploads: AllowDenyRequirement | null, full_cdp_access: AllowDenyRequirement | null, };
|
||||
@@ -0,0 +1,8 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AllowDenyRequirement } from "./AllowDenyRequirement";
|
||||
import type { ComputerUseMacosConfig } from "./ComputerUseMacosConfig";
|
||||
import type { ComputerUseWindowsConfig } from "./ComputerUseWindowsConfig";
|
||||
|
||||
export type ComputerUseConfig = { default_app_access: AllowDenyRequirement | null, macos: ComputerUseMacosConfig | null, windows: ComputerUseWindowsConfig | null, };
|
||||
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AllowDenyRequirement } from "./AllowDenyRequirement";
|
||||
|
||||
export type ComputerUseMacosConfig = { bundle_ids: { [key in string]?: AllowDenyRequirement } | null, };
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AllowDenyRequirement } from "./AllowDenyRequirement";
|
||||
import type { ComputerUseWindowsExeConfig } from "./ComputerUseWindowsExeConfig";
|
||||
|
||||
export type ComputerUseWindowsConfig = { aumids: { [key in string]?: AllowDenyRequirement } | null, exes: Array<ComputerUseWindowsExeConfig> | null, };
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AllowDenyRequirement } from "./AllowDenyRequirement";
|
||||
|
||||
export type ComputerUseWindowsExeConfig = { publisher_name: string, product_name: string, binary_name: string | null, access: AllowDenyRequirement, };
|
||||
+3
-1
@@ -11,6 +11,8 @@ import type { JsonValue } from "../serde_json/JsonValue";
|
||||
import type { AnalyticsConfig } from "./AnalyticsConfig";
|
||||
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
|
||||
import type { AskForApproval } from "./AskForApproval";
|
||||
import type { BrowserUseConfig } from "./BrowserUseConfig";
|
||||
import type { ComputerUseConfig } from "./ComputerUseConfig";
|
||||
import type { ForcedChatgptWorkspaceIds } from "./ForcedChatgptWorkspaceIds";
|
||||
import type { SandboxMode } from "./SandboxMode";
|
||||
import type { SandboxWorkspaceWrite } from "./SandboxWorkspaceWrite";
|
||||
@@ -20,4 +22,4 @@ export type Config = {model: string | null, review_model: string | null, model_c
|
||||
* [UNSTABLE] Optional default for where approval requests are routed for
|
||||
* review.
|
||||
*/
|
||||
approvals_reviewer: ApprovalsReviewer | null, sandbox_mode: SandboxMode | null, sandbox_workspace_write: SandboxWorkspaceWrite | null, forced_chatgpt_workspace_id: ForcedChatgptWorkspaceIds | null, forced_login_method: ForcedLoginMethod | null, web_search: WebSearchMode | null, tools: ToolsV2 | null, instructions: string | null, developer_instructions: string | null, compact_prompt: string | null, model_reasoning_effort: ReasoningEffort | null, model_reasoning_summary: ReasoningSummary | null, model_verbosity: Verbosity | null, service_tier: string | null, analytics: AnalyticsConfig | null, desktop: { [key in string]?: JsonValue } | null} & ({ [key in string]?: number | string | boolean | Array<JsonValue> | { [key in string]?: JsonValue } | null });
|
||||
approvals_reviewer: ApprovalsReviewer | null, sandbox_mode: SandboxMode | null, sandbox_workspace_write: SandboxWorkspaceWrite | null, forced_chatgpt_workspace_id: ForcedChatgptWorkspaceIds | null, forced_login_method: ForcedLoginMethod | null, web_search: WebSearchMode | null, tools: ToolsV2 | null, instructions: string | null, developer_instructions: string | null, compact_prompt: string | null, model_reasoning_effort: ReasoningEffort | null, model_reasoning_summary: ReasoningSummary | null, model_verbosity: Verbosity | null, service_tier: string | null, analytics: AnalyticsConfig | null, browser_use: BrowserUseConfig | null, computer_use: ComputerUseConfig | null, desktop: { [key in string]?: JsonValue } | null} & ({ [key in string]?: number | string | boolean | Array<JsonValue> | { [key in string]?: JsonValue } | null });
|
||||
|
||||
@@ -45,7 +45,9 @@ export type { AttestationGenerateResponse } from "./AttestationGenerateResponse"
|
||||
export type { AutoReviewDecisionSource } from "./AutoReviewDecisionSource";
|
||||
export type { AutoReviewRequirements } from "./AutoReviewRequirements";
|
||||
export type { BrowserUseAccessApprovalLifetime } from "./BrowserUseAccessApprovalLifetime";
|
||||
export type { BrowserUseConfig } from "./BrowserUseConfig";
|
||||
export type { BrowserUseOriginPolicy } from "./BrowserUseOriginPolicy";
|
||||
export type { BrowserUseOriginPolicyConfig } from "./BrowserUseOriginPolicyConfig";
|
||||
export type { BrowserUseRequirements } from "./BrowserUseRequirements";
|
||||
export type { ByteRange } from "./ByteRange";
|
||||
export type { CancelLoginAccountParams } from "./CancelLoginAccountParams";
|
||||
@@ -81,8 +83,12 @@ export type { CommandExecutionRequestApprovalResponse } from "./CommandExecution
|
||||
export type { CommandExecutionSource } from "./CommandExecutionSource";
|
||||
export type { CommandExecutionStatus } from "./CommandExecutionStatus";
|
||||
export type { CommandMigration } from "./CommandMigration";
|
||||
export type { ComputerUseConfig } from "./ComputerUseConfig";
|
||||
export type { ComputerUseMacosConfig } from "./ComputerUseMacosConfig";
|
||||
export type { ComputerUseMacosRequirements } from "./ComputerUseMacosRequirements";
|
||||
export type { ComputerUseRequirements } from "./ComputerUseRequirements";
|
||||
export type { ComputerUseWindowsConfig } from "./ComputerUseWindowsConfig";
|
||||
export type { ComputerUseWindowsExeConfig } from "./ComputerUseWindowsExeConfig";
|
||||
export type { ComputerUseWindowsExeRequirement } from "./ComputerUseWindowsExeRequirement";
|
||||
export type { ComputerUseWindowsRequirements } from "./ComputerUseWindowsRequirements";
|
||||
export type { Config } from "./Config";
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
use super::AllowDenyRequirement;
|
||||
use crate::JsonSchema;
|
||||
use crate::TS;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct BrowserUseConfig {
|
||||
pub allow_history_access: Option<bool>,
|
||||
pub default_origin_policy: Option<BrowserUseOriginPolicyConfig>,
|
||||
pub origins: Option<BTreeMap<String, BrowserUseOriginPolicyConfig>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct BrowserUseOriginPolicyConfig {
|
||||
pub access: Option<AllowDenyRequirement>,
|
||||
pub downloads: Option<AllowDenyRequirement>,
|
||||
pub uploads: Option<AllowDenyRequirement>,
|
||||
pub full_cdp_access: Option<AllowDenyRequirement>,
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
use super::AllowDenyRequirement;
|
||||
use crate::JsonSchema;
|
||||
use crate::TS;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ComputerUseConfig {
|
||||
pub default_app_access: Option<AllowDenyRequirement>,
|
||||
pub macos: Option<ComputerUseMacosConfig>,
|
||||
pub windows: Option<ComputerUseWindowsConfig>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ComputerUseMacosConfig {
|
||||
pub bundle_ids: Option<BTreeMap<String, AllowDenyRequirement>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ComputerUseWindowsConfig {
|
||||
pub aumids: Option<BTreeMap<String, AllowDenyRequirement>>,
|
||||
pub exes: Option<Vec<ComputerUseWindowsExeConfig>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ComputerUseWindowsExeConfig {
|
||||
pub publisher_name: String,
|
||||
pub product_name: String,
|
||||
pub binary_name: Option<String>,
|
||||
pub access: AllowDenyRequirement,
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
use super::ApprovalsReviewer;
|
||||
use super::AskForApproval;
|
||||
use super::BrowserUseConfig;
|
||||
use super::ComputerUseConfig;
|
||||
use super::SandboxMode;
|
||||
use super::WindowsSandboxSetupMode;
|
||||
use super::shared::default_enabled;
|
||||
@@ -282,6 +284,8 @@ pub struct Config {
|
||||
#[experimental("config/read.apps")]
|
||||
#[serde(default)]
|
||||
pub apps: Option<AppsConfig>,
|
||||
pub browser_use: Option<BrowserUseConfig>,
|
||||
pub computer_use: Option<ComputerUseConfig>,
|
||||
pub desktop: Option<HashMap<String, JsonValue>>,
|
||||
#[serde(default, flatten)]
|
||||
pub additional: HashMap<String, JsonValue>,
|
||||
|
||||
@@ -4,8 +4,10 @@ mod account;
|
||||
mod apps;
|
||||
mod attestation;
|
||||
mod bedrock;
|
||||
mod browser_use_config;
|
||||
mod collaboration_mode;
|
||||
mod command_exec;
|
||||
mod computer_use_config;
|
||||
mod config;
|
||||
mod current_time;
|
||||
mod diagnostics;
|
||||
@@ -36,8 +38,10 @@ pub use account::*;
|
||||
pub use apps::*;
|
||||
pub use attestation::*;
|
||||
pub use bedrock::*;
|
||||
pub use browser_use_config::*;
|
||||
pub use collaboration_mode::*;
|
||||
pub use command_exec::*;
|
||||
pub use computer_use_config::*;
|
||||
pub use config::*;
|
||||
pub use current_time::*;
|
||||
pub use diagnostics::*;
|
||||
|
||||
@@ -1996,6 +1996,8 @@ fn config_granular_approval_policy_is_marked_experimental() {
|
||||
service_tier: None,
|
||||
analytics: None,
|
||||
apps: None,
|
||||
browser_use: None,
|
||||
computer_use: None,
|
||||
desktop: None,
|
||||
additional: HashMap::new(),
|
||||
});
|
||||
@@ -2029,6 +2031,8 @@ fn config_approvals_reviewer_is_marked_experimental() {
|
||||
service_tier: None,
|
||||
analytics: None,
|
||||
apps: None,
|
||||
browser_use: None,
|
||||
computer_use: None,
|
||||
desktop: None,
|
||||
additional: HashMap::new(),
|
||||
});
|
||||
|
||||
@@ -10,11 +10,17 @@ use codex_app_server_protocol::AppsConfig;
|
||||
use codex_app_server_protocol::AppsDefaultConfig;
|
||||
use codex_app_server_protocol::AskForApproval;
|
||||
use codex_app_server_protocol::BrowserUseAccessApprovalLifetime;
|
||||
use codex_app_server_protocol::BrowserUseConfig;
|
||||
use codex_app_server_protocol::BrowserUseOriginPolicy;
|
||||
use codex_app_server_protocol::BrowserUseOriginPolicyConfig;
|
||||
use codex_app_server_protocol::BrowserUseRequirements;
|
||||
use codex_app_server_protocol::CliAuthCredentialsStoreMode;
|
||||
use codex_app_server_protocol::ComputerUseConfig;
|
||||
use codex_app_server_protocol::ComputerUseMacosConfig;
|
||||
use codex_app_server_protocol::ComputerUseMacosRequirements;
|
||||
use codex_app_server_protocol::ComputerUseRequirements;
|
||||
use codex_app_server_protocol::ComputerUseWindowsConfig;
|
||||
use codex_app_server_protocol::ComputerUseWindowsExeConfig;
|
||||
use codex_app_server_protocol::ComputerUseWindowsExeRequirement;
|
||||
use codex_app_server_protocol::ComputerUseWindowsRequirements;
|
||||
use codex_app_server_protocol::ConfigBatchWriteParams;
|
||||
@@ -613,6 +619,236 @@ allowed_domains = ["example.com"]
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn config_read_includes_browser_and_computer_use_config() -> Result<()> {
|
||||
let codex_home = TempDir::new()?;
|
||||
write_config(
|
||||
&codex_home,
|
||||
r#"
|
||||
[browser_use]
|
||||
allow_history_access = true
|
||||
|
||||
[browser_use.default_origin_policy]
|
||||
access = "deny"
|
||||
downloads = "allow"
|
||||
|
||||
[browser_use.origins."https://example.com"]
|
||||
downloads = "deny"
|
||||
uploads = "allow"
|
||||
|
||||
[computer_use]
|
||||
default_app_access = "deny"
|
||||
|
||||
[computer_use.macos.bundle_ids]
|
||||
"com.apple.Safari" = "allow"
|
||||
|
||||
[computer_use.windows.aumids]
|
||||
"Microsoft.Paint_8wekyb3d8bbwe!App" = "deny"
|
||||
|
||||
[[computer_use.windows.exes]]
|
||||
publisher_name = "CN=Google LLC"
|
||||
product_name = "Google Chrome"
|
||||
binary_name = "chrome.exe"
|
||||
access = "allow"
|
||||
"#,
|
||||
)?;
|
||||
std::fs::write(
|
||||
codex_home.path().join("requirements.toml"),
|
||||
r#"
|
||||
allow_browser_and_computer_use = false
|
||||
|
||||
[browser_use]
|
||||
allow_history_access = false
|
||||
allow_global_persistent_approval = false
|
||||
|
||||
[browser_use.default_origin_policy]
|
||||
access = "allow"
|
||||
|
||||
[computer_use]
|
||||
default_app_access = "allow"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let workspace = TempDir::new()?;
|
||||
let project_config_dir = workspace.path().join(".codex");
|
||||
std::fs::create_dir_all(&project_config_dir)?;
|
||||
std::fs::write(
|
||||
project_config_dir.join("config.toml"),
|
||||
r#"
|
||||
[browser_use.default_origin_policy]
|
||||
uploads = "deny"
|
||||
full_cdp_access = "allow"
|
||||
|
||||
[browser_use.origins."https://example.com"]
|
||||
access = "allow"
|
||||
full_cdp_access = "deny"
|
||||
|
||||
[computer_use.macos.bundle_ids]
|
||||
"com.apple.TextEdit" = "allow"
|
||||
"com.apple.Safari" = "deny"
|
||||
|
||||
[computer_use.windows.aumids]
|
||||
"Microsoft.WindowsCalculator_8wekyb3d8bbwe!App" = "allow"
|
||||
|
||||
[[computer_use.windows.exes]]
|
||||
publisher_name = "CN=Microsoft Corporation"
|
||||
product_name = "Microsoft Visual Studio Code"
|
||||
access = "deny"
|
||||
"#,
|
||||
)?;
|
||||
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
|
||||
let codex_home_path = codex_home.path().canonicalize()?;
|
||||
let user_file = AbsolutePathBuf::try_from(codex_home_path.join("config.toml"))?;
|
||||
let project_config = AbsolutePathBuf::try_from(project_config_dir)?;
|
||||
|
||||
let mut mcp = TestAppServer::builder()
|
||||
.with_codex_home(codex_home.path())
|
||||
.without_auto_env()
|
||||
.build_initialized_with_timeout(DEFAULT_READ_TIMEOUT)
|
||||
.await?;
|
||||
|
||||
let request_id = mcp
|
||||
.send_config_read_request(ConfigReadParams {
|
||||
include_layers: false,
|
||||
cwd: Some(workspace.path().to_string_lossy().into_owned()),
|
||||
})
|
||||
.await?;
|
||||
let ConfigReadResponse {
|
||||
config, origins, ..
|
||||
} = timeout(DEFAULT_READ_TIMEOUT, mcp.read_response(request_id)).await??;
|
||||
|
||||
assert_eq!(
|
||||
config.browser_use,
|
||||
Some(BrowserUseConfig {
|
||||
allow_history_access: Some(true),
|
||||
default_origin_policy: Some(BrowserUseOriginPolicyConfig {
|
||||
access: Some(AllowDenyRequirement::Deny),
|
||||
downloads: Some(AllowDenyRequirement::Allow),
|
||||
uploads: Some(AllowDenyRequirement::Deny),
|
||||
full_cdp_access: Some(AllowDenyRequirement::Allow),
|
||||
}),
|
||||
origins: Some(BTreeMap::from([(
|
||||
"https://example.com".to_string(),
|
||||
BrowserUseOriginPolicyConfig {
|
||||
access: Some(AllowDenyRequirement::Allow),
|
||||
downloads: Some(AllowDenyRequirement::Deny),
|
||||
uploads: Some(AllowDenyRequirement::Allow),
|
||||
full_cdp_access: Some(AllowDenyRequirement::Deny),
|
||||
},
|
||||
)])),
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
config.computer_use,
|
||||
Some(ComputerUseConfig {
|
||||
default_app_access: Some(AllowDenyRequirement::Deny),
|
||||
macos: Some(ComputerUseMacosConfig {
|
||||
bundle_ids: Some(BTreeMap::from([
|
||||
("com.apple.Safari".to_string(), AllowDenyRequirement::Deny,),
|
||||
(
|
||||
"com.apple.TextEdit".to_string(),
|
||||
AllowDenyRequirement::Allow,
|
||||
),
|
||||
])),
|
||||
}),
|
||||
windows: Some(ComputerUseWindowsConfig {
|
||||
aumids: Some(BTreeMap::from([
|
||||
(
|
||||
"Microsoft.Paint_8wekyb3d8bbwe!App".to_string(),
|
||||
AllowDenyRequirement::Deny,
|
||||
),
|
||||
(
|
||||
"Microsoft.WindowsCalculator_8wekyb3d8bbwe!App".to_string(),
|
||||
AllowDenyRequirement::Allow,
|
||||
),
|
||||
])),
|
||||
exes: Some(vec![ComputerUseWindowsExeConfig {
|
||||
publisher_name: "CN=Microsoft Corporation".to_string(),
|
||||
product_name: "Microsoft Visual Studio Code".to_string(),
|
||||
binary_name: None,
|
||||
access: AllowDenyRequirement::Deny,
|
||||
}]),
|
||||
}),
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
origins
|
||||
.get("browser_use.default_origin_policy.access")
|
||||
.expect("user policy origin")
|
||||
.name,
|
||||
ConfigLayerSource::User {
|
||||
file: user_file.clone(),
|
||||
profile: None,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
origins
|
||||
.get("browser_use.default_origin_policy.full_cdp_access")
|
||||
.expect("project policy origin")
|
||||
.name,
|
||||
ConfigLayerSource::Project {
|
||||
dot_codex_folder: project_config.clone(),
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
origins
|
||||
.get("browser_use.allow_history_access")
|
||||
.expect("user browser use origin")
|
||||
.name,
|
||||
ConfigLayerSource::User {
|
||||
file: user_file,
|
||||
profile: None,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
origins
|
||||
.get("computer_use.windows.exes.0.access")
|
||||
.expect("project computer use origin")
|
||||
.name,
|
||||
ConfigLayerSource::Project {
|
||||
dot_codex_folder: project_config,
|
||||
}
|
||||
);
|
||||
|
||||
let request_id = mcp.send_config_requirements_read_request().await?;
|
||||
let response: ConfigRequirementsReadResponse =
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.read_response(request_id)).await??;
|
||||
let requirements = response
|
||||
.requirements
|
||||
.expect("managed requirements should be returned");
|
||||
assert_eq!(requirements.allow_browser_and_computer_use, Some(false));
|
||||
assert_eq!(
|
||||
requirements.browser_use,
|
||||
Some(BrowserUseRequirements {
|
||||
allow_history_access: Some(false),
|
||||
disable_auto_review: None,
|
||||
allow_global_persistent_approval: Some(false),
|
||||
default_origin_policy: Some(BrowserUseOriginPolicy {
|
||||
access: Some(AllowDenyRequirement::Allow),
|
||||
downloads: None,
|
||||
uploads: None,
|
||||
full_cdp_access: None,
|
||||
auto_review: None,
|
||||
persistent_approval: None,
|
||||
access_approval_lifetime: None,
|
||||
}),
|
||||
origins: None,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
requirements.computer_use,
|
||||
Some(ComputerUseRequirements {
|
||||
allow_locked_computer_use: None,
|
||||
allow_persistent_approval: None,
|
||||
default_app_access: Some(AllowDenyRequirement::Allow),
|
||||
macos: None,
|
||||
windows: None,
|
||||
})
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn config_read_accepts_legacy_forced_chatgpt_workspace_id() -> Result<()> {
|
||||
const WORKSPACE_ID: &str = "123e4567-e89b-42d3-a456-426614174000";
|
||||
@@ -1422,6 +1658,238 @@ async fn config_batch_write_applies_multiple_edits() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn config_batch_write_round_trips_browser_and_computer_use_config() -> Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
let codex_home = tmp_dir.path().canonicalize()?;
|
||||
write_config(
|
||||
&tmp_dir,
|
||||
r#"
|
||||
model = "gpt-existing"
|
||||
|
||||
[browser_use.origins."https://stale.example"]
|
||||
access = "deny"
|
||||
|
||||
[computer_use.macos.bundle_ids]
|
||||
"com.example.Stale" = "deny"
|
||||
|
||||
[computer_use.windows.aumids]
|
||||
"Stale.App_123!App" = "allow"
|
||||
|
||||
[[computer_use.windows.exes]]
|
||||
publisher_name = "CN=Stale"
|
||||
product_name = "Stale App"
|
||||
binary_name = "stale.exe"
|
||||
access = "deny"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let mut mcp = TestAppServer::builder()
|
||||
.with_codex_home(&codex_home)
|
||||
.without_auto_env()
|
||||
.build_initialized_with_timeout(DEFAULT_READ_TIMEOUT)
|
||||
.await?;
|
||||
|
||||
let batch_id = mcp
|
||||
.send_config_batch_write_request(ConfigBatchWriteParams {
|
||||
file_path: None,
|
||||
edits: vec![
|
||||
ConfigEdit {
|
||||
key_path: "browser_use.allow_history_access".to_string(),
|
||||
value: json!(true),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "browser_use.default_origin_policy".to_string(),
|
||||
value: json!({
|
||||
"access": "allow",
|
||||
"downloads": "deny",
|
||||
"uploads": "allow",
|
||||
"full_cdp_access": "deny",
|
||||
}),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "browser_use.origins.\"https://example.com\"".to_string(),
|
||||
value: json!({
|
||||
"access": "deny",
|
||||
"downloads": "allow",
|
||||
"uploads": "deny",
|
||||
"full_cdp_access": "allow",
|
||||
}),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "browser_use.origins.\"https://stale.example\"".to_string(),
|
||||
value: json!(null),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "computer_use.default_app_access".to_string(),
|
||||
value: json!("deny"),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "computer_use.macos.bundle_ids.\"com.apple.Safari\"".to_string(),
|
||||
value: json!("allow"),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "computer_use.macos.bundle_ids.\"com.example.Stale\"".to_string(),
|
||||
value: json!(null),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "computer_use.windows.aumids.\"Microsoft.Paint_8wekyb3d8bbwe!App\""
|
||||
.to_string(),
|
||||
value: json!("deny"),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "computer_use.windows.aumids.\"Stale.App_123!App\"".to_string(),
|
||||
value: json!(null),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
ConfigEdit {
|
||||
key_path: "computer_use.windows.exes".to_string(),
|
||||
value: json!([
|
||||
{
|
||||
"publisher_name": "CN=Google LLC",
|
||||
"product_name": "Google Chrome",
|
||||
"binary_name": "chrome.exe",
|
||||
"access": "allow",
|
||||
},
|
||||
{
|
||||
"publisher_name": "CN=Microsoft Corporation",
|
||||
"product_name": "Microsoft Visual Studio Code",
|
||||
"access": "deny",
|
||||
},
|
||||
]),
|
||||
merge_strategy: MergeStrategy::Replace,
|
||||
},
|
||||
],
|
||||
expected_version: None,
|
||||
reload_user_config: false,
|
||||
})
|
||||
.await?;
|
||||
let batch_write: ConfigWriteResponse =
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.read_response(batch_id)).await??;
|
||||
assert_eq!(batch_write.status, WriteStatus::Ok);
|
||||
assert_eq!(
|
||||
batch_write.file_path,
|
||||
AbsolutePathBuf::resolve_path_against_base("config.toml", &codex_home)
|
||||
);
|
||||
assert_eq!(batch_write.overridden_metadata, None);
|
||||
|
||||
let persisted: toml::Value =
|
||||
toml::from_str(&std::fs::read_to_string(codex_home.join("config.toml"))?)?;
|
||||
let expected_persisted: toml::Value = toml::from_str(
|
||||
r#"
|
||||
model = "gpt-existing"
|
||||
|
||||
[browser_use]
|
||||
allow_history_access = true
|
||||
|
||||
[browser_use.default_origin_policy]
|
||||
access = "allow"
|
||||
downloads = "deny"
|
||||
uploads = "allow"
|
||||
full_cdp_access = "deny"
|
||||
|
||||
[browser_use.origins."https://example.com"]
|
||||
access = "deny"
|
||||
downloads = "allow"
|
||||
uploads = "deny"
|
||||
full_cdp_access = "allow"
|
||||
|
||||
[computer_use]
|
||||
default_app_access = "deny"
|
||||
|
||||
[computer_use.macos.bundle_ids]
|
||||
"com.apple.Safari" = "allow"
|
||||
|
||||
[computer_use.windows.aumids]
|
||||
"Microsoft.Paint_8wekyb3d8bbwe!App" = "deny"
|
||||
|
||||
[[computer_use.windows.exes]]
|
||||
publisher_name = "CN=Google LLC"
|
||||
product_name = "Google Chrome"
|
||||
binary_name = "chrome.exe"
|
||||
access = "allow"
|
||||
|
||||
[[computer_use.windows.exes]]
|
||||
publisher_name = "CN=Microsoft Corporation"
|
||||
product_name = "Microsoft Visual Studio Code"
|
||||
access = "deny"
|
||||
"#,
|
||||
)?;
|
||||
assert_eq!(persisted, expected_persisted);
|
||||
|
||||
let read_id = mcp
|
||||
.send_config_read_request(ConfigReadParams {
|
||||
include_layers: false,
|
||||
cwd: None,
|
||||
})
|
||||
.await?;
|
||||
let read: ConfigReadResponse =
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.read_response(read_id)).await??;
|
||||
assert_eq!(
|
||||
read.config.browser_use,
|
||||
Some(BrowserUseConfig {
|
||||
allow_history_access: Some(true),
|
||||
default_origin_policy: Some(BrowserUseOriginPolicyConfig {
|
||||
access: Some(AllowDenyRequirement::Allow),
|
||||
downloads: Some(AllowDenyRequirement::Deny),
|
||||
uploads: Some(AllowDenyRequirement::Allow),
|
||||
full_cdp_access: Some(AllowDenyRequirement::Deny),
|
||||
}),
|
||||
origins: Some(BTreeMap::from([(
|
||||
"https://example.com".to_string(),
|
||||
BrowserUseOriginPolicyConfig {
|
||||
access: Some(AllowDenyRequirement::Deny),
|
||||
downloads: Some(AllowDenyRequirement::Allow),
|
||||
uploads: Some(AllowDenyRequirement::Deny),
|
||||
full_cdp_access: Some(AllowDenyRequirement::Allow),
|
||||
},
|
||||
)])),
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
read.config.computer_use,
|
||||
Some(ComputerUseConfig {
|
||||
default_app_access: Some(AllowDenyRequirement::Deny),
|
||||
macos: Some(ComputerUseMacosConfig {
|
||||
bundle_ids: Some(BTreeMap::from([(
|
||||
"com.apple.Safari".to_string(),
|
||||
AllowDenyRequirement::Allow,
|
||||
)])),
|
||||
}),
|
||||
windows: Some(ComputerUseWindowsConfig {
|
||||
aumids: Some(BTreeMap::from([(
|
||||
"Microsoft.Paint_8wekyb3d8bbwe!App".to_string(),
|
||||
AllowDenyRequirement::Deny,
|
||||
)])),
|
||||
exes: Some(vec![
|
||||
ComputerUseWindowsExeConfig {
|
||||
publisher_name: "CN=Google LLC".to_string(),
|
||||
product_name: "Google Chrome".to_string(),
|
||||
binary_name: Some("chrome.exe".to_string()),
|
||||
access: AllowDenyRequirement::Allow,
|
||||
},
|
||||
ComputerUseWindowsExeConfig {
|
||||
publisher_name: "CN=Microsoft Corporation".to_string(),
|
||||
product_name: "Microsoft Visual Studio Code".to_string(),
|
||||
binary_name: None,
|
||||
access: AllowDenyRequirement::Deny,
|
||||
},
|
||||
]),
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn config_batch_write_rejects_legacy_profile_tables() -> Result<()> {
|
||||
let tmp_dir = TempDir::new()?;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum AllowDenyRequirementToml {
|
||||
Allow,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
use crate::AllowDenyRequirementToml;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct BrowserUseConfigToml {
|
||||
pub allow_history_access: Option<bool>,
|
||||
pub default_origin_policy: Option<BrowserUseOriginPolicyConfigToml>,
|
||||
pub origins: Option<BTreeMap<String, BrowserUseOriginPolicyConfigToml>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct BrowserUseOriginPolicyConfigToml {
|
||||
pub access: Option<AllowDenyRequirementToml>,
|
||||
pub downloads: Option<AllowDenyRequirementToml>,
|
||||
pub uploads: Option<AllowDenyRequirementToml>,
|
||||
pub full_cdp_access: Option<AllowDenyRequirementToml>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "browser_use_tests.rs"]
|
||||
mod tests;
|
||||
@@ -0,0 +1,52 @@
|
||||
use super::*;
|
||||
use crate::AllowDenyRequirementToml;
|
||||
use crate::config_toml::ConfigToml;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn browser_use_origin_policies_round_trip() {
|
||||
let config: ConfigToml = toml::from_str(
|
||||
r#"
|
||||
[browser_use]
|
||||
allow_history_access = true
|
||||
|
||||
[browser_use.default_origin_policy]
|
||||
access = "deny"
|
||||
downloads = "allow"
|
||||
uploads = "deny"
|
||||
full_cdp_access = "allow"
|
||||
|
||||
[browser_use.origins."https://example.com"]
|
||||
access = "allow"
|
||||
downloads = "deny"
|
||||
uploads = "allow"
|
||||
full_cdp_access = "deny"
|
||||
"#,
|
||||
)
|
||||
.expect("browser use config should deserialize");
|
||||
|
||||
let expected = BrowserUseConfigToml {
|
||||
allow_history_access: Some(true),
|
||||
default_origin_policy: Some(BrowserUseOriginPolicyConfigToml {
|
||||
access: Some(AllowDenyRequirementToml::Deny),
|
||||
downloads: Some(AllowDenyRequirementToml::Allow),
|
||||
uploads: Some(AllowDenyRequirementToml::Deny),
|
||||
full_cdp_access: Some(AllowDenyRequirementToml::Allow),
|
||||
}),
|
||||
origins: Some(BTreeMap::from([(
|
||||
"https://example.com".to_string(),
|
||||
BrowserUseOriginPolicyConfigToml {
|
||||
access: Some(AllowDenyRequirementToml::Allow),
|
||||
downloads: Some(AllowDenyRequirementToml::Deny),
|
||||
uploads: Some(AllowDenyRequirementToml::Allow),
|
||||
full_cdp_access: Some(AllowDenyRequirementToml::Deny),
|
||||
},
|
||||
)])),
|
||||
};
|
||||
assert_eq!(config.browser_use, Some(expected.clone()));
|
||||
|
||||
let serialized = toml::to_string(&config).expect("browser use config should serialize");
|
||||
let reparsed: ConfigToml =
|
||||
toml::from_str(&serialized).expect("serialized browser use config should deserialize");
|
||||
assert_eq!(reparsed.browser_use, Some(expected));
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
use crate::AllowDenyRequirementToml;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct ComputerUseConfigToml {
|
||||
pub default_app_access: Option<AllowDenyRequirementToml>,
|
||||
pub macos: Option<ComputerUseMacosConfigToml>,
|
||||
pub windows: Option<ComputerUseWindowsConfigToml>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct ComputerUseMacosConfigToml {
|
||||
pub bundle_ids: Option<BTreeMap<String, AllowDenyRequirementToml>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct ComputerUseWindowsConfigToml {
|
||||
pub aumids: Option<BTreeMap<String, AllowDenyRequirementToml>>,
|
||||
pub exes: Option<Vec<ComputerUseWindowsExeConfigToml>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct ComputerUseWindowsExeConfigToml {
|
||||
pub publisher_name: String,
|
||||
pub product_name: String,
|
||||
pub binary_name: Option<String>,
|
||||
pub access: AllowDenyRequirementToml,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "computer_use_tests.rs"]
|
||||
mod tests;
|
||||
@@ -0,0 +1,54 @@
|
||||
use super::*;
|
||||
use crate::config_toml::ConfigToml;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn computer_use_config_round_trips() {
|
||||
let config: ConfigToml = toml::from_str(
|
||||
r#"
|
||||
[computer_use]
|
||||
default_app_access = "deny"
|
||||
|
||||
[computer_use.macos.bundle_ids]
|
||||
"com.apple.Safari" = "allow"
|
||||
|
||||
[computer_use.windows.aumids]
|
||||
"Microsoft.Paint_8wekyb3d8bbwe!App" = "deny"
|
||||
|
||||
[[computer_use.windows.exes]]
|
||||
publisher_name = "CN=Google LLC"
|
||||
product_name = "Google Chrome"
|
||||
binary_name = "chrome.exe"
|
||||
access = "allow"
|
||||
"#,
|
||||
)
|
||||
.expect("computer use config should deserialize");
|
||||
|
||||
let expected = ComputerUseConfigToml {
|
||||
default_app_access: Some(AllowDenyRequirementToml::Deny),
|
||||
macos: Some(ComputerUseMacosConfigToml {
|
||||
bundle_ids: Some(BTreeMap::from([(
|
||||
"com.apple.Safari".to_string(),
|
||||
AllowDenyRequirementToml::Allow,
|
||||
)])),
|
||||
}),
|
||||
windows: Some(ComputerUseWindowsConfigToml {
|
||||
aumids: Some(BTreeMap::from([(
|
||||
"Microsoft.Paint_8wekyb3d8bbwe!App".to_string(),
|
||||
AllowDenyRequirementToml::Deny,
|
||||
)])),
|
||||
exes: Some(vec![ComputerUseWindowsExeConfigToml {
|
||||
publisher_name: "CN=Google LLC".to_string(),
|
||||
product_name: "Google Chrome".to_string(),
|
||||
binary_name: Some("chrome.exe".to_string()),
|
||||
access: AllowDenyRequirementToml::Allow,
|
||||
}]),
|
||||
}),
|
||||
};
|
||||
assert_eq!(config.computer_use, Some(expected.clone()));
|
||||
|
||||
let serialized = toml::to_string(&config).expect("computer use config should serialize");
|
||||
let reparsed: ConfigToml =
|
||||
toml::from_str(&serialized).expect("serialized computer use config should deserialize");
|
||||
assert_eq!(reparsed.computer_use, Some(expected));
|
||||
}
|
||||
@@ -6,6 +6,8 @@ use std::num::NonZeroU64;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::HooksToml;
|
||||
use crate::browser_use::BrowserUseConfigToml;
|
||||
use crate::computer_use::ComputerUseConfigToml;
|
||||
use crate::permissions_toml::PermissionsToml;
|
||||
use crate::profile_toml::ConfigProfile;
|
||||
use crate::types::AnalyticsConfigToml;
|
||||
@@ -182,6 +184,10 @@ pub struct ConfigToml {
|
||||
#[serde(default)]
|
||||
pub auto_review: Option<AutoReviewToml>,
|
||||
|
||||
pub browser_use: Option<BrowserUseConfigToml>,
|
||||
|
||||
pub computer_use: Option<ComputerUseConfigToml>,
|
||||
|
||||
#[serde(default)]
|
||||
pub shell_environment_policy: ShellEnvironmentPolicyToml,
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
mod auth_policy;
|
||||
mod browser_computer_use_requirements;
|
||||
mod browser_use;
|
||||
mod cloud_config_bundle;
|
||||
mod cloud_config_layers;
|
||||
mod computer_use;
|
||||
mod config_layer_source;
|
||||
mod config_requirements;
|
||||
pub mod config_toml;
|
||||
@@ -46,6 +48,8 @@ pub use browser_computer_use_requirements::ComputerUseMacosRequirementsToml;
|
||||
pub use browser_computer_use_requirements::ComputerUseRequirementsToml;
|
||||
pub use browser_computer_use_requirements::ComputerUseWindowsExeRequirementToml;
|
||||
pub use browser_computer_use_requirements::ComputerUseWindowsRequirementsToml;
|
||||
pub use browser_use::BrowserUseConfigToml;
|
||||
pub use browser_use::BrowserUseOriginPolicyConfigToml;
|
||||
pub use cloud_config_bundle::CloudConfigBundle;
|
||||
pub use cloud_config_bundle::CloudConfigBundleLayers;
|
||||
pub use cloud_config_bundle::CloudConfigBundleLoadError;
|
||||
@@ -69,6 +73,10 @@ pub use codex_protocol::mcp_policy::McpServerValueMatcher;
|
||||
pub use codex_protocol::mcp_policy::PluginMcpRequirements as PluginRequirementsToml;
|
||||
pub use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
pub use codex_utils_absolute_path::AbsolutePathBufGuard;
|
||||
pub use computer_use::ComputerUseConfigToml;
|
||||
pub use computer_use::ComputerUseMacosConfigToml;
|
||||
pub use computer_use::ComputerUseWindowsConfigToml;
|
||||
pub use computer_use::ComputerUseWindowsExeConfigToml;
|
||||
pub use config_layer_source::ConfigLayer;
|
||||
pub use config_layer_source::ConfigLayerMetadata;
|
||||
pub use config_layer_source::ConfigLayerSource;
|
||||
|
||||
@@ -70,6 +70,13 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AllowDenyRequirementToml": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AltScreenMode": {
|
||||
"description": "Controls whether the TUI uses the terminal's alternate screen buffer.\n\n- `auto` (default): Use alternate screen mode. - `always`: Always use alternate screen mode. - `never`: Never use alternate screen mode. Runs in inline mode, preserving scrollback.\n\nThe CLI flag `--no-alt-screen` can override this setting at runtime.",
|
||||
"oneOf": [
|
||||
@@ -374,6 +381,42 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseConfigToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"allow_history_access": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"default_origin_policy": {
|
||||
"$ref": "#/definitions/BrowserUseOriginPolicyConfigToml"
|
||||
},
|
||||
"origins": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/BrowserUseOriginPolicyConfigToml"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BrowserUseOriginPolicyConfigToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
},
|
||||
"downloads": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
},
|
||||
"full_cdp_access": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
},
|
||||
"uploads": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"BundledSkillsConfig": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@@ -426,6 +469,74 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseConfigToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"default_app_access": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
},
|
||||
"macos": {
|
||||
"$ref": "#/definitions/ComputerUseMacosConfigToml"
|
||||
},
|
||||
"windows": {
|
||||
"$ref": "#/definitions/ComputerUseWindowsConfigToml"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseMacosConfigToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"bundle_ids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsConfigToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"aumids": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"exes": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ComputerUseWindowsExeConfigToml"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ComputerUseWindowsExeConfigToml": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/AllowDenyRequirementToml"
|
||||
},
|
||||
"binary_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"product_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"publisher_name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"product_name",
|
||||
"publisher_name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ConfigProfile": {
|
||||
"additionalProperties": false,
|
||||
"description": "Collection of common configuration options that a user can define as a unit in `config.toml`.",
|
||||
@@ -5334,6 +5445,9 @@
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
},
|
||||
"browser_use": {
|
||||
"$ref": "#/definitions/BrowserUseConfigToml"
|
||||
},
|
||||
"chatgpt_base_url": {
|
||||
"description": "Base URL for requests to ChatGPT (as opposed to the OpenAI API).",
|
||||
"type": "string"
|
||||
@@ -5355,6 +5469,9 @@
|
||||
"description": "Compact prompt used for history compaction.",
|
||||
"type": "string"
|
||||
},
|
||||
"computer_use": {
|
||||
"$ref": "#/definitions/ComputerUseConfigToml"
|
||||
},
|
||||
"default_permissions": {
|
||||
"description": "Default permissions profile to apply. Names starting with `:` refer to built-in profiles; other names are resolved from the `[permissions]` table.",
|
||||
"type": "string"
|
||||
|
||||
Reference in New Issue
Block a user