Skip to main content

Crate skill_veil_core

Crate skill_veil_core 

Source
Expand description

skill-veil-core: Behavioral & Supply-Chain Security Analysis for Agent Skills

This crate provides the core analysis engine for detecting security risks in agent skills based on Markdown and associated code.

§Overview

skill-veil-core analyzes agent skill files (typically Markdown) for security risks such as:

  • Remote code execution patterns (curl | bash, PowerShell IEX, etc.)
  • Supply chain risks (untrusted sources, suspicious packages)
  • Credential exposure
  • Privilege escalation attempts
  • Data exfiltration indicators

§Quick Start

use skill_veil_core::scanner::Scanner;
use skill_veil_core::findings::Severity;

// Create a scanner with default rules
let scanner = Scanner::new().unwrap();

// Scan content directly (for demo purposes)
let result = scanner.scan_file(file.path()).unwrap();

// Check results
println!("Found {} findings", result.findings.len());
if result.has_severity(Severity::Critical) {
    println!("Critical issues detected!");
}

§Architecture

The crate follows a hexagonal (ports and adapters) architecture:

§Modules

  • scanner - High-level scanning orchestration
  • rules - Rule engine and rule definitions
  • findings - Finding and severity types
  • analyzer - Document parsing and analysis
  • policy - Policy generation (SHIELD.md, SARIF, JSON)
  • ports - Trait definitions for dependency injection
  • adapters - Default implementations
  • services - File discovery and filtering services

Re-exports§

pub use analyzer::AgentExtensionKind;
pub use analyzer::ArtifactAssessment;
pub use analyzer::ArtifactClassification;
pub use analyzer::ArtifactIdentitySource;
pub use analyzer::CodeBlock;
pub use analyzer::Section;
pub use analyzer::SkillDocument;
pub use analyzer::StructuralSignals;
pub use analyzer::StructuralValidity;
pub use benchmark::evaluate_gold_corpus;
pub use benchmark::AttackFamilyMetrics;
pub use benchmark::BenchmarkError;
pub use benchmark::BenchmarkHistory;
pub use benchmark::BenchmarkHistoryEntry;
pub use benchmark::CalibrationBucket;
pub use benchmark::CalibrationSummary;
pub use benchmark::CorpusCoverage;
pub use benchmark::CorpusEvaluation;
pub use benchmark::CorpusManifest;
pub use benchmark::CoverageBucket;
pub use benchmark::DeduplicationMetrics;
pub use benchmark::GoldCorpusManifest;
pub use benchmark::GoldSample;
pub use benchmark::LabeledSample;
pub use benchmark::RegressionMetrics;
pub use benchmark::SampleEvaluation;
pub use benchmark::SampleLabel;
pub use benchmark::ThresholdRecommendation;
pub use findings::artifact_scope_for_kind;
pub use findings::signal_class_for;
pub use findings::ActionTrigger;
pub use findings::ArtifactKind;
pub use findings::ArtifactScope;
pub use findings::BlastRadiusLevel;
pub use findings::BlastRadiusSummary;
pub use findings::ConsensusClass;
pub use findings::ConsensusDiscrepancy;
pub use findings::DeclaredPermission;
pub use findings::DeduplicationSummary;
pub use findings::EvidenceKind;
pub use findings::Finding;
pub use findings::FindingSummary;
pub use findings::HygieneSummary;
pub use findings::MatchTarget;
pub use findings::OperationalContext;
pub use findings::PackageHealth;
pub use findings::PackageVerdictReport;
pub use findings::ProviderVote;
pub use findings::RecommendedAction;
pub use findings::RiskFactor;
pub use findings::RootCauseGroup;
pub use findings::Severity;
pub use findings::SeverityCounts;
pub use findings::SignalClass;
pub use findings::ThreatCategory;
pub use findings::Verdict;
pub use findings::VerdictReason;
pub use findings::RISK_THRESHOLD_BLOCK;
pub use ioc_extraction::ExtractedIocs;
pub use ioc_extraction::FileHash;
pub use policy::adjust_confidence;
pub use policy::apply_baseline;
pub use policy::apply_policy_overrides;
pub use policy::apply_policy_overrides_with_audit;
pub use policy::apply_waivers;
pub use policy::baseline_from_reports;
pub use policy::count_baseline_matches;
pub use policy::diff_reports;
pub use policy::diff_reports_with_policy_state;
pub use policy::empty_sarif_report;
pub use policy::finding_fingerprint;
pub use policy::learned_allowlist;
pub use policy::learned_confidence_adjustments;
pub use policy::load_baseline;
pub use policy::load_disposition_overlay;
pub use policy::load_policy;
pub use policy::load_waivers;
pub use policy::validate_policy;
pub use policy::validate_waivers;
pub use policy::AppliedPolicyOverride;
pub use policy::BaselineEntry;
pub use policy::BaselineFile;
pub use policy::ConfiguredProfile;
pub use policy::ContextActionOverride;
pub use policy::ContextPolicy;
pub use policy::DiffEntry;
pub use policy::DiffReport;
pub use policy::Disposition;
pub use policy::DispositionOverlay;
pub use policy::DispositionRecord;
pub use policy::JsonReport;
pub use policy::PolicyAudit;
pub use policy::PolicyFile;
pub use policy::PolicyGenerator;
pub use policy::PolicyOverride;
pub use policy::PolicyProfile;
pub use policy::PolicyProfiles;
pub use policy::ShieldPolicy;
pub use policy::SuppressionSummary;
pub use policy::WaiverEntry;
pub use policy::WaiverFile;
pub use policy::POLICY_AUDIT_PRECEDENCE;
pub use policy::POLICY_SCHEMA_VERSION;
pub use rules::default_external_rule_dirs;
pub use rules::is_supported_rule_pack_schema;
pub use rules::parse_rules_file;
pub use rules::IocFeedFile;
pub use rules::Rule;
pub use rules::RuleCondition;
pub use rules::RuleEngine;
pub use rules::RulePackFile;
pub use rules::RulePackKind;
pub use rules::RulePackMetadata;
pub use rules::RULE_PACK_SCHEMA_VERSION;
pub use scanner::ArtifactMetadata;
pub use scanner::DefaultScanner;
pub use scanner::PackageScanResult;
pub use scanner::ScanError;
pub use scanner::ScanErrorEntry;
pub use scanner::ScanOptions;
pub use scanner::ScanResult;
pub use scanner::ScanTargetMode;
pub use scanner::Scanner;
pub use ports::DecodedText;
pub use ports::FileContent;
pub use ports::FileMeta;
pub use ports::FileSystemProvider;
pub use ports::MarkdownParser;
pub use ports::PatternMatcher;
pub use adapters::PulldownMarkdownParser;
pub use adapters::RegexPatternMatcher;
pub use adapters::StdFileSystemProvider;
pub use artifact_graph::ArtifactCapability;
pub use artifact_graph::ArtifactCapabilityFact;
pub use artifact_graph::ArtifactCapabilitySource;
pub use artifact_graph::ArtifactEdge;
pub use artifact_graph::ArtifactGraph;
pub use artifact_graph::ArtifactNode;
pub use artifact_graph::ArtifactRelation;
pub use artifact_graph::EndpointKind;

