Skip to content

Commit 682bca8

Browse files
authored
fix(ci): configure security audit exceptions and remove Ollama (#560)
* fix(ci): configure RUSTSEC advisory exceptions for security audit Add .cargo/audit.toml to centralize security advisory exceptions: - RUSTSEC-2025-0118: wasmtime v29 shared memory API (low severity) - RUSTSEC-2025-0046: wasmtime v29 fd_renumber panic (low severity) - RUSTSEC-2026-0006: wasmtime v29 f64.copysign segfault (medium) - RUSTSEC-2025-0057: fxhash unmaintained (transitive via wasmtime) - RUSTSEC-2024-0436: paste unmaintained (transitive via wasmtime) - RUSTSEC-2026-0002: lru unsound iteration (transitive via ratatui) Remove continue-on-error from security audit CI job so it properly fails on new unacknowledged vulnerabilities. * refactor(cli): remove Ollama provider from models command Remove all Ollama model definitions and related tests from cortex-cli. This simplifies the codebase by removing support for the local Ollama provider, focusing on cloud-based model providers.
1 parent ea52148 commit 682bca8

3 files changed

Lines changed: 50 additions & 85 deletions

File tree

.cargo/audit.toml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# audit.toml - cargo-audit configuration for security audit
2+
# https://github.com/rustsec/rustsec/blob/main/cargo-audit/audit.toml.example
3+
#
4+
# This file consolidates all RUSTSEC advisory exceptions in one place.
5+
# These are known vulnerabilities in transitive dependencies that cannot be
6+
# easily upgraded, typically due to deep dependency chains (e.g., wasmtime).
7+
8+
[advisories]
9+
# These advisories are either:
10+
# 1. False positives for our use case
11+
# 2. In transitive dependencies we cannot easily update
12+
# 3. Low severity issues being tracked for future resolution
13+
#
14+
# All wasmtime issues are due to using v29.0.1 via cortex-plugins.
15+
# Upgrading wasmtime is a significant effort tracked separately.
16+
ignore = [
17+
# wasmtime v29.0.1 - Unsound API access to WebAssembly shared linear memory
18+
# Severity: low (1.8)
19+
# We don't expose raw WebAssembly memory APIs to untrusted code
20+
"RUSTSEC-2025-0118",
21+
22+
# wasmtime v29.0.1 - Host panic with fd_renumber WASIp1 function
23+
# Severity: low (3.3)
24+
# Limited exposure - panic doesn't compromise security
25+
"RUSTSEC-2025-0046",
26+
27+
# wasmtime v29.0.1 - Segfault with f64.copysign operator on x86-64
28+
# Severity: medium (4.1)
29+
# Tracked for wasmtime upgrade
30+
"RUSTSEC-2026-0006",
31+
32+
# fxhash v0.2.1 - unmaintained
33+
# Transitive dependency via selectors/scraper and wasmtime
34+
"RUSTSEC-2025-0057",
35+
36+
# paste v1.0.15 - unmaintained
37+
# Transitive dependency via wasmtime and ratatui
38+
"RUSTSEC-2024-0436",
39+
40+
# lru v0.12.5 - unsound IterMut implementation
41+
# Transitive dependency via ratatui
42+
# We don't use LRU cache iteration mutably
43+
"RUSTSEC-2026-0002",
44+
]
45+
46+
# Warn on informational advisories (unmaintained, unsound, etc.)
47+
informational_warnings = ["unmaintained", "unsound", "notice"]

.github/workflows/ci.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,6 @@ jobs:
195195
audit:
196196
name: Security Audit
197197
runs-on: blacksmith-4vcpu-ubuntu-2404
198-
# Security audit is informational - don't block CI on known vulnerabilities
199-
# Issues are automatically created for any vulnerabilities found
200-
continue-on-error: true
201198
permissions:
202199
contents: read
203200
issues: write
@@ -210,6 +207,8 @@ jobs:
210207
- name: Install Rust stable
211208
uses: dtolnay/rust-toolchain@stable
212209

210+
# Known RUSTSEC advisories are configured in .cargo/audit.toml
211+
# See that file for detailed explanations of each exception
213212
- uses: actions-rust-lang/audit@v1
214213
name: Audit Rust Dependencies
215214

src/cortex-cli/src/models_cmd.rs

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -411,63 +411,6 @@ fn get_available_models() -> Vec<ModelInfo> {
411411
input_cost_per_million: Some(0.55),
412412
output_cost_per_million: Some(2.19),
413413
},
414-
// Ollama models (local)
415-
ModelInfo {
416-
id: "llama3.2".to_string(),
417-
name: "Llama 3.2".to_string(),
418-
provider: "ollama".to_string(),
419-
capabilities: ModelCapabilities {
420-
vision: false,
421-
tools: true,
422-
parallel_tools: false,
423-
streaming: true,
424-
json_mode: true,
425-
},
426-
input_cost_per_million: None, // Local model, no API cost
427-
output_cost_per_million: None,
428-
},
429-
ModelInfo {
430-
id: "llama3.2:1b".to_string(),
431-
name: "Llama 3.2 1B".to_string(),
432-
provider: "ollama".to_string(),
433-
capabilities: ModelCapabilities {
434-
vision: false,
435-
tools: true,
436-
parallel_tools: false,
437-
streaming: true,
438-
json_mode: true,
439-
},
440-
input_cost_per_million: None,
441-
output_cost_per_million: None,
442-
},
443-
ModelInfo {
444-
id: "codellama".to_string(),
445-
name: "Code Llama".to_string(),
446-
provider: "ollama".to_string(),
447-
capabilities: ModelCapabilities {
448-
vision: false,
449-
tools: false,
450-
parallel_tools: false,
451-
streaming: true,
452-
json_mode: false,
453-
},
454-
input_cost_per_million: None,
455-
output_cost_per_million: None,
456-
},
457-
ModelInfo {
458-
id: "mistral".to_string(),
459-
name: "Mistral 7B".to_string(),
460-
provider: "ollama".to_string(),
461-
capabilities: ModelCapabilities {
462-
vision: false,
463-
tools: true,
464-
parallel_tools: false,
465-
streaming: true,
466-
json_mode: true,
467-
},
468-
input_cost_per_million: None,
469-
output_cost_per_million: None,
470-
},
471414
]
472415
}
473416

