secure-code-agent 0.12.9__tar.gz → 0.12.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {secure_code_agent-0.12.9/src/secure_code_agent.egg-info → secure_code_agent-0.12.10}/PKG-INFO +2 -2
  2. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/README.md +1 -1
  3. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10/src/secure_code_agent.egg-info}/PKG-INFO +2 -2
  4. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/__init__.py +1 -1
  5. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/cli.py +8 -0
  6. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/base.py +16 -1
  7. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/LICENSE +0 -0
  8. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/pyproject.toml +0 -0
  9. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/setup.cfg +0 -0
  10. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_agent.egg-info/SOURCES.txt +0 -0
  11. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_agent.egg-info/dependency_links.txt +0 -0
  12. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_agent.egg-info/entry_points.txt +0 -0
  13. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_agent.egg-info/requires.txt +0 -0
  14. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_agent.egg-info/top_level.txt +0 -0
  15. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/baseline.py +0 -0
  16. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/capabilities.py +0 -0
  17. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/config.py +0 -0
  18. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/data/semgrep-offline.yaml +0 -0
  19. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/demo.py +0 -0
  20. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/findings.py +0 -0
  21. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/git_tools.py +0 -0
  22. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/history.py +0 -0
  23. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/instructions.py +0 -0
  24. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/mcp_server.py +0 -0
  25. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/pillar.py +0 -0
  26. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/practice.py +0 -0
  27. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/remediation.py +0 -0
  28. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/renderers.py +0 -0
  29. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/ruleset.py +0 -0
  30. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/sarif.py +0 -0
  31. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanner_status.py +0 -0
  32. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/__init__.py +0 -0
  33. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/bandit_scanner.py +0 -0
  34. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/builtin_rules.py +0 -0
  35. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/checkov_scanner.py +0 -0
  36. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/floor.py +0 -0
  37. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/gitleaks_scanner.py +0 -0
  38. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/gosec_scanner.py +0 -0
  39. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/hadolint_scanner.py +0 -0
  40. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/njsscan_scanner.py +0 -0
  41. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/npm_audit_scanner.py +0 -0
  42. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/osv_scanner.py +0 -0
  43. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/pip_audit_scanner.py +0 -0
  44. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/rubocop_scanner.py +0 -0
  45. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/scorecard_scanner.py +0 -0
  46. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/semgrep_scanner.py +0 -0
  47. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/trivy_scanner.py +0 -0
  48. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scanners/trufflehog_scanner.py +0 -0
  49. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/scoring.py +0 -0
  50. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/standards.py +0 -0
  51. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/suppressions.py +0 -0
  52. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/triage.py +0 -0
  53. {secure_code_agent-0.12.9 → secure_code_agent-0.12.10}/src/secure_code_audit/verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secure-code-agent
3
- Version: 0.12.9
3
+ Version: 0.12.10
4
4
  Summary: Deterministic security gate + bounded AI remediation prompt generator. NIST SSDF / OWASP ASVS / CWE Top 25 anchored.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -515,7 +515,7 @@ For agents that support invokable skills, this repo ships a portable skill under
515
515
  ## GitHub Action
516
516
 
517
517
  ```yaml
518
- - uses: marshallguillory86/secure-code-agent@v0.12.9
518
+ - uses: marshallguillory86/secure-code-agent@v0.12.10
519
519
  with:
520
520
  config: secure-code-agent.json
521
521
  fail-on-gate: true
@@ -467,7 +467,7 @@ For agents that support invokable skills, this repo ships a portable skill under
467
467
  ## GitHub Action
468
468
 
469
469
  ```yaml
470
- - uses: marshallguillory86/secure-code-agent@v0.12.9
470
+ - uses: marshallguillory86/secure-code-agent@v0.12.10
471
471
  with:
472
472
  config: secure-code-agent.json
473
473
  fail-on-gate: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secure-code-agent
3
- Version: 0.12.9
3
+ Version: 0.12.10
4
4
  Summary: Deterministic security gate + bounded AI remediation prompt generator. NIST SSDF / OWASP ASVS / CWE Top 25 anchored.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -515,7 +515,7 @@ For agents that support invokable skills, this repo ships a portable skill under
