mirror of
https://github.com/openai/codex.git
synced 2026-05-26 14:04:48 +00:00
Update guardian output schema (#17061)
## Summary - Update guardian output schema to separate risk, authorization, outcome, and rationale. - Feed guardian rationale into rejection messages. - Split the guardian policy into template and tenant-config sections. ## Validation - `cargo test -p codex-core mcp_tool_call` - `env -u CODEX_SANDBOX_NETWORK_DISABLED INSTA_UPDATE=always cargo test -p codex-core guardian::` --------- Co-authored-by: Owen Lin <owen@openai.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::codex::Session;
|
||||
use crate::guardian::GUARDIAN_REJECTION_MESSAGE;
|
||||
use crate::guardian::GuardianApprovalRequest;
|
||||
use crate::guardian::guardian_rejection_message;
|
||||
use crate::guardian::review_approval_request;
|
||||
use crate::guardian::routes_approval_to_guardian;
|
||||
use crate::network_policy_decision::denied_network_policy_message;
|
||||
@@ -368,6 +368,7 @@ impl NetworkApprovalService {
|
||||
protocol,
|
||||
};
|
||||
let owner_call = self.resolve_single_active_call().await;
|
||||
let guardian_approval_id = Self::approval_id_for_key(&key);
|
||||
let approval_decision = if routes_approval_to_guardian(&turn_context) {
|
||||
// TODO(ccunningham): Attach guardian network reviews to the reviewed tool item
|
||||
// lifecycle instead of this temporary standalone network approval id.
|
||||
@@ -375,7 +376,7 @@ impl NetworkApprovalService {
|
||||
&session,
|
||||
&turn_context,
|
||||
GuardianApprovalRequest::NetworkAccess {
|
||||
id: Self::approval_id_for_key(&key),
|
||||
id: guardian_approval_id.clone(),
|
||||
turn_id: owner_call
|
||||
.as_ref()
|
||||
.map_or_else(|| turn_context.sub_id.clone(), |call| call.turn_id.clone()),
|
||||
@@ -488,11 +489,12 @@ impl NetworkApprovalService {
|
||||
ReviewDecision::Denied | ReviewDecision::Abort => {
|
||||
if routes_approval_to_guardian(&turn_context) {
|
||||
if let Some(owner_call) = owner_call.as_ref() {
|
||||
let message =
|
||||
guardian_rejection_message(session.as_ref(), &guardian_approval_id)
|
||||
.await;
|
||||
self.record_call_outcome(
|
||||
&owner_call.registration_id,
|
||||
NetworkApprovalOutcome::DeniedByPolicy(
|
||||
GUARDIAN_REJECTION_MESSAGE.to_string(),
|
||||
),
|
||||
NetworkApprovalOutcome::DeniedByPolicy(message),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ simple sequence for any ToolRuntime: approval → select sandbox → attempt →
|
||||
retry with an escalated sandbox strategy on denial (no re‑approval thanks to
|
||||
caching).
|
||||
*/
|
||||
use crate::guardian::GUARDIAN_REJECTION_MESSAGE;
|
||||
use crate::guardian::guardian_rejection_message;
|
||||
use crate::guardian::routes_approval_to_guardian;
|
||||
use crate::network_policy_decision::network_approval_context_from_payload;
|
||||
use crate::tools::network_approval::DeferredNetworkApproval;
|
||||
@@ -149,7 +149,8 @@ impl ToolOrchestrator {
|
||||
match decision {
|
||||
ReviewDecision::Denied | ReviewDecision::Abort => {
|
||||
let reason = if routes_approval_to_guardian(turn_ctx) {
|
||||
GUARDIAN_REJECTION_MESSAGE.to_string()
|
||||
guardian_rejection_message(tool_ctx.session.as_ref(), &tool_ctx.call_id)
|
||||
.await
|
||||
} else {
|
||||
"rejected by user".to_string()
|
||||
};
|
||||
@@ -302,7 +303,11 @@ impl ToolOrchestrator {
|
||||
match decision {
|
||||
ReviewDecision::Denied | ReviewDecision::Abort => {
|
||||
let reason = if routes_approval_to_guardian(turn_ctx) {
|
||||
GUARDIAN_REJECTION_MESSAGE.to_string()
|
||||
guardian_rejection_message(
|
||||
tool_ctx.session.as_ref(),
|
||||
&tool_ctx.call_id,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
"rejected by user".to_string()
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::exec::ExecCapturePolicy;
|
||||
use crate::exec::ExecExpiration;
|
||||
use crate::exec::is_likely_sandbox_denied;
|
||||
use crate::guardian::GuardianApprovalRequest;
|
||||
use crate::guardian::guardian_rejection_message;
|
||||
use crate::guardian::review_approval_request;
|
||||
use crate::guardian::routes_approval_to_guardian;
|
||||
use crate::sandboxing::ExecOptions;
|
||||
@@ -469,7 +470,13 @@ impl CoreShellActionProvider {
|
||||
}
|
||||
},
|
||||
ReviewDecision::Denied => {
|
||||
EscalationDecision::deny(Some("User denied execution".to_string()))
|
||||
let message = if routes_approval_to_guardian(&self.turn) {
|
||||
guardian_rejection_message(self.session.as_ref(), &self.call_id)
|
||||
.await
|
||||
} else {
|
||||
"User denied execution".to_string()
|
||||
};
|
||||
EscalationDecision::deny(Some(message))
|
||||
}
|
||||
ReviewDecision::Abort => {
|
||||
EscalationDecision::deny(Some("User cancelled execution".to_string()))
|
||||
|
||||
Reference in New Issue
Block a user