SafeAI-Static-Analyzer 2.3.0__tar.gz → 2.4.0__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.
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/PKG-INFO +77 -4
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/README.md +76 -3
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/SafeAI_Static_Analyzer.egg-info/PKG-INFO +77 -4
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/SafeAI_Static_Analyzer.egg-info/SOURCES.txt +10 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/capability_diff.py +228 -2
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/component_graph.py +34 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/cmd/cli.py +18 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/cmd/postprocess.py +85 -3
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/__init__.py +1 -1
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/contract.py +48 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/enrich.py +66 -1
- safeai_static_analyzer-2.4.0/safeai/kya/exceptions.py +264 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/manifest.py +48 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/policy.py +157 -10
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/registry/persist.py +5 -2
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/registry/schema.py +13 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/html.py +160 -1
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/pr_comment.py +76 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/terminal.py +10 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/scorecard.py +1 -1
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/version.py +1 -1
- safeai_static_analyzer-2.4.0/tests/test_architectural_invariants.py +236 -0
- safeai_static_analyzer-2.4.0/tests/test_architecture_diagram.py +291 -0
- safeai_static_analyzer-2.4.0/tests/test_authority_change.py +318 -0
- safeai_static_analyzer-2.4.0/tests/test_baseline_compat.py +66 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_benchmarks.py +2 -2
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_capability_diff_v2.py +1 -1
- safeai_static_analyzer-2.4.0/tests/test_evidence_contract_v7.py +335 -0
- safeai_static_analyzer-2.4.0/tests/test_exceptions.py +284 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_github_action.py +2 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_html_report.py +26 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_plugin_sdk.py +24 -3
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_policy.py +154 -6
- safeai_static_analyzer-2.4.0/tests/test_pr_paths.py +163 -0
- safeai_static_analyzer-2.4.0/tests/test_release_workflow.py +114 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_scorecard.py +2 -2
- safeai_static_analyzer-2.4.0/tests/test_unknown_authority.py +175 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/LICENSE +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/SafeAI_Static_Analyzer.egg-info/dependency_links.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/SafeAI_Static_Analyzer.egg-info/entry_points.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/SafeAI_Static_Analyzer.egg-info/requires.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/SafeAI_Static_Analyzer.egg-info/top_level.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/pyproject.toml +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/__main__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/aggregation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/capabilities.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/component_diff.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/components.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/dependency_correlation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/escalation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/escalation_remediation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/import_graph.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/project_graph.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/semantic.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/target_taxonomy.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/tool_identity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/tool_implementation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analysis/tool_surface.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/capability/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/capability/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/claude_code/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/claude_code/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/data_leakage/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/data_leakage/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/dataflow/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/dataflow/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/env_dependency/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/env_dependency/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/governance/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/governance/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/mcp/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/mcp/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/mcp/compatibility.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/mcp/schema.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/mcp/validators.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/model_config/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/model_config/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/prompt/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/prompt/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/prompt_file/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/prompt_file/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/skill/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/skill/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/tool_def/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/tool_def/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/workflow/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/analyzers/workflow/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/cmd/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/cmd/manifest_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/cmd/registry_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/controls/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/controls/catalogs.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/controls/mappings.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/engine/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/engine/file_discovery.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/engine/metadata.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/engine/orchestrator.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/engine/scan.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/autogen/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/azure_foundry/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/azure_foundry/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/bedrock_agent/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/bedrock_agent/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/claude_code/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/claude_code/commands.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/claude_code/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/claude_code/permissions.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/claude_code/settings.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/copilot/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/copilot/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/crewai/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/crewai/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/cursorrules/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/cursorrules/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/dify/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/dify/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/google_adk/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/google_adk/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/haystack/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/haystack/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/langchain/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/langchain/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/langgraph/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/langgraph/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/llamaindex/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/llamaindex/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/mastra/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/mastra/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/microsoft_agent/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/microsoft_agent/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/n8n/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/n8n/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/openai_agents/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/openai_agents/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/openclaw/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/openclaw/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/semantic_kernel/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/semantic_kernel/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/windsurf/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/frameworks/windsurf/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/assurance.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/baseline.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/ci_context.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/exporter.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/fingerprints.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/identity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/importer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/integrity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/lockfile.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/registry/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/registry/connection.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/registry/queries.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/suppressions.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/kya/util.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/failure_matrix.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/html_kit.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/json_report.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/registry_html.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/report/sarif.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/rules/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/rules/base_rules.yaml +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/rules/loader.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/rules/pack_test.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/scoring/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/scoring/engine.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/severity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/telemetry/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/telemetry/client.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/telemetry/config.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/safeai/telemetry/schema.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/setup.cfg +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_adapter_dataflow.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_assurance.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_baseline.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_capability_detection.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_ci_context.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_claude_code_deep.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_compatibility.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_component_graph.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_component_hash.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_confidence_arbitration.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_config_adapters.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_control_mappings.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_crewai_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_cursorrules_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_dco.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_env_dependency.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_escalation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_escalation_remediation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_evidence_type.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_fingerprints.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_governance_analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_init_and_rules.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_kya_integration.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_kya_manifest.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_langgraph_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_llamaindex_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_manifest_contract.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_manifest_integrity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_mcp_tool_poisoning.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_mcp_validation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_n8n_workflow.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_parser_aggregation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_phase15.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_pr_comment.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_pr_comment_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_quality_gates.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_registry.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_registry_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_registry_html.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_regression_fixtures.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_release_assets.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_release_fixes.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_release_validation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_rules_loader_determinism.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_sarif.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_scan_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_scan_phase11.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_scoring.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_semantic.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_severity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_suppressions.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_target_taxonomy_engine.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_telemetry.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_tool_identity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_tool_implementation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_version.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.4.0}/tests/test_windsurf_framework.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SafeAI-Static-Analyzer
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: The lightweight, open-source Static AI Capability & Risk Analyzer for CI/CD pipelines.
|
|
5
5
|
Author: IkarusCareer
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -31,7 +31,7 @@ Provides-Extra: standalone
|
|
|
31
31
|
Requires-Dist: pyinstaller>=6.0; extra == "standalone"
|
|
32
32
|
Dynamic: license-file
|
|
33
33
|
|
|
34
|
-
# SafeAI —
|
|
34
|
+
# SafeAI — Agent Authority Security for the Software Supply Chain
|
|
35
35
|
|
|
36
36
|
[](https://github.com/ikaruscareer/SafeAI/actions/workflows/ci.yml)
|
|
37
37
|
[](https://scorecard.dev/viewer/?uri=github.com/ikaruscareer/SafeAI)
|
|
@@ -41,7 +41,19 @@ Dynamic: license-file
|
|
|
41
41
|
|
|
42
42
|
Enjoying SafeAI? A ⭐ on [GitHub](https://github.com/ikaruscareer/SafeAI) helps more security teams find it.
|
|
43
43
|
|
|
44
|
-
**
|
|
44
|
+
**Know what your AI agent can do before you deploy it.**
|
|
45
|
+
|
|
46
|
+
**SafeAI** statically maps agent capabilities, tools, MCP integrations, and authority changes, then turns material changes into explainable CI/CD security decisions and portable evidence. Technically, SafeAI is a *Static AI Capability & Risk Analyzer*: it scans AI application source code for security risks, capability exposure, and governance gaps. It is offline and source-private by default — it never executes agents or calls LLMs, and network activity occurs only through explicitly enabled integration commands (currently only `--pr-comment-post`). It integrates into CI/CD pipelines.
|
|
47
|
+
|
|
48
|
+
**Three pillars — DISCOVER / COMPARE / GOVERN:**
|
|
49
|
+
|
|
50
|
+
| Pillar | Question | What SafeAI does |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| **DISCOVER** | What can the agent access? | Builds an evidence-backed model of agent authority: tools, MCP servers, filesystem, shell, databases, APIs, destinations, memory, delegation, autonomy, approval controls |
|
|
53
|
+
| **COMPARE** | What changed? | Diffs authority against the approved baseline: new tools, `read → write` widening, new destinations, removed approval gates |
|
|
54
|
+
| **GOVERN** | Should that change be allowed? | Deterministic CI/CD decisions — `pass`, `review-required`, `block`, `accepted-exception` — with evidence, never an opaque score |
|
|
55
|
+
|
|
56
|
+
> SafeAI is not a runtime guardrail and does not certify an agent as safe. It provides source-first, evidence-backed visibility into agent authority and meaningful changes *before deployment*.
|
|
45
57
|
|
|
46
58
|
> 🌐 [safeai-analyzer.ikaruscareer.com](https://safeai-analyzer.ikaruscareer.com) — project landing page
|
|
47
59
|
|
|
@@ -75,6 +87,65 @@ Designed to be lightweight, explainable, and community-driven, SafeAI aims to be
|
|
|
75
87
|
|
|
76
88
|
SafeAI sits before runtime guardrails and red-teaming tools in the security lifecycle. It scans agent source code at commit time — detecting framework-specific capabilities, MCP misconfigurations, and prompt injection patterns — before you ever deploy an agent to staging. It does not replace runtime tools (Microsoft AGT), evaluation frameworks (LangSmith, DeepEval), or red-teaming scanners (Promptfoo, Garak). It complements them: find the risk in code first, then validate at runtime.
|
|
77
89
|
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Example: authority-change report
|
|
93
|
+
|
|
94
|
+
*SafeAI's most important security event is not simply that a finding exists. It is that an agent's effective authority materially changes.*
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Agent: customer-support-agent Baseline: release v2.4.0 (approved)
|
|
98
|
+
|
|
99
|
+
AUTHORITY CHANGE (material)
|
|
100
|
+
+ tool: crm_update
|
|
101
|
+
+ capability: database write
|
|
102
|
+
+ destination: production CRM
|
|
103
|
+
+ access: read → write
|
|
104
|
+
- human approval gate (GOV_APPROVAL_MISSING)
|
|
105
|
+
|
|
106
|
+
Policy decision: BLOCK
|
|
107
|
+
Reason: production write authority was added without an approved
|
|
108
|
+
exception or required approval control.
|
|
109
|
+
Evidence: source files · tool definition · baseline manifest ·
|
|
110
|
+
current manifest · policy profile · SafeAI version ·
|
|
111
|
+
ruleset version · commit SHA
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The reviewer learns *what the agent can now do that it could not do
|
|
115
|
+
before* — and the decision cites evidence, not a score.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Agent Authority Model
|
|
120
|
+
|
|
121
|
+
SafeAI builds an analytical model — not an observation of runtime
|
|
122
|
+
permissions — of what an agent is empowered to do:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Agent
|
|
126
|
+
→ Tool / MCP Server / Skill / Workflow Node
|
|
127
|
+
→ Capability
|
|
128
|
+
→ Access Mode (none < read < write < mutate < execute)
|
|
129
|
+
→ Data / Destination / Resource
|
|
130
|
+
→ Authority
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Every authority statement carries a class: **declared** (config says so),
|
|
134
|
+
**detected** (code shows it), **inferred** (heuristic, confidence-labelled),
|
|
135
|
+
**repository/IaC-observed** (in-repo infrastructure grants), or
|
|
136
|
+
**unknown**. Runtime-granted authority (live IAM, deployed network policy,
|
|
137
|
+
runtime identity) is explicitly **unknown** to the static scanner —
|
|
138
|
+
*unknown is an evidence state, not evidence of safety*, and SafeAI never
|
|
139
|
+
converts it into a pass.
|
|
140
|
+
|
|
141
|
+
**What decisions mean.** `pass` means no configured deterministic gate
|
|
142
|
+
triggered — never "the agent is safe." `unknown` means unattributable
|
|
143
|
+
evidence — never "no risk detected." Organizations can govern unknown
|
|
144
|
+
authority explicitly (`authority.unknown` policy, `--unknown-authority`),
|
|
145
|
+
but the default leaves it visible and unfailed.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
78
149
|
<img width="1024" height="1024" alt="SafeAI_Concept" src="https://github.com/user-attachments/assets/c07999b2-79d5-4200-9eec-ce1ab4e63cc8" />
|
|
79
150
|
|
|
80
151
|
|
|
@@ -101,7 +172,7 @@ SafeAI sits before runtime guardrails and red-teaming tools in the security life
|
|
|
101
172
|
| **Baseline & Escalation Gating** | `--fail-on-new` for new/regressed findings, `--fail-on-escalation` for authority changes, `--pr-comment` PR summaries |
|
|
102
173
|
| **Policy-as-Code & Suppressions** | `allow`/`warn`/`require_review`/`deny` policy with selectors; required-reason suppressions |
|
|
103
174
|
| **Assurance Boundary** | Every scan states exactly what it did and could not verify — never a fixed disclaimer |
|
|
104
|
-
| **Security Scorecard** | Deterministic 0–10 score with per-category breakdown and `pass`/`warn`/`fail` outcome;
|
|
175
|
+
| **Security Scorecard** | Deterministic 0–10 score with per-category breakdown and `pass`/`warn`/`fail` outcome; informational unless you opt into `--scorecard-fail-under` gating — evidence and policy decide, the score does not |
|
|
105
176
|
| **CI/CD Integration** | SARIF 2.1.0 output, exit codes, GitHub Actions **Marketplace action** and workflow included |
|
|
106
177
|
| **Community Scan** | Governed private-pilot workflow for scanning public third-party agent frameworks with responsible disclosure (`community-scans/`) — private by default, human-reviewed before any publication |
|
|
107
178
|
| **Multi-Format Reports** | Terminal, JSON, SARIF 2.1.0, HTML, canonical KYA manifest, PR comment, Security Scorecard |
|
|
@@ -530,6 +601,8 @@ contributors who have helped make AI safer:
|
|
|
530
601
|
| [@mah](https://github.com/mahirhir) | Claude Code deep analysis documentation |
|
|
531
602
|
| [@asarakhatun17-lgtm](https://github.com/asarakhatun17-lgtm) | Supported frameworks consistency fix |
|
|
532
603
|
| [@yugaaank](https://github.com/yugaaank) | Capability detectors (Docker, Kubernetes, Redis, S3, GCP, Slack, Jira, browser) |
|
|
604
|
+
| [@Teachmeplaycode](https://github.com/Teachmeplaycode) | Benchmark corpus expansion, static subprocess precision gap documentation (PR #174) |
|
|
605
|
+
| [@nikitajos7](https://github.com/nikitajos7) | Policy profile display in terminal and HTML reports (PR #175) |
|
|
533
606
|
|
|
534
607
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get involved.
|
|
535
608
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SafeAI —
|
|
1
|
+
# SafeAI — Agent Authority Security for the Software Supply Chain
|
|
2
2
|
|
|
3
3
|
[](https://github.com/ikaruscareer/SafeAI/actions/workflows/ci.yml)
|
|
4
4
|
[](https://scorecard.dev/viewer/?uri=github.com/ikaruscareer/SafeAI)
|
|
@@ -8,7 +8,19 @@
|
|
|
8
8
|
|
|
9
9
|
Enjoying SafeAI? A ⭐ on [GitHub](https://github.com/ikaruscareer/SafeAI) helps more security teams find it.
|
|
10
10
|
|
|
11
|
-
**
|
|
11
|
+
**Know what your AI agent can do before you deploy it.**
|
|
12
|
+
|
|
13
|
+
**SafeAI** statically maps agent capabilities, tools, MCP integrations, and authority changes, then turns material changes into explainable CI/CD security decisions and portable evidence. Technically, SafeAI is a *Static AI Capability & Risk Analyzer*: it scans AI application source code for security risks, capability exposure, and governance gaps. It is offline and source-private by default — it never executes agents or calls LLMs, and network activity occurs only through explicitly enabled integration commands (currently only `--pr-comment-post`). It integrates into CI/CD pipelines.
|
|
14
|
+
|
|
15
|
+
**Three pillars — DISCOVER / COMPARE / GOVERN:**
|
|
16
|
+
|
|
17
|
+
| Pillar | Question | What SafeAI does |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| **DISCOVER** | What can the agent access? | Builds an evidence-backed model of agent authority: tools, MCP servers, filesystem, shell, databases, APIs, destinations, memory, delegation, autonomy, approval controls |
|
|
20
|
+
| **COMPARE** | What changed? | Diffs authority against the approved baseline: new tools, `read → write` widening, new destinations, removed approval gates |
|
|
21
|
+
| **GOVERN** | Should that change be allowed? | Deterministic CI/CD decisions — `pass`, `review-required`, `block`, `accepted-exception` — with evidence, never an opaque score |
|
|
22
|
+
|
|
23
|
+
> SafeAI is not a runtime guardrail and does not certify an agent as safe. It provides source-first, evidence-backed visibility into agent authority and meaningful changes *before deployment*.
|
|
12
24
|
|
|
13
25
|
> 🌐 [safeai-analyzer.ikaruscareer.com](https://safeai-analyzer.ikaruscareer.com) — project landing page
|
|
14
26
|
|
|
@@ -42,6 +54,65 @@ Designed to be lightweight, explainable, and community-driven, SafeAI aims to be
|
|
|
42
54
|
|
|
43
55
|
SafeAI sits before runtime guardrails and red-teaming tools in the security lifecycle. It scans agent source code at commit time — detecting framework-specific capabilities, MCP misconfigurations, and prompt injection patterns — before you ever deploy an agent to staging. It does not replace runtime tools (Microsoft AGT), evaluation frameworks (LangSmith, DeepEval), or red-teaming scanners (Promptfoo, Garak). It complements them: find the risk in code first, then validate at runtime.
|
|
44
56
|
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Example: authority-change report
|
|
60
|
+
|
|
61
|
+
*SafeAI's most important security event is not simply that a finding exists. It is that an agent's effective authority materially changes.*
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Agent: customer-support-agent Baseline: release v2.4.0 (approved)
|
|
65
|
+
|
|
66
|
+
AUTHORITY CHANGE (material)
|
|
67
|
+
+ tool: crm_update
|
|
68
|
+
+ capability: database write
|
|
69
|
+
+ destination: production CRM
|
|
70
|
+
+ access: read → write
|
|
71
|
+
- human approval gate (GOV_APPROVAL_MISSING)
|
|
72
|
+
|
|
73
|
+
Policy decision: BLOCK
|
|
74
|
+
Reason: production write authority was added without an approved
|
|
75
|
+
exception or required approval control.
|
|
76
|
+
Evidence: source files · tool definition · baseline manifest ·
|
|
77
|
+
current manifest · policy profile · SafeAI version ·
|
|
78
|
+
ruleset version · commit SHA
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The reviewer learns *what the agent can now do that it could not do
|
|
82
|
+
before* — and the decision cites evidence, not a score.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Agent Authority Model
|
|
87
|
+
|
|
88
|
+
SafeAI builds an analytical model — not an observation of runtime
|
|
89
|
+
permissions — of what an agent is empowered to do:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
Agent
|
|
93
|
+
→ Tool / MCP Server / Skill / Workflow Node
|
|
94
|
+
→ Capability
|
|
95
|
+
→ Access Mode (none < read < write < mutate < execute)
|
|
96
|
+
→ Data / Destination / Resource
|
|
97
|
+
→ Authority
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Every authority statement carries a class: **declared** (config says so),
|
|
101
|
+
**detected** (code shows it), **inferred** (heuristic, confidence-labelled),
|
|
102
|
+
**repository/IaC-observed** (in-repo infrastructure grants), or
|
|
103
|
+
**unknown**. Runtime-granted authority (live IAM, deployed network policy,
|
|
104
|
+
runtime identity) is explicitly **unknown** to the static scanner —
|
|
105
|
+
*unknown is an evidence state, not evidence of safety*, and SafeAI never
|
|
106
|
+
converts it into a pass.
|
|
107
|
+
|
|
108
|
+
**What decisions mean.** `pass` means no configured deterministic gate
|
|
109
|
+
triggered — never "the agent is safe." `unknown` means unattributable
|
|
110
|
+
evidence — never "no risk detected." Organizations can govern unknown
|
|
111
|
+
authority explicitly (`authority.unknown` policy, `--unknown-authority`),
|
|
112
|
+
but the default leaves it visible and unfailed.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
45
116
|
<img width="1024" height="1024" alt="SafeAI_Concept" src="https://github.com/user-attachments/assets/c07999b2-79d5-4200-9eec-ce1ab4e63cc8" />
|
|
46
117
|
|
|
47
118
|
|
|
@@ -68,7 +139,7 @@ SafeAI sits before runtime guardrails and red-teaming tools in the security life
|
|
|
68
139
|
| **Baseline & Escalation Gating** | `--fail-on-new` for new/regressed findings, `--fail-on-escalation` for authority changes, `--pr-comment` PR summaries |
|
|
69
140
|
| **Policy-as-Code & Suppressions** | `allow`/`warn`/`require_review`/`deny` policy with selectors; required-reason suppressions |
|
|
70
141
|
| **Assurance Boundary** | Every scan states exactly what it did and could not verify — never a fixed disclaimer |
|
|
71
|
-
| **Security Scorecard** | Deterministic 0–10 score with per-category breakdown and `pass`/`warn`/`fail` outcome;
|
|
142
|
+
| **Security Scorecard** | Deterministic 0–10 score with per-category breakdown and `pass`/`warn`/`fail` outcome; informational unless you opt into `--scorecard-fail-under` gating — evidence and policy decide, the score does not |
|
|
72
143
|
| **CI/CD Integration** | SARIF 2.1.0 output, exit codes, GitHub Actions **Marketplace action** and workflow included |
|
|
73
144
|
| **Community Scan** | Governed private-pilot workflow for scanning public third-party agent frameworks with responsible disclosure (`community-scans/`) — private by default, human-reviewed before any publication |
|
|
74
145
|
| **Multi-Format Reports** | Terminal, JSON, SARIF 2.1.0, HTML, canonical KYA manifest, PR comment, Security Scorecard |
|
|
@@ -497,6 +568,8 @@ contributors who have helped make AI safer:
|
|
|
497
568
|
| [@mah](https://github.com/mahirhir) | Claude Code deep analysis documentation |
|
|
498
569
|
| [@asarakhatun17-lgtm](https://github.com/asarakhatun17-lgtm) | Supported frameworks consistency fix |
|
|
499
570
|
| [@yugaaank](https://github.com/yugaaank) | Capability detectors (Docker, Kubernetes, Redis, S3, GCP, Slack, Jira, browser) |
|
|
571
|
+
| [@Teachmeplaycode](https://github.com/Teachmeplaycode) | Benchmark corpus expansion, static subprocess precision gap documentation (PR #174) |
|
|
572
|
+
| [@nikitajos7](https://github.com/nikitajos7) | Policy profile display in terminal and HTML reports (PR #175) |
|
|
500
573
|
|
|
501
574
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get involved.
|
|
502
575
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SafeAI-Static-Analyzer
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: The lightweight, open-source Static AI Capability & Risk Analyzer for CI/CD pipelines.
|
|
5
5
|
Author: IkarusCareer
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -31,7 +31,7 @@ Provides-Extra: standalone
|
|
|
31
31
|
Requires-Dist: pyinstaller>=6.0; extra == "standalone"
|
|
32
32
|
Dynamic: license-file
|
|
33
33
|
|
|
34
|
-
# SafeAI —
|
|
34
|
+
# SafeAI — Agent Authority Security for the Software Supply Chain
|
|
35
35
|
|
|
36
36
|
[](https://github.com/ikaruscareer/SafeAI/actions/workflows/ci.yml)
|
|
37
37
|
[](https://scorecard.dev/viewer/?uri=github.com/ikaruscareer/SafeAI)
|
|
@@ -41,7 +41,19 @@ Dynamic: license-file
|
|
|
41
41
|
|
|
42
42
|
Enjoying SafeAI? A ⭐ on [GitHub](https://github.com/ikaruscareer/SafeAI) helps more security teams find it.
|
|
43
43
|
|
|
44
|
-
**
|
|
44
|
+
**Know what your AI agent can do before you deploy it.**
|
|
45
|
+
|
|
46
|
+
**SafeAI** statically maps agent capabilities, tools, MCP integrations, and authority changes, then turns material changes into explainable CI/CD security decisions and portable evidence. Technically, SafeAI is a *Static AI Capability & Risk Analyzer*: it scans AI application source code for security risks, capability exposure, and governance gaps. It is offline and source-private by default — it never executes agents or calls LLMs, and network activity occurs only through explicitly enabled integration commands (currently only `--pr-comment-post`). It integrates into CI/CD pipelines.
|
|
47
|
+
|
|
48
|
+
**Three pillars — DISCOVER / COMPARE / GOVERN:**
|
|
49
|
+
|
|
50
|
+
| Pillar | Question | What SafeAI does |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| **DISCOVER** | What can the agent access? | Builds an evidence-backed model of agent authority: tools, MCP servers, filesystem, shell, databases, APIs, destinations, memory, delegation, autonomy, approval controls |
|
|
53
|
+
| **COMPARE** | What changed? | Diffs authority against the approved baseline: new tools, `read → write` widening, new destinations, removed approval gates |
|
|
54
|
+
| **GOVERN** | Should that change be allowed? | Deterministic CI/CD decisions — `pass`, `review-required`, `block`, `accepted-exception` — with evidence, never an opaque score |
|
|
55
|
+
|
|
56
|
+
> SafeAI is not a runtime guardrail and does not certify an agent as safe. It provides source-first, evidence-backed visibility into agent authority and meaningful changes *before deployment*.
|
|
45
57
|
|
|
46
58
|
> 🌐 [safeai-analyzer.ikaruscareer.com](https://safeai-analyzer.ikaruscareer.com) — project landing page
|
|
47
59
|
|
|
@@ -75,6 +87,65 @@ Designed to be lightweight, explainable, and community-driven, SafeAI aims to be
|
|
|
75
87
|
|
|
76
88
|
SafeAI sits before runtime guardrails and red-teaming tools in the security lifecycle. It scans agent source code at commit time — detecting framework-specific capabilities, MCP misconfigurations, and prompt injection patterns — before you ever deploy an agent to staging. It does not replace runtime tools (Microsoft AGT), evaluation frameworks (LangSmith, DeepEval), or red-teaming scanners (Promptfoo, Garak). It complements them: find the risk in code first, then validate at runtime.
|
|
77
89
|
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Example: authority-change report
|
|
93
|
+
|
|
94
|
+
*SafeAI's most important security event is not simply that a finding exists. It is that an agent's effective authority materially changes.*
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Agent: customer-support-agent Baseline: release v2.4.0 (approved)
|
|
98
|
+
|
|
99
|
+
AUTHORITY CHANGE (material)
|
|
100
|
+
+ tool: crm_update
|
|
101
|
+
+ capability: database write
|
|
102
|
+
+ destination: production CRM
|
|
103
|
+
+ access: read → write
|
|
104
|
+
- human approval gate (GOV_APPROVAL_MISSING)
|
|
105
|
+
|
|
106
|
+
Policy decision: BLOCK
|
|
107
|
+
Reason: production write authority was added without an approved
|
|
108
|
+
exception or required approval control.
|
|
109
|
+
Evidence: source files · tool definition · baseline manifest ·
|
|
110
|
+
current manifest · policy profile · SafeAI version ·
|
|
111
|
+
ruleset version · commit SHA
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The reviewer learns *what the agent can now do that it could not do
|
|
115
|
+
before* — and the decision cites evidence, not a score.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Agent Authority Model
|
|
120
|
+
|
|
121
|
+
SafeAI builds an analytical model — not an observation of runtime
|
|
122
|
+
permissions — of what an agent is empowered to do:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Agent
|
|
126
|
+
→ Tool / MCP Server / Skill / Workflow Node
|
|
127
|
+
→ Capability
|
|
128
|
+
→ Access Mode (none < read < write < mutate < execute)
|
|
129
|
+
→ Data / Destination / Resource
|
|
130
|
+
→ Authority
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Every authority statement carries a class: **declared** (config says so),
|
|
134
|
+
**detected** (code shows it), **inferred** (heuristic, confidence-labelled),
|
|
135
|
+
**repository/IaC-observed** (in-repo infrastructure grants), or
|
|
136
|
+
**unknown**. Runtime-granted authority (live IAM, deployed network policy,
|
|
137
|
+
runtime identity) is explicitly **unknown** to the static scanner —
|
|
138
|
+
*unknown is an evidence state, not evidence of safety*, and SafeAI never
|
|
139
|
+
converts it into a pass.
|
|
140
|
+
|
|
141
|
+
**What decisions mean.** `pass` means no configured deterministic gate
|
|
142
|
+
triggered — never "the agent is safe." `unknown` means unattributable
|
|
143
|
+
evidence — never "no risk detected." Organizations can govern unknown
|
|
144
|
+
authority explicitly (`authority.unknown` policy, `--unknown-authority`),
|
|
145
|
+
but the default leaves it visible and unfailed.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
78
149
|
<img width="1024" height="1024" alt="SafeAI_Concept" src="https://github.com/user-attachments/assets/c07999b2-79d5-4200-9eec-ce1ab4e63cc8" />
|
|
79
150
|
|
|
80
151
|
|
|
@@ -101,7 +172,7 @@ SafeAI sits before runtime guardrails and red-teaming tools in the security life
|
|
|
101
172
|
| **Baseline & Escalation Gating** | `--fail-on-new` for new/regressed findings, `--fail-on-escalation` for authority changes, `--pr-comment` PR summaries |
|
|
102
173
|
| **Policy-as-Code & Suppressions** | `allow`/`warn`/`require_review`/`deny` policy with selectors; required-reason suppressions |
|
|
103
174
|
| **Assurance Boundary** | Every scan states exactly what it did and could not verify — never a fixed disclaimer |
|
|
104
|
-
| **Security Scorecard** | Deterministic 0–10 score with per-category breakdown and `pass`/`warn`/`fail` outcome;
|
|
175
|
+
| **Security Scorecard** | Deterministic 0–10 score with per-category breakdown and `pass`/`warn`/`fail` outcome; informational unless you opt into `--scorecard-fail-under` gating — evidence and policy decide, the score does not |
|
|
105
176
|
| **CI/CD Integration** | SARIF 2.1.0 output, exit codes, GitHub Actions **Marketplace action** and workflow included |
|
|
106
177
|
| **Community Scan** | Governed private-pilot workflow for scanning public third-party agent frameworks with responsible disclosure (`community-scans/`) — private by default, human-reviewed before any publication |
|
|
107
178
|
| **Multi-Format Reports** | Terminal, JSON, SARIF 2.1.0, HTML, canonical KYA manifest, PR comment, Security Scorecard |
|
|
@@ -530,6 +601,8 @@ contributors who have helped make AI safer:
|
|
|
530
601
|
| [@mah](https://github.com/mahirhir) | Claude Code deep analysis documentation |
|
|
531
602
|
| [@asarakhatun17-lgtm](https://github.com/asarakhatun17-lgtm) | Supported frameworks consistency fix |
|
|
532
603
|
| [@yugaaank](https://github.com/yugaaank) | Capability detectors (Docker, Kubernetes, Redis, S3, GCP, Slack, Jira, browser) |
|
|
604
|
+
| [@Teachmeplaycode](https://github.com/Teachmeplaycode) | Benchmark corpus expansion, static subprocess precision gap documentation (PR #174) |
|
|
605
|
+
| [@nikitajos7](https://github.com/nikitajos7) | Policy profile display in terminal and HTML reports (PR #175) |
|
|
533
606
|
|
|
534
607
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get involved.
|
|
535
608
|
|
|
@@ -121,6 +121,7 @@ safeai/kya/baseline.py
|
|
|
121
121
|
safeai/kya/ci_context.py
|
|
122
122
|
safeai/kya/contract.py
|
|
123
123
|
safeai/kya/enrich.py
|
|
124
|
+
safeai/kya/exceptions.py
|
|
124
125
|
safeai/kya/exporter.py
|
|
125
126
|
safeai/kya/fingerprints.py
|
|
126
127
|
safeai/kya/identity.py
|
|
@@ -156,8 +157,12 @@ safeai/telemetry/client.py
|
|
|
156
157
|
safeai/telemetry/config.py
|
|
157
158
|
safeai/telemetry/schema.py
|
|
158
159
|
tests/test_adapter_dataflow.py
|
|
160
|
+
tests/test_architectural_invariants.py
|
|
161
|
+
tests/test_architecture_diagram.py
|
|
159
162
|
tests/test_assurance.py
|
|
163
|
+
tests/test_authority_change.py
|
|
160
164
|
tests/test_baseline.py
|
|
165
|
+
tests/test_baseline_compat.py
|
|
161
166
|
tests/test_benchmarks.py
|
|
162
167
|
tests/test_capability_detection.py
|
|
163
168
|
tests/test_capability_diff_v2.py
|
|
@@ -175,7 +180,9 @@ tests/test_dco.py
|
|
|
175
180
|
tests/test_env_dependency.py
|
|
176
181
|
tests/test_escalation.py
|
|
177
182
|
tests/test_escalation_remediation.py
|
|
183
|
+
tests/test_evidence_contract_v7.py
|
|
178
184
|
tests/test_evidence_type.py
|
|
185
|
+
tests/test_exceptions.py
|
|
179
186
|
tests/test_fingerprints.py
|
|
180
187
|
tests/test_github_action.py
|
|
181
188
|
tests/test_governance_analyzer.py
|
|
@@ -196,6 +203,7 @@ tests/test_plugin_sdk.py
|
|
|
196
203
|
tests/test_policy.py
|
|
197
204
|
tests/test_pr_comment.py
|
|
198
205
|
tests/test_pr_comment_cli.py
|
|
206
|
+
tests/test_pr_paths.py
|
|
199
207
|
tests/test_quality_gates.py
|
|
200
208
|
tests/test_registry.py
|
|
201
209
|
tests/test_registry_cli.py
|
|
@@ -204,6 +212,7 @@ tests/test_regression_fixtures.py
|
|
|
204
212
|
tests/test_release_assets.py
|
|
205
213
|
tests/test_release_fixes.py
|
|
206
214
|
tests/test_release_validation.py
|
|
215
|
+
tests/test_release_workflow.py
|
|
207
216
|
tests/test_rules_loader_determinism.py
|
|
208
217
|
tests/test_sarif.py
|
|
209
218
|
tests/test_scan_framework.py
|
|
@@ -217,5 +226,6 @@ tests/test_target_taxonomy_engine.py
|
|
|
217
226
|
tests/test_telemetry.py
|
|
218
227
|
tests/test_tool_identity.py
|
|
219
228
|
tests/test_tool_implementation.py
|
|
229
|
+
tests/test_unknown_authority.py
|
|
220
230
|
tests/test_version.py
|
|
221
231
|
tests/test_windsurf_framework.py
|