@@ -799,7 +742,7 @@ mod tests {
799742
let model = ModelInfo {
800743
id: "local-model".to_string(),
801744
name: "Local Model".to_string(),
802-
provider: "ollama".to_string(),
745+
provider: "local".to_string(),
803746
capabilities: ModelCapabilities::default(),
804747
input_cost_per_million: None,
805748
output_cost_per_million: None,
@@ -881,30 +824,6 @@ mod tests {
881824
assert!(!google_models.is_empty(), "Should have Google models");
882825
}
883826

884-
#[test]
885-
fn test_get_available_models_has_ollama() {
886-
let models = get_available_models();
887-
let ollama_models: Vec<_> = models.iter().filter(|m| m.provider == "ollama").collect();
888-
assert!(!ollama_models.is_empty(), "Should have Ollama models");
889-
}
890-
891-
#[test]
892-
fn test_get_available_models_ollama_has_no_cost() {
893-
let models = get_available_models();
894-
for model in models.iter().filter(|m| m.provider == "ollama") {
895-
assert!(
896-
model.input_cost_per_million.is_none(),
897-
"Ollama model {} should have no input cost",
898-
model.id
899-
);
900-
assert!(
901-
model.output_cost_per_million.is_none(),
902-
"Ollama model {} should have no output cost",
903-
model.id
904-
);
905-
}
906-
}
907-
908827
#[test]
909828
fn test_get_available_models_unique_ids() {
910829
let models = get_available_models();

0 commit comments

Comments
 (0)