Modules§

adapters
Infrastructure adapters implementing port traits
analyzer
Markdown analyzer for SKILL.md files
artifact_graph
Artifact graph for representing relationships between scanned assets.
benchmark
Benchmark and corpus evaluation helpers.
findings
Finding data structures for security analysis results
ioc_extraction
Pure-offline extraction of URL / domain / IP / file-hash indicators from skill artifacts. The output feeds downstream enrichment tooling (e.g. the CLI’s VT lookup) without adding any runtime dependency on the network from inside the core scanner.
nova
NOVA (Prompt Pattern Matching) integration.
policy
Policy generation and stable public policy contract.
ports
Port traits for dependency inversion. The domain layer depends only on these traits; infrastructure implementations live in adapters and are wired in at construction time.
rules
Rule engine for detecting security signals in skills
scanner
Scanner module for orchestrating skill analysis.
services
Service layer for skill-veil operations

Macros§

lazy_pattern

Functions§

artifact_kind_for_path
derive_package_id
Recover a SHA-256 package id from any ancestor directory name.
is_conclusive_single_rule_id
true when rule_id is one of the curated zero-FP rules whose single Block-strength MaliciousBehavior finding escalates a package to Malicious on its own (the CONCLUSIVE_SINGLE_RULE_IDS set). Exposed so an out-of-crate adjudication gate can ask “would this already be conclusively malicious?” without duplicating — and drifting from — the curated list.
path_stays_within_base
Return true when candidate resolves inside base_dir after walking .. components lexically. Absolute paths are accepted only when they share the prefix with base_dir; otherwise the caller should reject them at an earlier guard (see extract_references for the recommended Path::is_absolute() pre-check).