515
515
  ## GitHub Action
516
516
 
517
517
  ```yaml
518
- - uses: marshallguillory86/secure-code-agent@v0.12.9
518
+ - uses: marshallguillory86/secure-code-agent@v0.12.10
519
519
  with:
520
520
  config: secure-code-agent.json
521
521
  fail-on-gate: true
@@ -12,4 +12,4 @@
12
12
  #:
13
13
  #: PyPI is immutable, so 0.4.0 stays wrong. 0.5.0 is the first build whose
14
14
  #: artifacts name their own producer correctly.
15
- __version__ = "0.12.9"
15
+ __version__ = "0.12.10"
@@ -306,6 +306,9 @@ def _do_preflight(args: argparse.Namespace) -> int:
306
306
  "command": " ".join(scanner.command) or None,
307
307
  "version": scanner.binary_version() if available else None,
308
308
  "remedy": None if available else scanner.unavailable_fix_hint(),
309
+ # Disclosed, not silent: the tree asked for a command and was
310
+ # not given it. `--trust-target-config` grants it.
311
+ "ignored_command": scanner.ignored_command,
309
312
  }
310
313
  )
311
314
 
@@ -341,6 +344,11 @@ def _print_preflight(rows: list[dict], unselected: list[str], blocking: list[str
341
344
  print(f" {mark} {row['scanner']:<14} {role:<8} {detail}")
342
345
  if row["remedy"]:
343
346
  print(f" → {row['remedy']}")
347
+ if row.get("ignored_command"):
348
+ print(
349
+ " ! the audited tree's config set this command; ignored "
350
+ "(pass --trust-target-config for a repository you own)"
351
+ )
344
352
  for name in unselected:
345
353
  print(f" ✗ {name:<14} required not enabled in this configuration")
346
354
  # Named, not omitted: a floor tool this run does not evaluate is a stated
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import dataclasses
5
6
  import importlib.util
6
7
  import os
7
8
  import re
@@ -18,6 +19,7 @@ from secure_code_audit.config import (
18
19
  containment_root,
19
20
  is_within,
20
21
  scanner_cfg,
22
+ target_config_is_untrusted,
21
23
  target_executables_allowed,
22
24
  )
23
25
  from secure_code_audit.findings import Category, Confidence, Finding, Severity
@@ -39,6 +41,9 @@ class Scanner(ABC):
39
41
  binary: str # name of the executable on PATH
40
42
  version_flag: str = "--version"
41
43
  python_module: str | None = None
44
+ #: True when the audited tree's own config set this scanner's command and
45
+ #: it was not honoured. See `configure`.
46
+ ignored_command: bool = False
42
47
  default_category: Category = Category.CODE_VULNERABILITIES
43
48
  # How an operator obtains this scanner. Surfaced in the unavailable
44
49
  # finding and in --preflight. The agent never installs anything itself.
@@ -61,7 +66,17 @@ class Scanner(ABC):
61
66
  """
62
67
  root = containment_root(target)
63
68
  self._allow_target_executables = target_executables_allowed(config, target)
64
- self._resolved_command = self._resolve_command(root, self.cfg(config))
69
+ chosen = self.cfg(config)
70
+ # An untrusted config does not choose the command — not just "not an
71
+ # executable from the tree". It could name any program on PATH with
72
+ # any arguments, and `python -c "<code>"` is any program; the
73
+ # `--version` probe ran it during preflight, before anything was
74
+ # audited (maintainability-agent's audit, 2026-10-02). The scanner
75
+ # resolves as it would with no config, and says it ignored one.
76
+ self.ignored_command = bool(chosen.command) and target_config_is_untrusted(config, target)
77
+ if self.ignored_command:
78
+ chosen = dataclasses.replace(chosen, command=[])
79
+ self._resolved_command = self._resolve_command(root, chosen)
65
80
 
66
81
  @property
67
82
  def command(self) -> tuple[str, ...]: