fix(permissions): validate network access flow
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
//! System-level agent permissions, distinct from filesystem/bash permissions.
|
||||
//!
|
||||
//! This model stores the policy the user wants IdeA to apply. It does not claim
|
||||
//! that an external assistant runtime can be elevated live: resolution combines
|
||||
//! the wanted policy with a read-only runtime probe.
|
||||
//! that an external assistant runtime can be elevated live: resolution exposes
|
||||
//! the wanted policy separately from the observed runtime state.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -235,11 +235,22 @@ pub struct RuntimePermissionSnapshot {
|
||||
pub effective_network: NetworkPolicy,
|
||||
/// Runtime lock details.
|
||||
pub runtime_lock: RuntimeLock,
|
||||
/// Control state exposed to the UI.
|
||||
pub control: SystemPermissionControl,
|
||||
/// Runtime control state, distinct from editing the persisted wanted policy.
|
||||
pub runtime_control: SystemPermissionControl,
|
||||
}
|
||||
|
||||
impl RuntimePermissionSnapshot {
|
||||
/// Snapshot for an agent with no known active runtime lock.
|
||||
#[must_use]
|
||||
pub fn unobserved() -> Self {
|
||||
const REASON: &str = "No active runtime network permission state is currently observed.";
|
||||
Self {
|
||||
effective_network: NetworkPolicy::Deny,
|
||||
runtime_lock: RuntimeLock::none(),
|
||||
runtime_control: SystemPermissionControl::read_only(REASON),
|
||||
}
|
||||
}
|
||||
|
||||
/// Snapshot for a runtime that IdeA cannot inspect or elevate.
|
||||
#[must_use]
|
||||
pub fn locked_uninspectable() -> Self {
|
||||
@ -248,7 +259,7 @@ impl RuntimePermissionSnapshot {
|
||||
Self {
|
||||
effective_network: NetworkPolicy::Deny,
|
||||
runtime_lock: RuntimeLock::locked("external-runtime", REASON),
|
||||
control: SystemPermissionControl::read_only(REASON),
|
||||
runtime_control: SystemPermissionControl::read_only(REASON),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,8 +274,10 @@ pub struct ResolvedAgentSystemPermissions {
|
||||
pub effective: NetworkPolicy,
|
||||
/// Runtime lock state.
|
||||
pub runtime_lock: RuntimeLock,
|
||||
/// Whether the UI can edit the policy live.
|
||||
/// Whether the UI can edit the persisted wanted policy.
|
||||
pub control: SystemPermissionControl,
|
||||
/// Whether IdeA can inspect or change the active runtime state.
|
||||
pub runtime_control: SystemPermissionControl,
|
||||
}
|
||||
|
||||
/// Resolves wanted system permissions against the runtime snapshot.
|
||||
@ -283,7 +296,8 @@ pub fn resolve_agent_system_permissions(
|
||||
wanted,
|
||||
effective,
|
||||
runtime_lock: runtime.runtime_lock,
|
||||
control: runtime.control,
|
||||
control: SystemPermissionControl::editable(),
|
||||
runtime_control: runtime.runtime_control,
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,7 +320,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn locked_runtime_controls_effective_policy_without_fake_allow() {
|
||||
fn locked_runtime_controls_effective_policy_without_making_wanted_read_only() {
|
||||
let agent = AgentId::new_random();
|
||||
let doc = ProjectSystemPermissions::default();
|
||||
|
||||
@ -319,6 +333,31 @@ mod tests {
|
||||
assert_eq!(resolved.wanted, None);
|
||||
assert_eq!(resolved.effective, NetworkPolicy::Deny);
|
||||
assert_eq!(resolved.runtime_lock.state, RuntimeLockState::Locked);
|
||||
assert_eq!(resolved.control.mode, SystemPermissionControlMode::ReadOnly);
|
||||
assert_eq!(resolved.control.mode, SystemPermissionControlMode::Editable);
|
||||
assert_eq!(
|
||||
resolved.runtime_control.mode,
|
||||
SystemPermissionControlMode::ReadOnly
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unobserved_runtime_has_no_active_lock_and_preserves_wanted_effective_policy() {
|
||||
let agent = AgentId::new_random();
|
||||
let doc = ProjectSystemPermissions::new(
|
||||
Some(SystemPermissionSet::new(Some(NetworkPolicy::Allow))),
|
||||
vec![],
|
||||
);
|
||||
|
||||
let resolved =
|
||||
resolve_agent_system_permissions(&doc, agent, RuntimePermissionSnapshot::unobserved());
|
||||
|
||||
assert_eq!(resolved.wanted, Some(NetworkPolicy::Allow));
|
||||
assert_eq!(resolved.effective, NetworkPolicy::Allow);
|
||||
assert_eq!(resolved.runtime_lock.state, RuntimeLockState::None);
|
||||
assert_eq!(resolved.control.mode, SystemPermissionControlMode::Editable);
|
||||
assert_eq!(
|
||||
resolved.runtime_control.mode,
|
||||
SystemPermissionControlMode::ReadOnly
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user