SafeAI-Static-Analyzer 2.3.0__tar.gz → 2.5.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.5.0}/PKG-INFO +83 -5
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/README.md +82 -4
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/SafeAI_Static_Analyzer.egg-info/PKG-INFO +83 -5
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/SafeAI_Static_Analyzer.egg-info/SOURCES.txt +25 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/capability_diff.py +228 -2
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/component_graph.py +34 -0
- safeai_static_analyzer-2.5.0/safeai/analysis/iac_correlation.py +482 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/cmd/cli.py +18 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/cmd/postprocess.py +85 -3
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/engine/orchestrator.py +42 -0
- safeai_static_analyzer-2.5.0/safeai/iac/__init__.py +169 -0
- safeai_static_analyzer-2.5.0/safeai/iac/k8s.py +216 -0
- safeai_static_analyzer-2.5.0/safeai/iac/linking.py +224 -0
- safeai_static_analyzer-2.5.0/safeai/iac/model.py +148 -0
- safeai_static_analyzer-2.5.0/safeai/iac/semantics.py +198 -0
- safeai_static_analyzer-2.5.0/safeai/iac/terraform.py +524 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/__init__.py +1 -1
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/assurance.py +34 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/contract.py +87 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/enrich.py +70 -1
- safeai_static_analyzer-2.5.0/safeai/kya/exceptions.py +264 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/manifest.py +81 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/policy.py +157 -10
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/registry/persist.py +5 -2
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/registry/schema.py +13 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/html.py +160 -1
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/pr_comment.py +188 -6
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/terminal.py +46 -15
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/rules/base_rules.yaml +13 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/scorecard.py +1 -1
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/version.py +1 -1
- safeai_static_analyzer-2.5.0/tests/test_architectural_invariants.py +320 -0
- safeai_static_analyzer-2.5.0/tests/test_architecture_diagram.py +291 -0
- safeai_static_analyzer-2.5.0/tests/test_authority_change.py +318 -0
- safeai_static_analyzer-2.5.0/tests/test_baseline_compat.py +66 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_benchmarks.py +2 -2
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_capability_diff_v2.py +1 -1
- safeai_static_analyzer-2.5.0/tests/test_evidence_contract_v7.py +338 -0
- safeai_static_analyzer-2.5.0/tests/test_exceptions.py +284 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_github_action.py +2 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_html_report.py +26 -0
- safeai_static_analyzer-2.5.0/tests/test_iac_adversarial.py +181 -0
- safeai_static_analyzer-2.5.0/tests/test_iac_benchmark.py +201 -0
- safeai_static_analyzer-2.5.0/tests/test_iac_correlation.py +270 -0
- safeai_static_analyzer-2.5.0/tests/test_iac_k8s.py +153 -0
- safeai_static_analyzer-2.5.0/tests/test_iac_linking.py +100 -0
- safeai_static_analyzer-2.5.0/tests/test_iac_semantics.py +93 -0
- safeai_static_analyzer-2.5.0/tests/test_iac_terraform.py +252 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_manifest_contract.py +122 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_plugin_sdk.py +24 -3
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_policy.py +154 -6
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_pr_comment.py +187 -0
- safeai_static_analyzer-2.5.0/tests/test_pr_paths.py +163 -0
- safeai_static_analyzer-2.5.0/tests/test_release_workflow.py +331 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_scorecard.py +2 -2
- safeai_static_analyzer-2.5.0/tests/test_terminal_report.py +116 -0
- safeai_static_analyzer-2.5.0/tests/test_unknown_authority.py +175 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/LICENSE +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/SafeAI_Static_Analyzer.egg-info/dependency_links.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/SafeAI_Static_Analyzer.egg-info/entry_points.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/SafeAI_Static_Analyzer.egg-info/requires.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/SafeAI_Static_Analyzer.egg-info/top_level.txt +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/pyproject.toml +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/__main__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/aggregation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/capabilities.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/component_diff.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/components.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/dependency_correlation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/escalation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/escalation_remediation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/import_graph.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/project_graph.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/semantic.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/target_taxonomy.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/tool_identity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/tool_implementation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analysis/tool_surface.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/capability/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/capability/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/claude_code/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/claude_code/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/data_leakage/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/data_leakage/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/dataflow/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/dataflow/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/env_dependency/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/env_dependency/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/governance/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/governance/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/mcp/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/mcp/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/mcp/compatibility.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/mcp/schema.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/mcp/validators.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/model_config/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/model_config/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/prompt/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/prompt/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/prompt_file/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/prompt_file/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/skill/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/skill/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/tool_def/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/tool_def/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/workflow/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/analyzers/workflow/analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/cmd/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/cmd/manifest_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/cmd/registry_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/controls/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/controls/catalogs.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/controls/mappings.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/engine/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/engine/file_discovery.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/engine/metadata.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/engine/scan.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/autogen/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/azure_foundry/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/azure_foundry/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/bedrock_agent/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/bedrock_agent/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/claude_code/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/claude_code/commands.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/claude_code/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/claude_code/permissions.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/claude_code/settings.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/copilot/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/copilot/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/crewai/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/crewai/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/cursorrules/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/cursorrules/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/dify/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/dify/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/google_adk/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/google_adk/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/haystack/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/haystack/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/langchain/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/langchain/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/langgraph/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/langgraph/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/llamaindex/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/llamaindex/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/mastra/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/mastra/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/microsoft_agent/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/microsoft_agent/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/n8n/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/n8n/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/openai_agents/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/openai_agents/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/openclaw/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/openclaw/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/semantic_kernel/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/semantic_kernel/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/windsurf/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/frameworks/windsurf/parser.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/baseline.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/ci_context.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/exporter.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/fingerprints.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/identity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/importer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/integrity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/lockfile.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/registry/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/registry/connection.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/registry/queries.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/suppressions.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/kya/util.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/failure_matrix.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/html_kit.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/json_report.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/registry_html.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/report/sarif.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/rules/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/rules/loader.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/rules/pack_test.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/scoring/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/scoring/engine.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/severity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/telemetry/__init__.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/telemetry/client.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/telemetry/config.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/safeai/telemetry/schema.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/setup.cfg +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_adapter_dataflow.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_assurance.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_baseline.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_capability_detection.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_ci_context.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_claude_code_deep.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_compatibility.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_component_graph.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_component_hash.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_confidence_arbitration.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_config_adapters.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_control_mappings.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_crewai_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_cursorrules_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_dco.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_env_dependency.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_escalation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_escalation_remediation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_evidence_type.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_fingerprints.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_governance_analyzer.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_init_and_rules.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_kya_integration.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_kya_manifest.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_langgraph_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_llamaindex_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_manifest_integrity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_mcp_tool_poisoning.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_mcp_validation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_n8n_workflow.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_parser_aggregation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_phase15.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_pr_comment_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_quality_gates.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_registry.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_registry_cli.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_registry_html.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_regression_fixtures.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_release_assets.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_release_fixes.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_release_validation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_rules_loader_determinism.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_sarif.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_scan_framework.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_scan_phase11.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_scoring.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_semantic.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_severity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_suppressions.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_target_taxonomy_engine.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_telemetry.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_tool_identity.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_tool_implementation.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.0}/tests/test_version.py +0 -0
- {safeai_static_analyzer-2.3.0 → safeai_static_analyzer-2.5.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.5.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,17 +31,29 @@ 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)
|
|
38
38
|
[](https://safeai-analyzer.ikaruscareer.com)
|
|
39
|
-
[](https://github.com/ikaruscareer/SafeAI/releases/tag/v2.4.0)
|
|
40
40
|
[](https://www.bestpractices.dev/en/projects/14126)
|
|
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,13 @@ 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) |
|
|
606
|
+
| [@be-student](https://github.com/be-student) | Portable registry import, MCP tool-pattern golden fixtures, canonical release checklist (PRs #123, #124, #125) |
|
|
607
|
+
| [@Karthik9849309055](https://github.com/Karthik9849309055) | Multi-framework scan automation script (PR #161) |
|
|
608
|
+
| [@chenzeyan54-commits](https://github.com/chenzeyan54-commits) | Terminal output sanitization against ANSI/OSC injection (PR #203) |
|
|
609
|
+
| [@HarshRajSinghania](https://github.com/HarshRajSinghania) | PR comment markdown injection sanitization (PR #204) |
|
|
610
|
+
| [@thadidaniel-ctrl](https://github.com/thadidaniel-ctrl) | Release workflow supply-chain posture tests (PR #206) |
|
|
533
611
|
|
|
534
612
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get involved.
|
|
535
613
|
|
|
@@ -1,14 +1,26 @@
|
|
|
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)
|
|
5
5
|
[](https://safeai-analyzer.ikaruscareer.com)
|
|
6
|
-
[](https://github.com/ikaruscareer/SafeAI/releases/tag/v2.4.0)
|
|
7
7
|
[](https://www.bestpractices.dev/en/projects/14126)
|
|
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,13 @@ 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) |
|
|
573
|
+
| [@be-student](https://github.com/be-student) | Portable registry import, MCP tool-pattern golden fixtures, canonical release checklist (PRs #123, #124, #125) |
|
|
574
|
+
| [@Karthik9849309055](https://github.com/Karthik9849309055) | Multi-framework scan automation script (PR #161) |
|
|
575
|
+
| [@chenzeyan54-commits](https://github.com/chenzeyan54-commits) | Terminal output sanitization against ANSI/OSC injection (PR #203) |
|
|
576
|
+
| [@HarshRajSinghania](https://github.com/HarshRajSinghania) | PR comment markdown injection sanitization (PR #204) |
|
|
577
|
+
| [@thadidaniel-ctrl](https://github.com/thadidaniel-ctrl) | Release workflow supply-chain posture tests (PR #206) |
|
|
500
578
|
|
|
501
579
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get involved.
|
|
502
580
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SafeAI-Static-Analyzer
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.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,17 +31,29 @@ 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)
|
|
38
38
|
[](https://safeai-analyzer.ikaruscareer.com)
|
|
39
|
-
[](https://github.com/ikaruscareer/SafeAI/releases/tag/v2.4.0)
|
|
40
40
|
[](https://www.bestpractices.dev/en/projects/14126)
|
|
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,13 @@ 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) |
|
|
606
|
+
| [@be-student](https://github.com/be-student) | Portable registry import, MCP tool-pattern golden fixtures, canonical release checklist (PRs #123, #124, #125) |
|
|
607
|
+
| [@Karthik9849309055](https://github.com/Karthik9849309055) | Multi-framework scan automation script (PR #161) |
|
|
608
|
+
| [@chenzeyan54-commits](https://github.com/chenzeyan54-commits) | Terminal output sanitization against ANSI/OSC injection (PR #203) |
|
|
609
|
+
| [@HarshRajSinghania](https://github.com/HarshRajSinghania) | PR comment markdown injection sanitization (PR #204) |
|
|
610
|
+
| [@thadidaniel-ctrl](https://github.com/thadidaniel-ctrl) | Release workflow supply-chain posture tests (PR #206) |
|
|
533
611
|
|
|
534
612
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get involved.
|
|
535
613
|
|
|
@@ -22,6 +22,7 @@ safeai/analysis/components.py
|
|
|
22
22
|
safeai/analysis/dependency_correlation.py
|
|
23
23
|
safeai/analysis/escalation.py
|
|
24
24
|
safeai/analysis/escalation_remediation.py
|
|
25
|
+
safeai/analysis/iac_correlation.py
|
|
25
26
|
safeai/analysis/import_graph.py
|
|
26
27
|
safeai/analysis/project_graph.py
|
|
27
28
|
safeai/analysis/semantic.py
|
|
@@ -115,12 +116,19 @@ safeai/frameworks/semantic_kernel/__init__.py
|
|
|
115
116
|
safeai/frameworks/semantic_kernel/parser.py
|
|
116
117
|
safeai/frameworks/windsurf/__init__.py
|
|
117
118
|
safeai/frameworks/windsurf/parser.py
|
|
119
|
+
safeai/iac/__init__.py
|
|
120
|
+
safeai/iac/k8s.py
|
|
121
|
+
safeai/iac/linking.py
|
|
122
|
+
safeai/iac/model.py
|
|
123
|
+
safeai/iac/semantics.py
|
|
124
|
+
safeai/iac/terraform.py
|
|
118
125
|
safeai/kya/__init__.py
|
|
119
126
|
safeai/kya/assurance.py
|
|
120
127
|
safeai/kya/baseline.py
|
|
121
128
|
safeai/kya/ci_context.py
|
|
122
129
|
safeai/kya/contract.py
|
|
123
130
|
safeai/kya/enrich.py
|
|
131
|
+
safeai/kya/exceptions.py
|
|
124
132
|
safeai/kya/exporter.py
|
|
125
133
|
safeai/kya/fingerprints.py
|
|
126
134
|
safeai/kya/identity.py
|
|
@@ -156,8 +164,12 @@ safeai/telemetry/client.py
|
|
|
156
164
|
safeai/telemetry/config.py
|
|
157
165
|
safeai/telemetry/schema.py
|
|
158
166
|
tests/test_adapter_dataflow.py
|
|
167
|
+
tests/test_architectural_invariants.py
|
|
168
|
+
tests/test_architecture_diagram.py
|
|
159
169
|
tests/test_assurance.py
|
|
170
|
+
tests/test_authority_change.py
|
|
160
171
|
tests/test_baseline.py
|
|
172
|
+
tests/test_baseline_compat.py
|
|
161
173
|
tests/test_benchmarks.py
|
|
162
174
|
tests/test_capability_detection.py
|
|
163
175
|
tests/test_capability_diff_v2.py
|
|
@@ -175,11 +187,20 @@ tests/test_dco.py
|
|
|
175
187
|
tests/test_env_dependency.py
|
|
176
188
|
tests/test_escalation.py
|
|
177
189
|
tests/test_escalation_remediation.py
|
|
190
|
+
tests/test_evidence_contract_v7.py
|
|
178
191
|
tests/test_evidence_type.py
|
|
192
|
+
tests/test_exceptions.py
|
|
179
193
|
tests/test_fingerprints.py
|
|
180
194
|
tests/test_github_action.py
|
|
181
195
|
tests/test_governance_analyzer.py
|
|
182
196
|
tests/test_html_report.py
|
|
197
|
+
tests/test_iac_adversarial.py
|
|
198
|
+
tests/test_iac_benchmark.py
|
|
199
|
+
tests/test_iac_correlation.py
|
|
200
|
+
tests/test_iac_k8s.py
|
|
201
|
+
tests/test_iac_linking.py
|
|
202
|
+
tests/test_iac_semantics.py
|
|
203
|
+
tests/test_iac_terraform.py
|
|
183
204
|
tests/test_init_and_rules.py
|
|
184
205
|
tests/test_kya_integration.py
|
|
185
206
|
tests/test_kya_manifest.py
|
|
@@ -196,6 +217,7 @@ tests/test_plugin_sdk.py
|
|
|
196
217
|
tests/test_policy.py
|
|
197
218
|
tests/test_pr_comment.py
|
|
198
219
|
tests/test_pr_comment_cli.py
|
|
220
|
+
tests/test_pr_paths.py
|
|
199
221
|
tests/test_quality_gates.py
|
|
200
222
|
tests/test_registry.py
|
|
201
223
|
tests/test_registry_cli.py
|
|
@@ -204,6 +226,7 @@ tests/test_regression_fixtures.py
|
|
|
204
226
|
tests/test_release_assets.py
|
|
205
227
|
tests/test_release_fixes.py
|
|
206
228
|
tests/test_release_validation.py
|
|
229
|
+
tests/test_release_workflow.py
|
|
207
230
|
tests/test_rules_loader_determinism.py
|
|
208
231
|
tests/test_sarif.py
|
|
209
232
|
tests/test_scan_framework.py
|
|
@@ -215,7 +238,9 @@ tests/test_severity.py
|
|
|
215
238
|
tests/test_suppressions.py
|
|
216
239
|
tests/test_target_taxonomy_engine.py
|
|
217
240
|
tests/test_telemetry.py
|
|
241
|
+
tests/test_terminal_report.py
|
|
218
242
|
tests/test_tool_identity.py
|
|
219
243
|
tests/test_tool_implementation.py
|
|
244
|
+
tests/test_unknown_authority.py
|
|
220
245
|
tests/test_version.py
|
|
221
246
|
tests/test_windsurf_framework.py
|