sqlguard-ninja 0.4.0__tar.gz → 0.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.
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/CHANGELOG.md +19 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/PKG-INFO +30 -17
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/README.md +25 -16
- {sqlguard_ninja-0.4.0/benchmarks/results/v1.1.0 → sqlguard_ninja-0.5.0/benchmarks/baselines}/native.json +1815 -1257
- sqlguard_ninja-0.5.0/benchmarks/datasets/v1/cases/09_mysql.yaml +143 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/manifest.yaml +1 -1
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/agent-sql-guard.csv +1071 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/agent-sql-guard.json +20729 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/agent-sql-guard.md +112 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/krish2105-sqlguard.csv +1071 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/krish2105-sqlguard.json +20666 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/krish2105-sqlguard.md +112 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/native.csv +1071 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/native.json +21042 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/native.md +80 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/sql-guardrail.csv +1071 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/sql-guardrail.json +21348 -0
- sqlguard_ninja-0.5.0/benchmarks/results/v1.2.0/sql-guardrail.md +108 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/architecture/ARCHITECTURE_DECISIONS.md +20 -0
- sqlguard_ninja-0.5.0/docs/benchmarks/RESULTS_v1.2.md +63 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/development/IMPLEMENTATION_PROGRESS.md +2 -1
- sqlguard_ninja-0.5.0/docs/development/NEXT_ACTIONS.md +6 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/development/TEST_EVIDENCE.md +3 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/development/progress.json +8 -5
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/AGENT_INTEGRATION.md +21 -10
- sqlguard_ninja-0.5.0/docs/guides/DATABASE_COMPATIBILITY.md +53 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/MCP_INTEGRATION.md +1 -1
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/POLICY_REFERENCE.md +9 -3
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/QUERY_COST.md +3 -2
- sqlguard_ninja-0.5.0/docs/releases/v0.5.0.md +20 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/security/THREAT_MODEL.md +1 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/pyproject.toml +4 -2
- sqlguard_ninja-0.5.0/src/sqlguard_ninja/_version.py +1 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/fixtures.py +9 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/analysis.py +1 -1
- sqlguard_ninja-0.5.0/src/sqlguard_ninja/integrations/mysql.py +108 -0
- sqlguard_ninja-0.5.0/tests/integration/test_mysql.py +117 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_dataset.py +1 -1
- sqlguard_ninja-0.5.0/tests/unit/test_experimental_dialects.py +39 -0
- sqlguard_ninja-0.5.0/tests/unit/test_mysql_binding.py +113 -0
- sqlguard_ninja-0.4.0/docs/development/NEXT_ACTIONS.md +0 -6
- sqlguard_ninja-0.4.0/src/sqlguard_ninja/_version.py +0 -1
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/.gitignore +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/LICENSE +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/THIRD_PARTY_NOTICES.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/external/README.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/LABEL_CHANGES.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/01_destructive.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/02_multi_statement_and_formatting.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/03_table_and_column_access.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/04_privacy.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/05_tenant_isolation.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/06_cte_nested_unicode.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/07_legitimate_lookalike_cost_dialect.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/cases/08_lineage.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/generated/grant_matrix.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/generated/label_matrix.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/generated/tenant_matrix.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/datasets/v1/generated/transforms.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/policies/retail_saas.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/agent-sql-guard.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/agent-sql-guard.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/native.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/native.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/sql-guardrail.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.0.0/sql-guardrail.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/agent-sql-guard.csv +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/agent-sql-guard.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/agent-sql-guard.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/krish2105-sqlguard.csv +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/krish2105-sqlguard.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/krish2105-sqlguard.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/native.csv +0 -0
- {sqlguard_ninja-0.4.0/benchmarks/baselines → sqlguard_ninja-0.5.0/benchmarks/results/v1.1.0}/native.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/native.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/sql-guardrail.csv +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/sql-guardrail.json +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/benchmarks/results/v1.1.0/sql-guardrail.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/benchmarks/RESULTS_v1.1.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/benchmarks/RESULTS_v1.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/development/ARCHITECTURE_MAP.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/development/DECISION_LOG.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/development/UPGRADE_MASTER_PLAN.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/BENCHMARK_BIAS_REVIEW.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/BENCHMARK_METHODOLOGY.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/CI_INTEGRATION.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/guides/POLICY_AS_CODE.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/release/FINAL_TECHNICAL_AUDIT.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/releases/v0.1.0.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/releases/v0.1.1.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/releases/v0.2.0.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/releases/v0.3.0.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/releases/v0.4.0.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/research/COMPETITIVE_ANALYSIS.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/docs/security/STATIC_ANALYSIS_LIMITS.md +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/_shared.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/fastapi/app.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/github-actions/sql-security.yml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/langchain/guarded_tool_demo.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/langgraph/real_llm_agent.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/langgraph/sql_agent_demo.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/postgresql/plan_inspection_demo.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/sdk/quickstart.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/examples/sqlite/text_to_sql_demo.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/adapters.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/builtin.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/compare.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/dataset.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/metrics.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/runner.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/translate.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/workers/_protocol.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/workers/agent_sql_guard_worker.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/workers/krish_sqlguard_worker.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/benchmarking/workers/sql_guardrail_worker.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/cli/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/cli/config.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/cli/main.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/cli/templates.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/findings.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/guard.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/lineage.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/access.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/base.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/catalog.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/functions.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/statements.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/structure.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/core/rules/tenant.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/integrations/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/integrations/audit.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/integrations/checkpoint.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/integrations/executors.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/integrations/fastapi.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/integrations/langchain.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/integrations/langgraph.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/mcp_server.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/policy/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/policy/inheritance.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/policy/model.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/policy/templates/analytics_readonly.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/policy/templates/minimal.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/policy/templates/multi_tenant_saas.yaml +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/policy/tools.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/privacy/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/privacy/rules.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/privacy/suggest.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/py.typed +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/query_cost/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/query_cost/postgres.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/query_cost/static.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/reporting/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/reporting/markdown.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/src/sqlguard_ninja/tenancy.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/conftest.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/integration/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/integration/test_corpus_sqlite_validation.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/integration/test_external_adapters.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/integration/test_frameworks.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/integration/test_mcp_server.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/integration/test_postgres.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/pg_support.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/property/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/property/test_guard_properties.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/security/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/security/test_agent_boundaries.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/security/test_corpus_native.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/security/test_tenant_rewrite.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/__init__.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/helpers.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_benchmark_engine.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_cli.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_docs.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_function_policy_mechanics.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_lineage.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_policy.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_policy_inheritance.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_policy_tools.py +0 -0
- {sqlguard_ninja-0.4.0 → sqlguard_ninja-0.5.0}/tests/unit/test_rules.py +0 -0
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes are documented here. The project follows
|
|
4
4
|
[Semantic Versioning](https://semver.org/); before 1.0, minor versions may change the API.
|
|
5
5
|
|
|
6
|
+
## [0.5.0] — 2026-10-24
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
* **MySQL 8** as a tested dialect within a documented scope: `sqlguard_ninja.integrations.mysql`
|
|
10
|
+
(`mysql_executor`: read-only transaction, `MAX_EXECUTION_TIME`, rollback; `bind_placeholders`:
|
|
11
|
+
AST-based binding of named placeholders, ADR-013), extra `[mysql]` (PyMySQL), and a MySQL 8.4
|
|
12
|
+
service-container CI job that executes every MySQL `allow` case as a SELECT-only account.
|
|
13
|
+
* Corpus **1.2.0**: 26 MySQL cases (`cases/09_mysql.yaml`); results in
|
|
14
|
+
`docs/benchmarks/RESULTS_v1.2.md`.
|
|
15
|
+
* `docs/guides/DATABASE_COMPATIBILITY.md`: compatibility matrix. SQL Server and Oracle are
|
|
16
|
+
parser-level experimental with smoke tests; they are not accepted by the MCP server.
|
|
17
|
+
* The MCP server accepts `mysql` as a dialect.
|
|
18
|
+
|
|
19
|
+
### Security
|
|
20
|
+
* MySQL identifiers are compared exactly and never case-folded (fail closed). String values
|
|
21
|
+
containing a backslash or NUL are refused at binding time. `mysql_executor` refuses sessions
|
|
22
|
+
whose `sql_mode` changes lexing (`ANSI_QUOTES`, `NO_BACKSLASH_ESCAPES`, `PIPES_AS_CONCAT`,
|
|
23
|
+
`HIGH_NOT_PRECEDENCE`, `ANSI`); threat model T18.
|
|
24
|
+
|
|
6
25
|
## [0.4.0] — 2026-10-24
|
|
7
26
|
|
|
8
27
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sqlguard-ninja
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Security testing, policy enforcement, agent integration, privacy analysis and CI benchmarking for LLM-generated SQL.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Pratik653/SQLGuard_Ninjapy
|
|
6
6
|
Project-URL: Documentation, https://github.com/Pratik653/SQLGuard_Ninjapy/tree/main/docs
|
|
@@ -31,6 +31,7 @@ Requires-Dist: langchain-core>=0.3; extra == 'all'
|
|
|
31
31
|
Requires-Dist: langgraph>=0.2; extra == 'all'
|
|
32
32
|
Requires-Dist: mcp<3,>=2.3; extra == 'all'
|
|
33
33
|
Requires-Dist: psycopg[binary]>=3.1; extra == 'all'
|
|
34
|
+
Requires-Dist: pymysql>=1.1; extra == 'all'
|
|
34
35
|
Provides-Extra: dev
|
|
35
36
|
Requires-Dist: build>=1.2; extra == 'dev'
|
|
36
37
|
Requires-Dist: fastapi>=0.110; extra == 'dev'
|
|
@@ -41,6 +42,7 @@ Requires-Dist: langgraph>=0.2; extra == 'dev'
|
|
|
41
42
|
Requires-Dist: mcp<3,>=2.3; extra == 'dev'
|
|
42
43
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
43
44
|
Requires-Dist: psycopg[binary]>=3.1; extra == 'dev'
|
|
45
|
+
Requires-Dist: pymysql>=1.1; extra == 'dev'
|
|
44
46
|
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
45
47
|
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
46
48
|
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
@@ -54,6 +56,8 @@ Requires-Dist: langchain-core>=0.3; extra == 'langgraph'
|
|
|
54
56
|
Requires-Dist: langgraph>=0.2; extra == 'langgraph'
|
|
55
57
|
Provides-Extra: mcp
|
|
56
58
|
Requires-Dist: mcp<3,>=2.3; extra == 'mcp'
|
|
59
|
+
Provides-Extra: mysql
|
|
60
|
+
Requires-Dist: pymysql>=1.1; extra == 'mysql'
|
|
57
61
|
Provides-Extra: postgres
|
|
58
62
|
Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
|
|
59
63
|
Description-Content-Type: text/markdown
|
|
@@ -181,8 +185,8 @@ result = guard.validate(
|
|
|
181
185
|
role="hr_analyst",
|
|
182
186
|
dialect="postgres",
|
|
183
187
|
)
|
|
184
|
-
result.allowed
|
|
185
|
-
result.findings
|
|
188
|
+
result.allowed # True
|
|
189
|
+
result.findings # () - structured Finding objects with rule_id, action, message, remediation
|
|
186
190
|
|
|
187
191
|
guard.validate("SELECT full_name, salary FROM employees", role="hr_analyst").explain()
|
|
188
192
|
# DENY:
|
|
@@ -195,16 +199,21 @@ guard.validate("SELECT full_name, salary FROM employees", role="hr_analyst").exp
|
|
|
195
199
|
```python
|
|
196
200
|
from sqlguard_ninja.integrations import RequestContext, SQLCheckpoint
|
|
197
201
|
from sqlguard_ninja.integrations.langgraph import (
|
|
198
|
-
CONTEXT_KEY,
|
|
202
|
+
CONTEXT_KEY,
|
|
203
|
+
make_execute_node,
|
|
204
|
+
make_guard_node,
|
|
205
|
+
route_after_guard,
|
|
206
|
+
)
|
|
199
207
|
|
|
200
208
|
checkpoint = SQLCheckpoint(guard, mode="block", max_denied_attempts=3)
|
|
201
209
|
graph.add_node("guard", make_guard_node(checkpoint))
|
|
202
|
-
graph.add_node("execute", make_execute_node(checkpoint, executor))
|
|
203
|
-
graph.add_conditional_edges(
|
|
204
|
-
|
|
210
|
+
graph.add_node("execute", make_execute_node(checkpoint, executor)) # re-validates
|
|
211
|
+
graph.add_conditional_edges(
|
|
212
|
+
"guard", route_after_guard(3), {"execute": "execute", "revise": "generate", "end": END}
|
|
213
|
+
)
|
|
205
214
|
|
|
206
215
|
ctx = RequestContext(principal=user.id, role=user.role, tenant_id=user.tenant_id)
|
|
207
|
-
app.invoke(state, config={"configurable": {CONTEXT_KEY: ctx}})
|
|
216
|
+
app.invoke(state, config={"configurable": {CONTEXT_KEY: ctx}}) # nodes cannot alter config
|
|
208
217
|
```
|
|
209
218
|
|
|
210
219
|
More in [AGENT_INTEGRATION.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/AGENT_INTEGRATION.md): the LangChain tool (its
|
|
@@ -298,8 +307,10 @@ rolled-back transaction:
|
|
|
298
307
|
|
|
299
308
|
```python
|
|
300
309
|
from sqlguard_ninja.query_cost.postgres import PostgresPlanInspector
|
|
310
|
+
|
|
301
311
|
report = PostgresPlanInspector(guard, lambda: psycopg.connect(READER_DSN)).inspect(
|
|
302
|
-
sql, role="support_analyst", context={"tenant_id": 1}
|
|
312
|
+
sql, role="support_analyst", context={"tenant_id": 1}
|
|
313
|
+
)
|
|
303
314
|
report.total_cost, report.plan_rows, report.static.score, report.findings
|
|
304
315
|
```
|
|
305
316
|
|
|
@@ -314,16 +325,16 @@ sqlninja benchmark run --dataset builtin:v1 --adapter external:sql-guardrail
|
|
|
314
325
|
sqlninja benchmark compare --baseline benchmarks/baselines/native.json --candidate results/latest.json
|
|
315
326
|
```
|
|
316
327
|
|
|
317
|
-
Results for corpus v1.
|
|
328
|
+
Results for corpus v1.2.0 (577 cases, 1,070 evaluations; SQLGuard Ninja 0.5.0; Windows 11,
|
|
318
329
|
Python 3.11). Intervals are 95% Wilson intervals. Details, CSV and raw files:
|
|
319
|
-
[RESULTS_v1.
|
|
330
|
+
[RESULTS_v1.2.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.2.md).
|
|
320
331
|
|
|
321
332
|
| Validator | Recall (95% CI) | Precision | F1 | FPR (95% CI) | Recall / FPR within declared capability | p95 ms |
|
|
322
333
|
|---|---:|---:|---:|---:|---:|---:|
|
|
323
|
-
| SQLGuard Ninja 0.
|
|
324
|
-
| sql-guardrail 0.5.2 | 98.
|
|
325
|
-
| agent-sql-guard 0.2.0 |
|
|
326
|
-
| krish2105/sqlguard 0.1.0 |
|
|
334
|
+
| SQLGuard Ninja 0.5.0 | 100.0% (99.4–100.0) | 100.0% | 1.000 | 0.0% (0.0–0.9) | 100.0% / 0.0% | 3.36 |
|
|
335
|
+
| sql-guardrail 0.5.2 | 98.2% (96.9–99.0) | 84.7% | 0.909 | 24.8% (21.1–29.0) | 98.3% / 19.7% | 1.84 |
|
|
336
|
+
| agent-sql-guard 0.2.0 | 66.8% (63.0–70.4) | 85.1% | 0.748 | 16.3% (13.2–20.0) | 89.4% / 17.7% | 1.44 |
|
|
337
|
+
| krish2105/sqlguard 0.1.0 | 64.8% (61.0–68.5) | 89.4% | 0.752 | 10.7% (8.2–14.0) | 83.5% / 5.2% | 1.42 |
|
|
327
338
|
|
|
328
339
|
**All of these are internal results.** The corpus was written by this project, alongside the
|
|
329
340
|
engine. The native 100% shows consistency with the documented semantics, not independent
|
|
@@ -390,8 +401,10 @@ writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](https://
|
|
|
390
401
|
## Supported versions
|
|
391
402
|
|
|
392
403
|
* Python 3.11, 3.12, 3.13 (CI matrix on Linux and Windows).
|
|
393
|
-
* SQL dialects: **PostgreSQL** (tested against PostgreSQL 16) and **
|
|
394
|
-
|
|
404
|
+
* SQL dialects: **PostgreSQL** (tested against PostgreSQL 16), **SQLite**, and **MySQL 8**
|
|
405
|
+
(tested against MySQL 8.4 in CI, within the documented scope: identifier case is not folded,
|
|
406
|
+
named placeholders only). SQL Server and Oracle are parser-level **experimental**; others are
|
|
407
|
+
untested. See the [compatibility matrix](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/DATABASE_COMPATIBILITY.md).
|
|
395
408
|
|
|
396
409
|
## Development
|
|
397
410
|
|
|
@@ -121,8 +121,8 @@ result = guard.validate(
|
|
|
121
121
|
role="hr_analyst",
|
|
122
122
|
dialect="postgres",
|
|
123
123
|
)
|
|
124
|
-
result.allowed
|
|
125
|
-
result.findings
|
|
124
|
+
result.allowed # True
|
|
125
|
+
result.findings # () - structured Finding objects with rule_id, action, message, remediation
|
|
126
126
|
|
|
127
127
|
guard.validate("SELECT full_name, salary FROM employees", role="hr_analyst").explain()
|
|
128
128
|
# DENY:
|
|
@@ -135,16 +135,21 @@ guard.validate("SELECT full_name, salary FROM employees", role="hr_analyst").exp
|
|
|
135
135
|
```python
|
|
136
136
|
from sqlguard_ninja.integrations import RequestContext, SQLCheckpoint
|
|
137
137
|
from sqlguard_ninja.integrations.langgraph import (
|
|
138
|
-
CONTEXT_KEY,
|
|
138
|
+
CONTEXT_KEY,
|
|
139
|
+
make_execute_node,
|
|
140
|
+
make_guard_node,
|
|
141
|
+
route_after_guard,
|
|
142
|
+
)
|
|
139
143
|
|
|
140
144
|
checkpoint = SQLCheckpoint(guard, mode="block", max_denied_attempts=3)
|
|
141
145
|
graph.add_node("guard", make_guard_node(checkpoint))
|
|
142
|
-
graph.add_node("execute", make_execute_node(checkpoint, executor))
|
|
143
|
-
graph.add_conditional_edges(
|
|
144
|
-
|
|
146
|
+
graph.add_node("execute", make_execute_node(checkpoint, executor)) # re-validates
|
|
147
|
+
graph.add_conditional_edges(
|
|
148
|
+
"guard", route_after_guard(3), {"execute": "execute", "revise": "generate", "end": END}
|
|
149
|
+
)
|
|
145
150
|
|
|
146
151
|
ctx = RequestContext(principal=user.id, role=user.role, tenant_id=user.tenant_id)
|
|
147
|
-
app.invoke(state, config={"configurable": {CONTEXT_KEY: ctx}})
|
|
152
|
+
app.invoke(state, config={"configurable": {CONTEXT_KEY: ctx}}) # nodes cannot alter config
|
|
148
153
|
```
|
|
149
154
|
|
|
150
155
|
More in [AGENT_INTEGRATION.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/AGENT_INTEGRATION.md): the LangChain tool (its
|
|
@@ -238,8 +243,10 @@ rolled-back transaction:
|
|
|
238
243
|
|
|
239
244
|
```python
|
|
240
245
|
from sqlguard_ninja.query_cost.postgres import PostgresPlanInspector
|
|
246
|
+
|
|
241
247
|
report = PostgresPlanInspector(guard, lambda: psycopg.connect(READER_DSN)).inspect(
|
|
242
|
-
sql, role="support_analyst", context={"tenant_id": 1}
|
|
248
|
+
sql, role="support_analyst", context={"tenant_id": 1}
|
|
249
|
+
)
|
|
243
250
|
report.total_cost, report.plan_rows, report.static.score, report.findings
|
|
244
251
|
```
|
|
245
252
|
|
|
@@ -254,16 +261,16 @@ sqlninja benchmark run --dataset builtin:v1 --adapter external:sql-guardrail
|
|
|
254
261
|
sqlninja benchmark compare --baseline benchmarks/baselines/native.json --candidate results/latest.json
|
|
255
262
|
```
|
|
256
263
|
|
|
257
|
-
Results for corpus v1.
|
|
264
|
+
Results for corpus v1.2.0 (577 cases, 1,070 evaluations; SQLGuard Ninja 0.5.0; Windows 11,
|
|
258
265
|
Python 3.11). Intervals are 95% Wilson intervals. Details, CSV and raw files:
|
|
259
|
-
[RESULTS_v1.
|
|
266
|
+
[RESULTS_v1.2.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.2.md).
|
|
260
267
|
|
|
261
268
|
| Validator | Recall (95% CI) | Precision | F1 | FPR (95% CI) | Recall / FPR within declared capability | p95 ms |
|
|
262
269
|
|---|---:|---:|---:|---:|---:|---:|
|
|
263
|
-
| SQLGuard Ninja 0.
|
|
264
|
-
| sql-guardrail 0.5.2 | 98.
|
|
265
|
-
| agent-sql-guard 0.2.0 |
|
|
266
|
-
| krish2105/sqlguard 0.1.0 |
|
|
270
|
+
| SQLGuard Ninja 0.5.0 | 100.0% (99.4–100.0) | 100.0% | 1.000 | 0.0% (0.0–0.9) | 100.0% / 0.0% | 3.36 |
|
|
271
|
+
| sql-guardrail 0.5.2 | 98.2% (96.9–99.0) | 84.7% | 0.909 | 24.8% (21.1–29.0) | 98.3% / 19.7% | 1.84 |
|
|
272
|
+
| agent-sql-guard 0.2.0 | 66.8% (63.0–70.4) | 85.1% | 0.748 | 16.3% (13.2–20.0) | 89.4% / 17.7% | 1.44 |
|
|
273
|
+
| krish2105/sqlguard 0.1.0 | 64.8% (61.0–68.5) | 89.4% | 0.752 | 10.7% (8.2–14.0) | 83.5% / 5.2% | 1.42 |
|
|
267
274
|
|
|
268
275
|
**All of these are internal results.** The corpus was written by this project, alongside the
|
|
269
276
|
engine. The native 100% shows consistency with the documented semantics, not independent
|
|
@@ -330,8 +337,10 @@ writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](https://
|
|
|
330
337
|
## Supported versions
|
|
331
338
|
|
|
332
339
|
* Python 3.11, 3.12, 3.13 (CI matrix on Linux and Windows).
|
|
333
|
-
* SQL dialects: **PostgreSQL** (tested against PostgreSQL 16) and **
|
|
334
|
-
|
|
340
|
+
* SQL dialects: **PostgreSQL** (tested against PostgreSQL 16), **SQLite**, and **MySQL 8**
|
|
341
|
+
(tested against MySQL 8.4 in CI, within the documented scope: identifier case is not folded,
|
|
342
|
+
named placeholders only). SQL Server and Oracle are parser-level **experimental**; others are
|
|
343
|
+
untested. See the [compatibility matrix](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/DATABASE_COMPATIBILITY.md).
|
|
335
344
|
|
|
336
345
|
## Development
|
|
337
346
|
|