Use ApiPathString in app-server filesystem permission paths (#28367)

## Why

Clients running an app-server on one OS and an exec-server on another OS
need to be able to pass sandbox config to app-server that refers to
resources on the executor's foreign OS.

## What

`AbsolutePathBuf` can't represent these paths and we don't want users to
be exposed to `PathUri` yet, so this moves the public app-server API to
be expressed in terms of `ApiPathString`.

Stacked on #28165.

- change app-server v2 filesystem permission paths, including legacy
read/write roots, to `ApiPathString`
- localize API paths through `PathUri` when converting into the current
native core permission types
- make path-bearing permission conversions fallible and surface
localization failures instead of silently treating malformed grants as
ordinary denials
- propagate conversion failures through app-server and TUI approval
handling
- regenerate the app-server JSON and TypeScript schemas
- leave migration TODOs on native-path conversions so they can be
removed once core permission paths use `PathUri`
This commit is contained in:
Adam Perry @ OpenAI
2026-06-15 19:25:54 -07:00
committed by GitHub
Unverified
parent d959664420
commit ecfe174d5f
34 changed files with 546 additions and 233 deletions
@@ -27,7 +27,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -37,7 +37,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -84,6 +84,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"CommandAction": {
"oneOf": [
{
@@ -286,7 +289,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [
@@ -27,7 +27,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -37,7 +37,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -58,6 +58,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
@@ -71,7 +74,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [
@@ -1,10 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AbsolutePathBuf": {
"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"
},
"AdditionalFileSystemPermissions": {
"properties": {
"entries": {
@@ -27,7 +23,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -37,7 +33,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -58,6 +54,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
@@ -71,7 +70,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [
@@ -107,7 +107,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -117,7 +117,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -164,6 +164,9 @@
"AgentPath": {
"type": "string"
},
"ApiPathString": {
"type": "string"
},
"AppBranding": {
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
"properties": {
@@ -1318,7 +1321,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [
+6 -3
View File
@@ -27,7 +27,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -37,7 +37,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -84,6 +84,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"ApplyPatchApprovalParams": {
"properties": {
"callId": {
@@ -640,7 +643,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [
@@ -6020,7 +6020,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/v2/AbsolutePathBuf"
"$ref": "#/definitions/v2/ApiPathString"
},
"type": [
"array",
@@ -6030,7 +6030,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/v2/AbsolutePathBuf"
"$ref": "#/definitions/v2/ApiPathString"
},
"type": [
"array",
@@ -6135,6 +6135,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"AppBranding": {
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
"properties": {
@@ -9372,7 +9375,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/v2/AbsolutePathBuf"
"$ref": "#/definitions/v2/ApiPathString"
},
"type": {
"enum": [
@@ -265,7 +265,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -275,7 +275,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -380,6 +380,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"AppBranding": {
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
"properties": {
@@ -5685,7 +5688,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [
@@ -27,7 +27,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -37,7 +37,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -58,6 +58,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"AutoReviewDecisionSource": {
"description": "[UNSTABLE] Source that produced a terminal approval auto-review decision.",
"enum": [
@@ -78,7 +81,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [
@@ -27,7 +27,7 @@
"read": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -37,7 +37,7 @@
"write": {
"description": "This will be removed in favor of `entries`.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": [
"array",
@@ -58,6 +58,9 @@
},
"type": "object"
},
"ApiPathString": {
"type": "string"
},
"FileSystemAccessMode": {
"enum": [
"read",
@@ -71,7 +74,7 @@
{
"properties": {
"path": {
"$ref": "#/definitions/AbsolutePathBuf"
"$ref": "#/definitions/ApiPathString"
},
"type": {
"enum": [