raxit-core 0.1.2

Core security scanning engine for AI agent applications
Documentation
//! RAXIT Core - Runtime AI eXecution Integrity & Trust
//!
//! Core security scanning engine for AI agent applications built with Rust.
//! Provides high-performance static analysis, security vulnerability detection,
//! and compliance validation for AI agent codebases.
//!
//! ## Features
//!
//! - **Fast AST Parsing**: Uses tree-sitter for high-performance Python code analysis
//! - **Framework Detection**: Automatically detects PydanticAI, LangGraph, CrewAI, AutoGen, Swarm
//! - **Security Analysis**: 4 built-in analyzers for comprehensive security coverage
//! - **Incremental Scanning**: File-level caching for fast re-scans
//! - **Multi-format Output**: JSON and YAML serialization support
//!
//! ## Security Analyzers
//!
//! 1. **Trust Boundary Analyzer** - Meta's "Rule of Two" for unsafe component detection
//! 2. **Secret Detection** - Find exposed API keys, credentials, and sensitive data
//! 3. **Memory Detection** - Track vector stores, databases, and persistence layers
//! 4. **Network Detection** - Identify HTTP calls, API clients, and external communications
//! 5. **Data Provenance** - CaMeL-style taint analysis for data flow tracking
//!
//! ## Quick Start
//!
//! ```rust,no_run
//! use raxit_core::{scan, ScanConfig};
//!
//! // Scan a directory for AI agent code
//! let config = ScanConfig::default()
//!     .with_path("./my-agent-project")
//!     .with_format("yaml");
//!
//! let result = scan(config)?;
//!
//! // Access discovered assets
//! println!("Found {} agents", result.agents.len());
//! println!("Found {} tools", result.tools.len());
//! println!("Secret findings: {}", result.secret_findings.len());
//!
//! // Serialize to YAML
//! println!("{}", result.to_yaml()?);
//! # Ok::<(), raxit_core::RaxitError>(())
//! ```
//!
//! ## Advanced Usage
//!
//! ```rust,no_run
//! use raxit_core::{scan, ScanConfig};
//!
//! // Create a custom configuration
//! let config = ScanConfig::new("./agents")
//!     .with_format("json");
//!
//! // Run scan
//! let result = scan(config)?;
//!
//! // Access specific findings
//! for finding in &result.secret_findings {
//!     println!("Secret detected: {} (severity: {})",
//!         finding.secret_type, finding.severity);
//! }
//!
//! // Check for critical issues
//! let critical_secrets = result.secret_findings
//!     .iter()
//!     .filter(|s| s.severity == "critical")
//!     .count();
//!
//! let critical_flows = result.provenance_findings
//!     .iter()
//!     .filter(|p| p.severity == "critical")
//!     .count();
//!
//! println!("Found {} critical security issues", critical_secrets + critical_flows);
//! # Ok::<(), raxit_core::RaxitError>(())
//! ```

pub mod analyzers;
pub mod ast;
pub mod cache;
pub mod config;
pub mod error;
pub mod extractors;
pub mod scanner;
pub mod schema;

// Re-export main types
pub use config::ScanConfig;
pub use error::{RaxitError, Result};
pub use scanner::Scanner;
pub use schema::{AgentAssets, ScanResult};

/// Main entry point for scanning AI agent codebases
///
/// # Example
///
/// ```rust,no_run
/// use raxit_core::{scan, ScanConfig};
///
/// let config = ScanConfig::default()
///     .with_path("./my-agent-project")
///     .with_format("yaml");
///
/// let result = scan(config)?;
/// println!("{}", result.to_yaml()?);
/// # Ok::<(), raxit_core::RaxitError>(())
/// ```
pub fn scan(config: ScanConfig) -> Result<ScanResult> {
    tracing::info!("Starting RAXIT scan with config: {:?}", config);

    // Create scanner instance
    let mut scanner = Scanner::new(config)?;

    // Execute scan pipeline:
    // 1. File discovery (with incremental scanning)
    let (files, files_skipped) = scanner.discover_files()?;
    tracing::debug!(
        "Discovered {} files ({} skipped)",
        files.len(),
        files_skipped
    );

    // 2. Framework detection
    let frameworks = scanner.detect_frameworks(&files)?;
    tracing::debug!("Detected frameworks: {:?}", frameworks);

    // 3. Parallel extraction (using Rayon)
    let results = scanner.extract_all(&files, &frameworks, files_skipped)?;
    tracing::debug!("Extracted {} assets", results.agents.len());

    // 4. Cross-file analysis
    let _graph = scanner.build_call_graph(&results)?;
    tracing::debug!("Built call graph");

    // 5. Trust boundary analysis
    let boundaries = scanner.analyze_trust_boundaries(&results)?;
    tracing::debug!("Analyzed {} trust boundaries", boundaries.len());

    // 6. Schema generation
    let schema = scanner.generate_schema(&results, &boundaries)?;
    tracing::info!(
        "Scan complete: {} agents, {} tools",
        schema.agents.len(),
        schema.tools.len()
    );

    Ok(schema)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_scan_api() {
        // Placeholder test - will be implemented with actual test fixtures
        let _config = ScanConfig::default().with_path("./test-fixtures/simple-agent");

        // This will fail until we implement the scanner
        // let result = scan(config);
        // assert!(result.is_ok());
    }
}