Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -6917,6 +6917,12 @@
},
"ConfigRequirements": {
"properties": {
"allowManagedHooksOnly": {
"type": [
"boolean",
"null"
]
},
"allowedApprovalPolicies": {
"items": {
"$ref": "#/definitions/v2/AskForApproval"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3514,6 +3514,12 @@
},
"ConfigRequirements": {
"properties": {
"allowManagedHooksOnly": {
"type": [
"boolean",
"null"
]
},
"allowedApprovalPolicies": {
"items": {
"$ref": "#/definitions/AskForApproval"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
},
"ConfigRequirements": {
"properties": {
"allowManagedHooksOnly": {
"type": [
"boolean",
"null"
]
},
"allowedApprovalPolicies": {
"items": {
"$ref": "#/definitions/AskForApproval"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ import type { AskForApproval } from "./AskForApproval";
import type { ResidencyRequirement } from "./ResidencyRequirement";
import type { SandboxMode } from "./SandboxMode";

export type ConfigRequirements = {allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedWebSearchModes: Array<WebSearchMode> | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null};
export type ConfigRequirements = {allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedWebSearchModes: Array<WebSearchMode> | null, allowManagedHooksOnly: boolean | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null};
2 changes: 2 additions & 0 deletions codex-rs/app-server-protocol/src/protocol/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,7 @@ pub struct ConfigRequirements {
pub allowed_approvals_reviewers: Option<Vec<ApprovalsReviewer>>,
pub allowed_sandbox_modes: Option<Vec<SandboxMode>>,
pub allowed_web_search_modes: Option<Vec<WebSearchMode>>,
pub allow_managed_hooks_only: Option<bool>,
pub feature_requirements: Option<BTreeMap<String, bool>>,
pub enforce_residency: Option<ResidencyRequirement>,
#[experimental("configRequirements/read.network")]
Expand Down Expand Up @@ -7845,6 +7846,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
feature_requirements: None,
enforce_residency: None,
network: None,
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ Example with notification opt-out:
- `externalAgentConfig/import` — apply selected external-agent migration items by passing explicit `migrationItems` with `cwd` (`null` for home) and any plugin `details` returned by detect. When a request includes plugin imports, the server emits `externalAgentConfig/import/completed` after the full import finishes (immediately after the response when everything completed synchronously, or after background remote imports finish).
- `config/value/write` — write a single config key/value to the user's config.toml on disk.
- `config/batchWrite` — apply multiple config edits atomically to the user's config.toml on disk, with optional `reloadUserConfig: true` to hot-reload loaded threads.
- `configRequirements/read` — fetch loaded requirements constraints from `requirements.toml` and/or MDM (or `null` if none are configured), including allow-lists (`allowedApprovalPolicies`, `allowedSandboxModes`, `allowedWebSearchModes`), pinned feature values (`featureRequirements`), `enforceResidency`, and `network` constraints such as canonical domain/socket permissions plus `managedAllowedDomainsOnly`.
- `configRequirements/read` — fetch loaded requirements constraints from `requirements.toml` and/or MDM (or `null` if none are configured), including allow-lists (`allowedApprovalPolicies`, `allowedSandboxModes`, `allowedWebSearchModes`), `allowManagedHooksOnly`, pinned feature values (`featureRequirements`), `enforceResidency`, and `network` constraints such as canonical domain/socket permissions plus `managedAllowedDomainsOnly` and `dangerFullAccessDenylistOnly`.

### Example: Start or resume a thread

Expand Down
5 changes: 5 additions & 0 deletions codex-rs/app-server/src/config_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ fn map_requirements_toml_to_api(requirements: ConfigRequirementsToml) -> ConfigR
}
normalized
}),
allow_managed_hooks_only: requirements.allow_managed_hooks_only,
feature_requirements: requirements
.feature_requirements
.map(|requirements| requirements.entries),
Expand Down Expand Up @@ -566,6 +567,7 @@ mod tests {
allowed_web_search_modes: Some(vec![
codex_core::config_loader::WebSearchModeRequirement::Cached,
]),
allow_managed_hooks_only: Some(true),
guardian_policy_config: None,
feature_requirements: Some(codex_core::config_loader::FeatureRequirementsToml {
entries: std::collections::BTreeMap::from([
Expand Down Expand Up @@ -632,6 +634,7 @@ mod tests {
mapped.allowed_web_search_modes,
Some(vec![WebSearchMode::Cached, WebSearchMode::Disabled]),
);
assert_eq!(mapped.allow_managed_hooks_only, Some(true));
assert_eq!(
mapped.feature_requirements,
Some(std::collections::BTreeMap::from([
Expand Down Expand Up @@ -676,6 +679,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -734,6 +738,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: Some(Vec::new()),
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down
16 changes: 16 additions & 0 deletions codex-rs/cloud-requirements/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1195,6 +1196,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1225,6 +1227,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1272,6 +1275,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1355,6 +1359,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1428,6 +1433,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1499,6 +1505,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1697,6 +1704,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1733,6 +1741,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1789,6 +1798,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1840,6 +1850,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1895,6 +1906,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -1951,6 +1963,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -2007,6 +2020,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -2096,6 +2110,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down Expand Up @@ -2124,6 +2139,7 @@ enabled = false
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
guardian_policy_config: None,
feature_requirements: None,
mcp_servers: None,
Expand Down
21 changes: 21 additions & 0 deletions codex-rs/config/src/config_requirements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ pub struct ConfigRequirements {
pub approvals_reviewer: ConstrainedWithSource<ApprovalsReviewer>,
pub sandbox_policy: ConstrainedWithSource<SandboxPolicy>,
pub web_search_mode: ConstrainedWithSource<WebSearchMode>,
pub allow_managed_hooks_only: Option<Sourced<bool>>,
pub feature_requirements: Option<Sourced<FeatureRequirementsToml>>,
pub mcp_servers: Option<Sourced<BTreeMap<String, McpServerRequirement>>>,
pub exec_policy: Option<Sourced<RequirementsExecPolicy>>,
Expand Down Expand Up @@ -113,6 +114,7 @@ impl Default for ConfigRequirements {
Constrained::allow_any(WebSearchMode::Cached),
/*source*/ None,
),
allow_managed_hooks_only: None,
feature_requirements: None,
mcp_servers: None,
exec_policy: None,
Expand Down Expand Up @@ -621,6 +623,7 @@ pub struct ConfigRequirementsToml {
pub allowed_approvals_reviewers: Option<Vec<ApprovalsReviewer>>,
pub allowed_sandbox_modes: Option<Vec<SandboxModeRequirement>>,
pub allowed_web_search_modes: Option<Vec<WebSearchModeRequirement>>,
pub allow_managed_hooks_only: Option<bool>,
#[serde(rename = "features", alias = "feature_requirements")]
pub feature_requirements: Option<FeatureRequirementsToml>,
pub mcp_servers: Option<BTreeMap<String, McpServerRequirement>>,
Expand Down Expand Up @@ -661,6 +664,7 @@ pub struct ConfigRequirementsWithSources {
pub allowed_approvals_reviewers: Option<Sourced<Vec<ApprovalsReviewer>>>,
pub allowed_sandbox_modes: Option<Sourced<Vec<SandboxModeRequirement>>>,
pub allowed_web_search_modes: Option<Sourced<Vec<WebSearchModeRequirement>>>,
pub allow_managed_hooks_only: Option<Sourced<bool>>,
pub feature_requirements: Option<Sourced<FeatureRequirementsToml>>,
pub mcp_servers: Option<Sourced<BTreeMap<String, McpServerRequirement>>>,
pub apps: Option<Sourced<AppsRequirementsToml>>,
Expand Down Expand Up @@ -694,6 +698,7 @@ impl ConfigRequirementsWithSources {
allowed_approvals_reviewers: _,
allowed_sandbox_modes: _,
allowed_web_search_modes: _,
allow_managed_hooks_only: _,
feature_requirements: _,
mcp_servers: _,
apps: _,
Expand Down Expand Up @@ -721,6 +726,7 @@ impl ConfigRequirementsWithSources {
allowed_approvals_reviewers,
allowed_sandbox_modes,
allowed_web_search_modes,
allow_managed_hooks_only,
feature_requirements,
mcp_servers,
rules,
Expand All @@ -746,6 +752,7 @@ impl ConfigRequirementsWithSources {
allowed_approvals_reviewers,
allowed_sandbox_modes,
allowed_web_search_modes,
allow_managed_hooks_only,
feature_requirements,
mcp_servers,
apps,
Expand All @@ -760,6 +767,7 @@ impl ConfigRequirementsWithSources {
allowed_approvals_reviewers: allowed_approvals_reviewers.map(|sourced| sourced.value),
allowed_sandbox_modes: allowed_sandbox_modes.map(|sourced| sourced.value),
allowed_web_search_modes: allowed_web_search_modes.map(|sourced| sourced.value),
allow_managed_hooks_only: allow_managed_hooks_only.map(|sourced| sourced.value),
feature_requirements: feature_requirements.map(|sourced| sourced.value),
mcp_servers: mcp_servers.map(|sourced| sourced.value),
apps: apps.map(|sourced| sourced.value),
Expand Down Expand Up @@ -811,6 +819,7 @@ impl ConfigRequirementsToml {
&& self.allowed_approvals_reviewers.is_none()
&& self.allowed_sandbox_modes.is_none()
&& self.allowed_web_search_modes.is_none()
&& self.allow_managed_hooks_only.is_none()
&& self
.feature_requirements
.as_ref()
Expand Down Expand Up @@ -840,6 +849,7 @@ impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {
allowed_approvals_reviewers,
allowed_sandbox_modes,
allowed_web_search_modes,
allow_managed_hooks_only,
feature_requirements,
mcp_servers,
apps: _apps,
Expand Down Expand Up @@ -1061,6 +1071,7 @@ impl TryFrom<ConfigRequirementsWithSources> for ConfigRequirements {
approvals_reviewer,
sandbox_policy,
web_search_mode,
allow_managed_hooks_only,
feature_requirements,
mcp_servers,
exec_policy,
Expand Down Expand Up @@ -1100,6 +1111,7 @@ mod tests {
allowed_approvals_reviewers,
allowed_sandbox_modes,
allowed_web_search_modes,
allow_managed_hooks_only,
feature_requirements,
mcp_servers,
apps,
Expand All @@ -1118,6 +1130,8 @@ mod tests {
.map(|value| Sourced::new(value, RequirementSource::Unknown)),
allowed_web_search_modes: allowed_web_search_modes
.map(|value| Sourced::new(value, RequirementSource::Unknown)),
allow_managed_hooks_only: allow_managed_hooks_only
.map(|value| Sourced::new(value, RequirementSource::Unknown)),
feature_requirements: feature_requirements
.map(|value| Sourced::new(value, RequirementSource::Unknown)),
mcp_servers: mcp_servers.map(|value| Sourced::new(value, RequirementSource::Unknown)),
Expand Down Expand Up @@ -1162,6 +1176,7 @@ mod tests {
allowed_approvals_reviewers: Some(allowed_approvals_reviewers.clone()),
allowed_sandbox_modes: Some(allowed_sandbox_modes.clone()),
allowed_web_search_modes: Some(allowed_web_search_modes.clone()),
allow_managed_hooks_only: Some(true),
feature_requirements: Some(feature_requirements.clone()),
mcp_servers: None,
apps: None,
Expand Down Expand Up @@ -1190,6 +1205,10 @@ mod tests {
allowed_web_search_modes,
enforce_source.clone(),
)),
allow_managed_hooks_only: Some(Sourced::new(
/*value*/ true,
enforce_source.clone(),
)),
feature_requirements: Some(Sourced::new(
feature_requirements,
enforce_source.clone(),
Expand Down Expand Up @@ -1230,6 +1249,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
feature_requirements: None,
mcp_servers: None,
apps: None,
Expand Down Expand Up @@ -1275,6 +1295,7 @@ mod tests {
allowed_approvals_reviewers: None,
allowed_sandbox_modes: None,
allowed_web_search_modes: None,
allow_managed_hooks_only: None,
feature_requirements: None,
mcp_servers: None,
apps: None,
Expand Down
11 changes: 11 additions & 0 deletions codex-rs/config/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ impl ConfigLayerEntry {
self.disabled_reason.is_some()
}

/// Returns true for config layers controlled by managed policy sources.
pub fn is_managed(&self) -> bool {
matches!(
self.name,
ConfigLayerSource::Mdm { .. }
| ConfigLayerSource::System { .. }
| ConfigLayerSource::LegacyManagedConfigTomlFromFile { .. }
| ConfigLayerSource::LegacyManagedConfigTomlFromMdm
)
}

pub fn raw_toml(&self) -> Option<&str> {
self.raw_toml.as_deref()
}
Expand Down
Loading
Loading