mirror of
https://github.com/openai/codex.git
synced 2026-10-19 17:28:46 +00:00
fix(runtime-install): restrict archive sources
This commit is contained in:
Generated
+1
@@ -3759,6 +3759,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
|
||||
@@ -2982,6 +2982,27 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallParams": {
|
||||
"properties": {
|
||||
"environmentId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"manifest": {
|
||||
"$ref": "#/definitions/RuntimeInstallManifestParams"
|
||||
},
|
||||
"release": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"manifest",
|
||||
"release"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SandboxMode": {
|
||||
"enum": [
|
||||
"read-only",
|
||||
@@ -5663,6 +5684,53 @@
|
||||
"title": "Plugin/installRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"runtime/install"
|
||||
],
|
||||
"title": "Runtime/installRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/RuntimeInstallParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Runtime/installRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"runtime/install/cancel"
|
||||
],
|
||||
"title": "Runtime/install/cancelRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method"
|
||||
],
|
||||
"title": "Runtime/install/cancelRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
|
||||
+106
@@ -1357,6 +1357,53 @@
|
||||
"title": "Plugin/installRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"runtime/install"
|
||||
],
|
||||
"title": "Runtime/installRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/RuntimeInstallParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Runtime/installRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"runtime/install/cancel"
|
||||
],
|
||||
"title": "Runtime/install/cancelRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method"
|
||||
],
|
||||
"title": "Runtime/install/cancelRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -15120,6 +15167,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"RuntimeInstallCancelResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"status": {
|
||||
"$ref": "#/definitions/v2/RuntimeInstallCancelStatus"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"title": "RuntimeInstallCancelResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallCancelStatus": {
|
||||
"enum": [
|
||||
"canceled",
|
||||
@@ -15182,6 +15242,29 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"environmentId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"manifest": {
|
||||
"$ref": "#/definitions/v2/RuntimeInstallManifestParams"
|
||||
},
|
||||
"release": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"manifest",
|
||||
"release"
|
||||
],
|
||||
"title": "RuntimeInstallParams",
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallPaths": {
|
||||
"properties": {
|
||||
"bundledPluginMarketplacePaths": {
|
||||
@@ -15269,6 +15352,29 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RuntimeInstallResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"bundleVersion": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"paths": {
|
||||
"$ref": "#/definitions/v2/RuntimeInstallPaths"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/v2/RuntimeInstallStatus"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"paths",
|
||||
"status"
|
||||
],
|
||||
"title": "RuntimeInstallResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallStatus": {
|
||||
"enum": [
|
||||
"already-current",
|
||||
|
||||
+106
@@ -2341,6 +2341,53 @@
|
||||
"title": "Plugin/installRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"runtime/install"
|
||||
],
|
||||
"title": "Runtime/installRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/RuntimeInstallParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Runtime/installRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"runtime/install/cancel"
|
||||
],
|
||||
"title": "Runtime/install/cancelRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method"
|
||||
],
|
||||
"title": "Runtime/install/cancelRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -11573,6 +11620,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"RuntimeInstallCancelResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"status": {
|
||||
"$ref": "#/definitions/RuntimeInstallCancelStatus"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"title": "RuntimeInstallCancelResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallCancelStatus": {
|
||||
"enum": [
|
||||
"canceled",
|
||||
@@ -11635,6 +11695,29 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"environmentId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"manifest": {
|
||||
"$ref": "#/definitions/RuntimeInstallManifestParams"
|
||||
},
|
||||
"release": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"manifest",
|
||||
"release"
|
||||
],
|
||||
"title": "RuntimeInstallParams",
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallPaths": {
|
||||
"properties": {
|
||||
"bundledPluginMarketplacePaths": {
|
||||
@@ -11722,6 +11805,29 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"RuntimeInstallResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"bundleVersion": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"paths": {
|
||||
"$ref": "#/definitions/RuntimeInstallPaths"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/RuntimeInstallStatus"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"paths",
|
||||
"status"
|
||||
],
|
||||
"title": "RuntimeInstallResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallStatus": {
|
||||
"enum": [
|
||||
"already-current",
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"RuntimeInstallCancelStatus": {
|
||||
"enum": [
|
||||
"canceled",
|
||||
"not-found"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"status": {
|
||||
"$ref": "#/definitions/RuntimeInstallCancelStatus"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"title": "RuntimeInstallCancelResponse",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"RuntimeInstallManifestParams": {
|
||||
"properties": {
|
||||
"archiveName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"archiveSha256": {
|
||||
"type": "string"
|
||||
},
|
||||
"archiveSizeBytes": {
|
||||
"format": "uint64",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"archiveUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"bundleFormatVersion": {
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"bundleVersion": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"runtimeRootDirectoryName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"archiveSha256",
|
||||
"archiveUrl"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"environmentId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"manifest": {
|
||||
"$ref": "#/definitions/RuntimeInstallManifestParams"
|
||||
},
|
||||
"release": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"manifest",
|
||||
"release"
|
||||
],
|
||||
"title": "RuntimeInstallParams",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"$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"
|
||||
},
|
||||
"RuntimeInstallPaths": {
|
||||
"properties": {
|
||||
"bundledPluginMarketplacePaths": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"bundledSkillPaths": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nodeModulesPath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"nodePath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"pythonPath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"skillsToRemove": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bundledPluginMarketplacePaths",
|
||||
"bundledSkillPaths",
|
||||
"nodeModulesPath",
|
||||
"nodePath",
|
||||
"pythonPath",
|
||||
"skillsToRemove"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RuntimeInstallStatus": {
|
||||
"enum": [
|
||||
"already-current",
|
||||
"installed"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"bundleVersion": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"paths": {
|
||||
"$ref": "#/definitions/RuntimeInstallPaths"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/RuntimeInstallStatus"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"paths",
|
||||
"status"
|
||||
],
|
||||
"title": "RuntimeInstallResponse",
|
||||
"type": "object"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
+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 { RuntimeInstallCancelStatus } from "./RuntimeInstallCancelStatus";
|
||||
|
||||
export type RuntimeInstallCancelResponse = { status: RuntimeInstallCancelStatus, };
|
||||
@@ -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 { RuntimeInstallManifestParams } from "./RuntimeInstallManifestParams";
|
||||
|
||||
export type RuntimeInstallParams = { environmentId?: string | null, manifest: RuntimeInstallManifestParams, release: string, };
|
||||
@@ -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 { RuntimeInstallPaths } from "./RuntimeInstallPaths";
|
||||
import type { RuntimeInstallStatus } from "./RuntimeInstallStatus";
|
||||
|
||||
export type RuntimeInstallResponse = { bundleVersion: string | null, paths: RuntimeInstallPaths, status: RuntimeInstallStatus, };
|
||||
@@ -334,11 +334,14 @@ export type { ReviewDelivery } from "./ReviewDelivery";
|
||||
export type { ReviewStartParams } from "./ReviewStartParams";
|
||||
export type { ReviewStartResponse } from "./ReviewStartResponse";
|
||||
export type { ReviewTarget } from "./ReviewTarget";
|
||||
export type { RuntimeInstallCancelResponse } from "./RuntimeInstallCancelResponse";
|
||||
export type { RuntimeInstallCancelStatus } from "./RuntimeInstallCancelStatus";
|
||||
export type { RuntimeInstallManifestParams } from "./RuntimeInstallManifestParams";
|
||||
export type { RuntimeInstallParams } from "./RuntimeInstallParams";
|
||||
export type { RuntimeInstallPaths } from "./RuntimeInstallPaths";
|
||||
export type { RuntimeInstallProgressNotification } from "./RuntimeInstallProgressNotification";
|
||||
export type { RuntimeInstallProgressPhase } from "./RuntimeInstallProgressPhase";
|
||||
export type { RuntimeInstallResponse } from "./RuntimeInstallResponse";
|
||||
export type { RuntimeInstallStatus } from "./RuntimeInstallStatus";
|
||||
export type { SandboxMode } from "./SandboxMode";
|
||||
export type { SandboxPolicy } from "./SandboxPolicy";
|
||||
|
||||
@@ -791,13 +791,11 @@ client_request_definitions! {
|
||||
serialization: global("config"),
|
||||
response: v2::PluginInstallResponse,
|
||||
},
|
||||
#[experimental("runtime/install")]
|
||||
RuntimeInstall => "runtime/install" {
|
||||
params: v2::RuntimeInstallParams,
|
||||
serialization: global("runtime-install"),
|
||||
response: v2::RuntimeInstallResponse,
|
||||
},
|
||||
#[experimental("runtime/install/cancel")]
|
||||
RuntimeInstallCancel => "runtime/install/cancel" {
|
||||
params: #[ts(type = "undefined")] #[serde(skip_serializing_if = "Option::is_none")] Option<()>,
|
||||
serialization: None,
|
||||
|
||||
@@ -220,9 +220,9 @@ Example with notification opt-out:
|
||||
- `remoteControl/status/changed` — notification emitted when the remote-control status or client-visible environment id changes. `status` is one of `disabled`, `connecting`, `connected`, or `errored`; `serverName` is the local machine name used by this app-server process; `environmentId` is a string when the app-server has a current enrollment and `null` when that enrollment is cleared, invalidated, or remote control is disabled. Newly initialized app-server clients always receive the current status snapshot.
|
||||
- `skills/config/write` — write user-level skill config by name or absolute path.
|
||||
- `plugin/install` — install a plugin from a discovered marketplace entry, rejecting marketplace entries marked unavailable for install, install MCPs if any, and return the effective plugin auth policy plus any apps that still need auth (**under development; do not call from production clients yet**).
|
||||
- `runtime/install` — experimental; install the selected primary runtime bundle and return its executable, dependency, bundled-skill, and bundled-marketplace paths after app-server config synchronization. App-server coordinates the install through the selected environment's generic process and filesystem operations; runtime installs are process-wide and serialized.
|
||||
- `runtime/install` — install the selected primary runtime bundle and return its executable, dependency, bundled-skill, and bundled-marketplace paths after app-server config synchronization. App-server coordinates the install through the selected environment's generic process and filesystem operations; runtime installs are process-wide and serialized. The `latest` and `latest-alpha` releases only accept archive URLs under their corresponding OpenAI runtime asset locations.
|
||||
- `runtime/install/progress` — notification sent to the connection that requested `runtime/install` as the active install moves through checking, downloading, verifying, extracting, validating, installed, and configuring phases. Download notifications include byte counts when available.
|
||||
- `runtime/install/cancel` — experimental; cancel the one active `runtime/install` request for this app-server process and report whether an install was found.
|
||||
- `runtime/install/cancel` — cancel the one active `runtime/install` request for this app-server process and report whether an install was found.
|
||||
- `plugin/uninstall` — uninstall a local plugin by `pluginId` in `<plugin>@<marketplace>` form by removing its cached files and clearing its user-level config entry, or uninstall a remote ChatGPT plugin by backend `pluginId` by forwarding the uninstall to the ChatGPT plugin backend and removing any downloaded remote-plugin cache (**under development; do not call from production clients yet**).
|
||||
- `mcpServer/oauth/login` — start an OAuth login for a configured MCP server; returns an `authorization_url` and later emits `mcpServer/oauthLogin/completed` once the browser flow finishes.
|
||||
- `tool/requestUserInput` — prompt the user with 1–3 short questions for a tool call and return their answers (experimental).
|
||||
|
||||
@@ -29,6 +29,7 @@ tokio = { workspace = true, features = [
|
||||
] }
|
||||
tokio-util = { workspace = true, features = ["rt"] }
|
||||
tracing = { workspace = true }
|
||||
url = { workspace = true }
|
||||
uuid = { workspace = true, features = ["v7"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -105,7 +105,7 @@ async fn install_runtime_with_root_and_control(
|
||||
progress: Option<RuntimeInstallProgressSender>,
|
||||
cancellation: CancellationToken,
|
||||
) -> Result<RuntimeInstallResponse, JSONRPCErrorError> {
|
||||
validate_manifest(¶ms.manifest)?;
|
||||
validate_manifest(¶ms.release, ¶ms.manifest)?;
|
||||
let archive_format = runtime_archive_format(¶ms.manifest)?;
|
||||
let archive_name = params
|
||||
.manifest
|
||||
|
||||
@@ -44,14 +44,15 @@ async fn install_runtime_reuses_current_runtime_without_downloading_archive() {
|
||||
.await
|
||||
.expect("write archive");
|
||||
let mut manifest = manifest_for_archive(&archive_path, "v1").await;
|
||||
manifest.archive_url = "not a valid archive URL".to_string();
|
||||
manifest.archive_url =
|
||||
"https://persistent.oaistatic.com/codex-primary-runtime/v1/runtime.tar.xz".to_string();
|
||||
|
||||
let response = install_runtime_with_root_and_control(
|
||||
&executor,
|
||||
RuntimeInstallParams {
|
||||
environment_id: None,
|
||||
manifest: Box::new(manifest),
|
||||
release: "primary".to_string(),
|
||||
release: "latest".to_string(),
|
||||
},
|
||||
install_root,
|
||||
local_platform(),
|
||||
|
||||
@@ -8,6 +8,7 @@ use codex_app_server_protocol::RuntimeInstallManifestParams;
|
||||
use codex_app_server_protocol::RuntimeInstallPaths;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
use crate::errors::internal_error;
|
||||
use crate::errors::invalid_params;
|
||||
@@ -16,7 +17,29 @@ use crate::executor::RuntimeExecutor;
|
||||
use crate::executor::TargetPlatform;
|
||||
use crate::executor::path_uri;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "validation_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
pub(crate) const PUBLISHED_ARTIFACT_NAME: &str = "codex-primary-runtime";
|
||||
const LATEST_RELEASE: &str = "latest";
|
||||
const LATEST_ALPHA_RELEASE: &str = "latest-alpha";
|
||||
const LATEST_ARCHIVE_LOCATION: ApprovedArchiveLocation = ApprovedArchiveLocation {
|
||||
base_url: "https://persistent.oaistatic.com/codex-primary-runtime",
|
||||
host: "persistent.oaistatic.com",
|
||||
path_prefix: "/codex-primary-runtime/",
|
||||
};
|
||||
const LATEST_ALPHA_ARCHIVE_LOCATION: ApprovedArchiveLocation = ApprovedArchiveLocation {
|
||||
base_url: "https://oaisidekickupdates.blob.core.windows.net/owl/codex-primary-runtime/alpha",
|
||||
host: "oaisidekickupdates.blob.core.windows.net",
|
||||
path_prefix: "/owl/codex-primary-runtime/alpha/",
|
||||
};
|
||||
|
||||
struct ApprovedArchiveLocation {
|
||||
base_url: &'static str,
|
||||
host: &'static str,
|
||||
path_prefix: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -29,13 +52,10 @@ pub(crate) struct InstalledRuntimeMetadata {
|
||||
}
|
||||
|
||||
pub(crate) fn validate_manifest(
|
||||
release: &str,
|
||||
manifest: &RuntimeInstallManifestParams,
|
||||
) -> Result<(), JSONRPCErrorError> {
|
||||
if manifest.archive_url.trim().is_empty() {
|
||||
return Err(invalid_params(
|
||||
"runtime manifest archiveUrl must not be empty",
|
||||
));
|
||||
}
|
||||
validate_archive_url(release, &manifest.archive_url)?;
|
||||
if !is_sha256(&manifest.archive_sha256) {
|
||||
return Err(invalid_params(
|
||||
"runtime manifest archiveSha256 must be a 64-character hex digest",
|
||||
@@ -50,6 +70,50 @@ pub(crate) fn validate_manifest(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_archive_url(release: &str, archive_url: &str) -> Result<(), JSONRPCErrorError> {
|
||||
let approved_location = match release {
|
||||
LATEST_RELEASE => &LATEST_ARCHIVE_LOCATION,
|
||||
LATEST_ALPHA_RELEASE => &LATEST_ALPHA_ARCHIVE_LOCATION,
|
||||
_ => {
|
||||
return Err(invalid_params(format!(
|
||||
"unsupported runtime release: {release}"
|
||||
)));
|
||||
}
|
||||
};
|
||||
let archive_url = Url::parse(archive_url)
|
||||
.map_err(|_| invalid_archive_url(release, approved_location.base_url))?;
|
||||
let archive_path = archive_url
|
||||
.path()
|
||||
.strip_prefix(approved_location.path_prefix)
|
||||
.unwrap_or_default();
|
||||
let mut path_segments = archive_path.split('/');
|
||||
let has_archive_layout = path_segments
|
||||
.next()
|
||||
.is_some_and(|segment| !segment.is_empty())
|
||||
&& path_segments
|
||||
.next()
|
||||
.is_some_and(|segment| !segment.is_empty())
|
||||
&& path_segments.next().is_none();
|
||||
if archive_url.scheme() != "https"
|
||||
|| archive_url.host_str() != Some(approved_location.host)
|
||||
|| archive_url.port_or_known_default() != Some(443)
|
||||
|| !archive_url.username().is_empty()
|
||||
|| archive_url.password().is_some()
|
||||
|| archive_url.query().is_some()
|
||||
|| archive_url.fragment().is_some()
|
||||
|| !has_archive_layout
|
||||
{
|
||||
return Err(invalid_archive_url(release, approved_location.base_url));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn invalid_archive_url(release: &str, approved_base_url: &str) -> JSONRPCErrorError {
|
||||
invalid_params(format!(
|
||||
"runtime manifest archiveUrl for release '{release}' must match the approved OpenAI runtime asset location {approved_base_url}/<version>/<archive>"
|
||||
))
|
||||
}
|
||||
|
||||
fn is_sha256(value: &str) -> bool {
|
||||
value.len() == 64 && value.bytes().all(|byte| byte.is_ascii_hexdigit())
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
use codex_app_server_protocol::RuntimeInstallManifestParams;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::validate_manifest;
|
||||
use crate::errors::invalid_params;
|
||||
|
||||
const SHA256: &str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
||||
|
||||
#[test]
|
||||
fn manifest_accepts_archive_for_selected_release() {
|
||||
let cases = [
|
||||
(
|
||||
"latest",
|
||||
"https://persistent.oaistatic.com/codex-primary-runtime/2026.06.17/runtime.tar.xz",
|
||||
),
|
||||
(
|
||||
"latest-alpha",
|
||||
"https://oaisidekickupdates.blob.core.windows.net/owl/codex-primary-runtime/alpha/2026.06.17/runtime.zip",
|
||||
),
|
||||
];
|
||||
|
||||
for (release, archive_url) in cases {
|
||||
assert_eq!(validate_manifest(release, &manifest(archive_url)), Ok(()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn manifest_rejects_unapproved_archive_locations() {
|
||||
let cases = [
|
||||
(
|
||||
"latest",
|
||||
"http://persistent.oaistatic.com/codex-primary-runtime/2026.06.17/runtime.tar.xz",
|
||||
),
|
||||
(
|
||||
"latest",
|
||||
"https://persistent.oaistatic.com.example.com/codex-primary-runtime/2026.06.17/runtime.tar.xz",
|
||||
),
|
||||
(
|
||||
"latest",
|
||||
"https://persistent.oaistatic.com/other/2026.06.17/runtime.tar.xz",
|
||||
),
|
||||
(
|
||||
"latest",
|
||||
"https://persistent.oaistatic.com/codex-primary-runtime/2026.06.17/runtime.tar.xz?redirect=https://example.com",
|
||||
),
|
||||
(
|
||||
"latest",
|
||||
"https://oaisidekickupdates.blob.core.windows.net/owl/codex-primary-runtime/alpha/2026.06.17/runtime.zip",
|
||||
),
|
||||
(
|
||||
"latest-alpha",
|
||||
"https://persistent.oaistatic.com/codex-primary-runtime/2026.06.17/runtime.tar.xz",
|
||||
),
|
||||
];
|
||||
|
||||
for (release, archive_url) in cases {
|
||||
let error = validate_manifest(release, &manifest(archive_url))
|
||||
.expect_err("archive location should be rejected");
|
||||
|
||||
assert_eq!(
|
||||
error,
|
||||
invalid_params(format!(
|
||||
"runtime manifest archiveUrl for release '{release}' must match the approved OpenAI runtime asset location {}/<version>/<archive>",
|
||||
approved_base_url(release)
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn manifest_rejects_unsupported_release() {
|
||||
let error = validate_manifest(
|
||||
"canary",
|
||||
&manifest(
|
||||
"https://persistent.oaistatic.com/codex-primary-runtime/2026.06.17/runtime.tar.xz",
|
||||
),
|
||||
)
|
||||
.expect_err("release should be rejected");
|
||||
|
||||
assert_eq!(error, invalid_params("unsupported runtime release: canary"));
|
||||
}
|
||||
|
||||
fn manifest(archive_url: &str) -> RuntimeInstallManifestParams {
|
||||
RuntimeInstallManifestParams {
|
||||
archive_name: None,
|
||||
archive_sha256: SHA256.to_string(),
|
||||
archive_size_bytes: None,
|
||||
archive_url: archive_url.to_string(),
|
||||
bundle_format_version: Some(2),
|
||||
bundle_version: Some("2026.06.17".to_string()),
|
||||
format: Some("tar.xz".to_string()),
|
||||
runtime_root_directory_name: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn approved_base_url(release: &str) -> &'static str {
|
||||
match release {
|
||||
"latest" => "https://persistent.oaistatic.com/codex-primary-runtime",
|
||||
"latest-alpha" => {
|
||||
"https://oaisidekickupdates.blob.core.windows.net/owl/codex-primary-runtime/alpha"
|
||||
}
|
||||
_ => panic!("unsupported test release"),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user