Skip to content

Commit 60e5006

Browse files
agent: simplify ai agent enforcement config
1 parent 4488111 commit 60e5006

10 files changed

Lines changed: 671 additions & 1523 deletions

File tree

agent/crates/enterprise-utils/src/lib.rs

Lines changed: 197 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -502,45 +502,61 @@ pub mod kernel_version {
502502
}
503503

504504
pub mod ai_agent_enforcement {
505-
use std::sync::Arc;
505+
use std::sync::{Arc, OnceLock, RwLock};
506+
507+
pub const BPF_PATH_LEN: usize = 256;
508+
pub const BPF_RULE_ID_LEN: usize = 64;
509+
pub const BPF_EXEC_MAX_RULES: usize = 256;
510+
pub const BPF_SYSCALL_NAME_LEN: usize = 32;
511+
pub const BPF_SYSCALL_MAX_RULES: usize = 32;
512+
pub const BPF_CMDLINE_PATTERN_MAX_PARTS: usize = 4;
513+
pub const BPF_CMDLINE_PATTERN_PART_LEN: usize = 64;
506514

507515
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
508-
pub enum EnforcementMode {
509-
AuditOnly,
510-
Block,
516+
pub enum EnforcementMechanism {
517+
KprobeOverride,
518+
Lsm,
511519
}
512520

513-
#[derive(Clone, Debug, PartialEq, Eq)]
514-
pub struct ExecRuleInput {
515-
pub id: String,
516-
pub mode: EnforcementMode,
517-
pub exact: Vec<String>,
518-
pub prefix: Vec<String>,
519-
pub suffix: Vec<String>,
520-
pub argv_matches: Vec<ExecArgvMatchInput>,
521-
pub argv_contains_any: Vec<String>,
521+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
522+
pub enum EnforcementAction {
523+
Audit,
524+
Block,
522525
}
523526

524527
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
525-
pub enum ExecArgvMatchOp {
526-
Exact,
527-
Prefix,
528-
Suffix,
528+
pub enum EnforcementMode {
529+
AuditOnly,
530+
Block,
529531
}
530532

531533
#[derive(Clone, Debug, PartialEq, Eq)]
532-
pub struct ExecArgvMatchInput {
533-
pub index: u8,
534-
pub op: ExecArgvMatchOp,
535-
pub value: String,
534+
pub struct AiAgentEnforcementInput {
535+
pub enabled: bool,
536+
pub mechanism: EnforcementMechanism,
537+
pub rules: Vec<EnforcementRuleInput>,
536538
}
537539

538540
#[derive(Clone, Debug, PartialEq, Eq)]
539-
pub struct SyscallRuleInput {
541+
pub struct EnforcementRuleInput {
540542
pub id: String,
541-
pub mode: EnforcementMode,
542-
pub names: Vec<String>,
543-
pub symbols: Vec<String>,
543+
pub action: EnforcementAction,
544+
pub target: EnforcementTargetInput,
545+
}
546+
547+
#[derive(Clone, Debug, PartialEq, Eq)]
548+
pub enum EnforcementTargetInput {
549+
ExecCmdline {
550+
patterns: Vec<String>,
551+
},
552+
ExecPath {
553+
exact: Vec<String>,
554+
prefix: Vec<String>,
555+
suffix: Vec<String>,
556+
},
557+
Syscall {
558+
names: Vec<String>,
559+
},
544560
}
545561

546562
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -558,92 +574,202 @@ pub mod ai_agent_enforcement {
558574
KprobeOverride,
559575
}
560576

577+
#[repr(C)]
578+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
579+
pub struct BpfKprobeExecRuleRecord {
580+
pub rule_index: u32,
581+
pub mode: u8,
582+
pub pattern_flags: u8,
583+
pub part_count: u8,
584+
pub reserved: u8,
585+
pub rule_id: [u8; BPF_RULE_ID_LEN],
586+
pub part_lens: [u16; BPF_CMDLINE_PATTERN_MAX_PARTS],
587+
pub parts: [[u8; BPF_CMDLINE_PATTERN_PART_LEN]; BPF_CMDLINE_PATTERN_MAX_PARTS],
588+
}
589+
590+
#[repr(C)]
591+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
592+
pub struct BpfLsmExecRuleRecord {
593+
pub rule_index: u32,
594+
pub mode: u8,
595+
pub match_type: u8,
596+
pub pattern_len: u16,
597+
pub rule_id: [u8; BPF_RULE_ID_LEN],
598+
pub pattern: [u8; BPF_PATH_LEN],
599+
}
600+
601+
#[repr(C)]
602+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
603+
pub struct BpfSyscallRuleRecord {
604+
pub rule_index: u32,
605+
pub mode: u8,
606+
pub syscall_key: u8,
607+
pub reserved: u16,
608+
pub syscall_id: u32,
609+
pub errno_code: i32,
610+
pub rule_id: [u8; BPF_RULE_ID_LEN],
611+
pub syscall_name: [u8; BPF_SYSCALL_NAME_LEN],
612+
}
613+
614+
impl Default for BpfKprobeExecRuleRecord {
615+
fn default() -> Self {
616+
Self {
617+
rule_index: 0,
618+
mode: 0,
619+
pattern_flags: 0,
620+
part_count: 0,
621+
reserved: 0,
622+
rule_id: [0; BPF_RULE_ID_LEN],
623+
part_lens: [0; BPF_CMDLINE_PATTERN_MAX_PARTS],
624+
parts: [[0; BPF_CMDLINE_PATTERN_PART_LEN]; BPF_CMDLINE_PATTERN_MAX_PARTS],
625+
}
626+
}
627+
}
628+
629+
impl Default for BpfLsmExecRuleRecord {
630+
fn default() -> Self {
631+
Self {
632+
rule_index: 0,
633+
mode: 0,
634+
match_type: 0,
635+
pattern_len: 0,
636+
rule_id: [0; BPF_RULE_ID_LEN],
637+
pattern: [0; BPF_PATH_LEN],
638+
}
639+
}
640+
}
641+
642+
impl Default for BpfSyscallRuleRecord {
643+
fn default() -> Self {
644+
Self {
645+
rule_index: 0,
646+
mode: 0,
647+
syscall_key: 0,
648+
reserved: 0,
649+
syscall_id: 0,
650+
errno_code: 0,
651+
rule_id: [0; BPF_RULE_ID_LEN],
652+
syscall_name: [0; BPF_SYSCALL_NAME_LEN],
653+
}
654+
}
655+
}
656+
561657
#[derive(Clone, Debug, PartialEq, Eq)]
562-
pub struct CompiledExecPolicy {
658+
pub struct CompiledKprobePolicy {
563659
pub epoch: u64,
660+
pub exec_rules: Vec<BpfKprobeExecRuleRecord>,
661+
pub syscall_rules: Vec<BpfSyscallRuleRecord>,
564662
}
565663

566664
#[derive(Clone, Debug, PartialEq, Eq)]
567-
pub struct CompiledSyscallPolicy {
665+
pub struct CompiledLsmPolicy {
568666
pub epoch: u64,
667+
pub exec_rules: Vec<BpfLsmExecRuleRecord>,
569668
}
570669

571-
impl CompiledExecPolicy {
572-
pub fn match_exec(&self, _exec_path: &str, _cmdline: &str) -> Option<PolicyHit> {
670+
static GLOBAL_KPROBE_POLICY: OnceLock<RwLock<Option<Arc<CompiledKprobePolicy>>>> =
671+
OnceLock::new();
672+
static GLOBAL_LSM_POLICY: OnceLock<RwLock<Option<Arc<CompiledLsmPolicy>>>> = OnceLock::new();
673+
674+
impl CompiledKprobePolicy {
675+
pub fn exec_records(&self) -> &[BpfKprobeExecRuleRecord] {
676+
&self.exec_rules
677+
}
678+
679+
pub fn syscall_records(&self) -> &[BpfSyscallRuleRecord] {
680+
&self.syscall_rules
681+
}
682+
683+
pub fn match_cmdline(&self, _cmdline: &str) -> Option<PolicyHit> {
573684
None
574685
}
575686

576687
pub fn sync_to_bpf_maps(
577688
&self,
578-
_exec_rules_fd: i32,
579689
_policy_epoch_fd: i32,
580-
_max_records: usize,
690+
_kprobe_exec_rules_fd: i32,
691+
_syscall_rules_fd: i32,
581692
) -> Result<(), String> {
582693
Ok(())
583694
}
584695
}
585696

586-
impl CompiledSyscallPolicy {
587-
pub fn to_bpf_records(&self) -> Vec<BpfSyscallRuleRecord> {
588-
vec![]
697+
impl CompiledLsmPolicy {
698+
pub fn exec_records(&self) -> &[BpfLsmExecRuleRecord] {
699+
&self.exec_rules
700+
}
701+
702+
pub fn match_exec_path(&self, _exec_path: &str) -> Option<PolicyHit> {
703+
None
589704
}
590705

591706
pub fn sync_to_bpf_maps(
592707
&self,
593-
_syscall_rules_fd: i32,
594708
_policy_epoch_fd: i32,
595-
_max_records: usize,
709+
_lsm_exec_rules_fd: i32,
596710
) -> Result<(), String> {
597711
Ok(())
598712
}
599713
}
600714

601-
#[repr(C)]
602-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
603-
pub struct BpfSyscallRuleRecord {
604-
pub rule_index: u32,
605-
pub mode: u8,
606-
pub syscall_key: u8,
607-
pub reserved: u16,
608-
pub syscall_id: u32,
609-
pub errno_code: i32,
610-
pub rule_id: [u8; 64],
611-
pub syscall_name: [u8; 32],
715+
pub fn clear_kprobe_bpf_maps(
716+
_kprobe_exec_rules_fd: i32,
717+
_syscall_rules_fd: i32,
718+
) -> Result<(), String> {
719+
Ok(())
612720
}
613721

614-
impl Default for BpfSyscallRuleRecord {
615-
fn default() -> Self {
616-
Self {
617-
rule_index: 0,
618-
mode: 0,
619-
syscall_key: 0,
620-
reserved: 0,
621-
syscall_id: 0,
622-
errno_code: 0,
623-
rule_id: [0; 64],
624-
syscall_name: [0; 32],
625-
}
626-
}
722+
pub fn clear_lsm_bpf_maps(_lsm_exec_rules_fd: i32) -> Result<(), String> {
723+
Ok(())
724+
}
725+
726+
pub fn compile_kprobe_policy(
727+
_input: &AiAgentEnforcementInput,
728+
) -> Result<CompiledKprobePolicy, String> {
729+
Ok(CompiledKprobePolicy {
730+
epoch: 0,
731+
exec_rules: Vec::new(),
732+
syscall_rules: Vec::new(),
733+
})
627734
}
628735

629-
pub fn compile_exec_rules(_rules: &[ExecRuleInput]) -> Result<CompiledExecPolicy, String> {
630-
Ok(CompiledExecPolicy { epoch: 0 })
736+
pub fn compile_lsm_policy(
737+
_input: &AiAgentEnforcementInput,
738+
) -> Result<CompiledLsmPolicy, String> {
739+
Ok(CompiledLsmPolicy {
740+
epoch: 0,
741+
exec_rules: Vec::new(),
742+
})
631743
}
632744

633-
pub fn compile_syscall_rules(
634-
_rules: &[SyscallRuleInput],
635-
) -> Result<CompiledSyscallPolicy, String> {
636-
Ok(CompiledSyscallPolicy { epoch: 0 })
745+
pub fn set_global_kprobe_policy(policy: Option<CompiledKprobePolicy>) {
746+
*GLOBAL_KPROBE_POLICY
747+
.get_or_init(|| RwLock::new(None))
748+
.write()
749+
.unwrap() = policy.map(Arc::new);
637750
}
638751

639-
pub fn syscall_override_symbols(_syscall_key: u8) -> &'static [&'static str] {
640-
&[]
752+
pub fn global_kprobe_policy() -> Option<Arc<CompiledKprobePolicy>> {
753+
GLOBAL_KPROBE_POLICY
754+
.get_or_init(|| RwLock::new(None))
755+
.read()
756+
.unwrap()
757+
.clone()
641758
}
642759

643-
pub fn set_global_exec_policy(_policy: Option<CompiledExecPolicy>) {}
760+
pub fn set_global_lsm_policy(policy: Option<CompiledLsmPolicy>) {
761+
*GLOBAL_LSM_POLICY
762+
.get_or_init(|| RwLock::new(None))
763+
.write()
764+
.unwrap() = policy.map(Arc::new);
765+
}
644766

645-
pub fn global_exec_policy() -> Option<Arc<CompiledExecPolicy>> {
646-
None
767+
pub fn global_lsm_policy() -> Option<Arc<CompiledLsmPolicy>> {
768+
GLOBAL_LSM_POLICY
769+
.get_or_init(|| RwLock::new(None))
770+
.read()
771+
.unwrap()
772+
.clone()
647773
}
648774
}
649775

0 commit comments

Comments
 (0)