feat(permissions): LP4-4 — enforcement Landlock sur le chemin structuré
Étend l'enforcement OS au chemin structuré (sessions Claude/Codex mode JSON), jusqu'ici seulement advisory. Approche validée par l'Architecte : transposer la technique du PTY plutôt qu'un pre_exec (rejeté — landlock alloue, deadlock malloc post-fork en process multithreadé). Mécanique (cfg(target_os=linux)) : run_turn_sandboxed/drain_sandboxed exécutent enforce(plan) sur un thread jetable AVANT le spawn std, puis std::process::spawn depuis ce thread ; l'enfant hérite le domaine Landlock via les credentials de la tâche (garanti à travers fork/clone/execve, y compris posix_spawn — pas de pre_exec nécessaire, forbid(unsafe_code) préservé). Fail-closed sur Err d'enforce (aucun child). Timeout sous sandbox : oneshot killer + tokio::time::timeout → kill → EOF → reap (pas de zombie/thread bloqué). Chemin non-sandboxé (plan None / pas d'enforcer / non-Linux) = drain async tokio inchangé. Contrat : SpawnLine.sandbox ; AgentSessionFactory::start(.., sandbox) ; StructuredSessionFactory::with_sandbox_enforcer (jumeau du PTY) ; plan calculé en step 5d de lifecycle relayé à launch_structured ; default_enforcer() injecté au composition root. Tests : 7 invariants e2e (parité, companion négatif, fail-closed, no-op natif, confinement de l'irréversibilité entre tours, timeout, resume préservé) — zéro token (sh/FakeCli). 80 suites vertes, 0 failed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -340,6 +340,7 @@ impl AgentSessionFactory for FakeFactory {
|
||||
_ctx: &PreparedContext,
|
||||
_cwd: &ProjectPath,
|
||||
_session: &SessionPlan,
|
||||
_sandbox: Option<&domain::sandbox::SandboxPlan>,
|
||||
) -> Result<Arc<dyn AgentSession>, AgentSessionError> {
|
||||
Ok(Arc::new(FakeSession {
|
||||
id: SessionId::from_uuid(Uuid::from_u128(7)),
|
||||
@ -394,7 +395,7 @@ async fn fake_factory_supports_only_structured_profiles_and_starts() {
|
||||
};
|
||||
let cwd = ProjectPath::new("/srv/run").unwrap();
|
||||
let session = factory
|
||||
.start(&structured, &ctx, &cwd, &SessionPlan::None)
|
||||
.start(&structured, &ctx, &cwd, &SessionPlan::None, None)
|
||||
.await
|
||||
.expect("factory starts a session");
|
||||
assert_eq!(session.id(), SessionId::from_uuid(Uuid::from_u128(7)));
|
||||
|
||||
Reference in New Issue
Block a user