Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLA_SIGNATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ julien-boost - Julien Champoux
GuillaumeRoss - Guillaume Ross
c0tton-fluff - Michal Ambrozkiewicz
tveronezi - Thiago Veronezi
stlef14 - Stephan Lefrancois
stlef14 - Stephan Lefrancois
smithjw - James Smith
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ Each probe declares its scope (user/system), paths touched, env vars read, and r
| `jetbrains` | JetBrains IDE configuration | JetBrains IDE workspace files and configuration for embedded secrets |
| `gh` | GitHub CLI | GitHub CLI authentication tokens and configuration |
| `ai_cli` | AI CLI tools | Credential files and chat logs for Gemini, Codex, Claude, and OpenCode |
| `mise` | [`mise`](https://mise.jdx.dev) configuration files | Plaintext secrets in `[env]` tables, `[[env]]` array-of-tables, and `[tasks.*]` env/run blocks |
| `mise_tasks` | `mise` file-task scripts | Plaintext secrets in script bodies and in `#MISE env={...}` / `# [MISE] env=` / `//MISE env=` header directives |

### Current Detectors

Expand Down
26 changes: 26 additions & 0 deletions bagel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,32 @@ probes:
# max_file_size: maximum bytes to read from a chat file before skipping it.
# Prevents scan hangs on large conversation histories. Default: 1048576 (1 MB).
# max_file_size: 1048576
mise:
# Scans mise (https://mise.jdx.dev) configuration files for plaintext
# secrets in [env] tables AND in inline [tasks.*] env/run blocks.
# Covers global config plus the mise.toml family (mise.toml, .mise.toml,
# mise.local.toml, env-specific variants like mise.production.toml, idiomatic
# dir forms, and legacy .rtx.toml). The `redact = true` table form is reported
# as a finding (only suppresses output; the secret is still plaintext on disk).
enabled: true
flags:
# max_file_size: maximum bytes to read from a mise config before
# skipping it. Mise configs are typically <100KB. Default: 4194304 (4 MB).
# max_file_size: 4194304
mise_tasks:
# Scans mise file-task scripts under mise-tasks/, .mise-tasks/,
# mise/tasks/, .mise/tasks/, and .config/mise/tasks/ (at up to 3
# levels of sub-directory depth). Each script is line-scanned for
# plaintext secrets and its `#MISE env={...}` (or `# [MISE] env=`,
# `//MISE env=`) header directives are decoded as inline TOML and
# scanned the same way the config probe handles [env] tables.
# Findings are tagged `mise_task_file: true` and carry the derived
# task name (e.g. `test:units` for `mise-tasks/test/units`).
enabled: true
flags:
# max_file_size: maximum bytes to read from a mise file-task
# script before skipping it. Default: 4194304 (4 MB).
# max_file_size: 4194304
privacy:
redact_paths: []
exclude_env_prefixes: []
Expand Down
13 changes: 13 additions & 0 deletions cmd/bagel/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,5 +217,18 @@ func initializeProbes(cfg *models.Config) []probe.Probe {
probes = append(probes, probe.NewContextProbe(cfg.Probes.AIContext, registry))
}

// mise probe - plaintext secrets in mise.toml [env] tables and
// inline [tasks.*] blocks.
if cfg.Probes.Mise.Enabled {
probes = append(probes, probe.NewMiseProbe(cfg.Probes.Mise, registry))
}

// mise_tasks probe - plaintext secrets in file-task scripts
// under mise-tasks/, .mise-tasks/, mise/tasks/, .mise/tasks/,
// and .config/mise/tasks/.
if cfg.Probes.MiseTasks.Enabled {
probes = append(probes, probe.NewMiseTasksProbe(cfg.Probes.MiseTasks, registry))
}

return probes
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/google/uuid v1.6.0
github.com/mattn/go-isatty v0.0.20
github.com/olekukonko/tablewriter v1.1.0
github.com/pelletier/go-toml/v2 v2.2.4
github.com/rs/zerolog v1.34.0
github.com/schollz/progressbar/v3 v3.19.0
github.com/spf13/cobra v1.10.1
Expand All @@ -29,7 +30,6 @@ require (
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.0.9 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
Expand Down
75 changes: 75 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ func setDefaults(v *viper.Viper) {
v.SetDefault("probes.iac.enabled", true)
v.SetDefault("probes.ai_mcp.enabled", true)
v.SetDefault("probes.ai_context.enabled", true)
v.SetDefault("probes.mise.enabled", true)
v.SetDefault("probes.mise_tasks.enabled", true)
v.SetDefault("output.include_file_hashes", false)
v.SetDefault("output.include_file_content", false)

Expand Down Expand Up @@ -414,6 +416,79 @@ func setDefaults(v *viper.Viper) {
// macOS
"Library/Preferences/helm/repositories.yaml",
}, "type": "glob"},

// mise (https://mise.jdx.dev) - polyglot tool / version /
// env manager. The [env] table sets shell env vars and is a
// common landing site for plaintext tokens.
//
// Pattern set tracks `LOCAL_CONFIG_FILENAMES` in mise's
// src/config/mod.rs plus the env-specific variants enumerated
// in `DEFAULT_CONFIG_FILENAMES`. The probe classifies each
// matched file at runtime (global vs project, local-override,
// env-specific) based on its path and basename.
//
// `.rtx.*` are mise's legacy (pre-rename) names; mise still
// reads them, so we include them here.
{"name": "mise_config", "patterns": []string{
// Project-level basenames (match at any depth)
"mise.toml",
".mise.toml",
"mise.*.toml", // mise.local.toml, mise.production.toml, mise.production.local.toml
".mise.*.toml", // .mise.local.toml, .mise.production.toml, etc.
".rtx.toml",
".rtx.*.toml",
// Idiomatic-dir forms (Unix + project-nested copies)
"mise/config.toml",
"mise/config.*.toml",
".mise/config.toml",
".mise/config.*.toml",
".config/mise.toml",
".config/mise.*.toml",
".config/mise/config.toml",
".config/mise/config.*.toml",
".config/mise/mise.toml",
".config/mise/mise.*.toml",
".config/mise/conf.d/*.toml",
// Windows: %APPDATA%\mise\...
"AppData/Roaming/mise/config.toml",
"AppData/Roaming/mise/config.*.toml",
"AppData/Roaming/mise/conf.d/*.toml",
}, "type": "glob"},

// mise file-task scripts. Each entry is a directory whose
// files are the task scripts (shell, python, node, deno, ...).
// Sub-directories are valid — mise composes the task name
// from the path. We enumerate 1-3 levels deep, which covers
// the typical `mise-tasks/<category>/<subcategory>/<task>`
// shape; deeper nesting is unusual.
//
// Windows: the docs don't mention Windows-specific paths
// for file tasks. Since these are user-authored scripts
// kept inside repos, the Unix paths apply via WSL or as
// repo-relative paths on plain Windows too.
{"name": "mise_task_file", "patterns": []string{
// mise-tasks/
"mise-tasks/*",
"mise-tasks/*/*",
"mise-tasks/*/*/*",
// .mise-tasks/
".mise-tasks/*",
".mise-tasks/*/*",
".mise-tasks/*/*/*",
// mise/tasks/
"mise/tasks/*",
"mise/tasks/*/*",
"mise/tasks/*/*/*",
// .mise/tasks/
".mise/tasks/*",
".mise/tasks/*/*",
".mise/tasks/*/*/*",
// .config/mise/tasks/ (covers ~/.config/mise/tasks/ when
// the home dir is walked + project-nested copies)
".config/mise/tasks/*",
".config/mise/tasks/*/*",
".config/mise/tasks/*/*/*",
}, "type": "glob"},
})
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/models/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type ProbeConfig struct {
IaC ProbeSettings `yaml:"iac" mapstructure:"iac"`
AIMCP ProbeSettings `yaml:"ai_mcp" mapstructure:"ai_mcp"`
AIContext ProbeSettings `yaml:"ai_context" mapstructure:"ai_context"`
Mise ProbeSettings `yaml:"mise" mapstructure:"mise"`
MiseTasks ProbeSettings `yaml:"mise_tasks" mapstructure:"mise_tasks"`
}

// ProbeSettings contains settings for a specific probe
Expand Down
Loading