sqlguard-ninja 0.1.1__tar.gz → 0.2.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.1.1 → sqlguard_ninja-0.2.0}/CHANGELOG.md +24 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/PKG-INFO +22 -20
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/README.md +21 -19
- {sqlguard_ninja-0.1.1/benchmarks/results/v1.0.0 → sqlguard_ninja-0.2.0/benchmarks/baselines}/native.json +4844 -1315
- sqlguard_ninja-0.2.0/benchmarks/datasets/v1/LABEL_CHANGES.yaml +22 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/04_privacy.yaml +5 -4
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/05_tenant_isolation.yaml +5 -2
- sqlguard_ninja-0.2.0/benchmarks/datasets/v1/cases/08_lineage.yaml +150 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/manifest.yaml +1 -1
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.csv +1045 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.json +20184 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.md +110 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.csv +1045 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.json +20121 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.md +110 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.csv +1045 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.json +20484 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.md +78 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.csv +1045 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.json +20779 -0
- sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.md +103 -0
- sqlguard_ninja-0.2.0/docs/benchmarks/RESULTS_v1.1.md +48 -0
- sqlguard_ninja-0.2.0/docs/development/ARCHITECTURE_MAP.md +47 -0
- sqlguard_ninja-0.2.0/docs/development/DECISION_LOG.md +9 -0
- sqlguard_ninja-0.2.0/docs/development/IMPLEMENTATION_PROGRESS.md +7 -0
- sqlguard_ninja-0.2.0/docs/development/NEXT_ACTIONS.md +5 -0
- sqlguard_ninja-0.2.0/docs/development/TEST_EVIDENCE.md +7 -0
- sqlguard_ninja-0.2.0/docs/development/UPGRADE_MASTER_PLAN.md +25 -0
- sqlguard_ninja-0.2.0/docs/development/progress.json +106 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/BENCHMARK_BIAS_REVIEW.md +1 -1
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/BENCHMARK_METHODOLOGY.md +7 -4
- sqlguard_ninja-0.2.0/docs/releases/v0.2.0.md +27 -0
- sqlguard_ninja-0.2.0/src/sqlguard_ninja/_version.py +1 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/compare.py +8 -1
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/dataset.py +38 -2
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/metrics.py +66 -2
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/runner.py +35 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/config.py +2 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/main.py +34 -5
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/analysis.py +9 -1
- sqlguard_ninja-0.2.0/src/sqlguard_ninja/core/lineage.py +199 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/tenant.py +56 -25
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/rules.py +53 -14
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/reporting/markdown.py +36 -5
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_benchmark_engine.py +77 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_cli.py +47 -0
- sqlguard_ninja-0.2.0/tests/unit/test_lineage.py +84 -0
- sqlguard_ninja-0.1.1/src/sqlguard_ninja/_version.py +0 -1
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/.gitignore +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/LICENSE +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/THIRD_PARTY_NOTICES.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/external/README.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/01_destructive.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/02_multi_statement_and_formatting.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/03_table_and_column_access.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/06_cte_nested_unicode.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/07_legitimate_lookalike_cost_dialect.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/grant_matrix.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/label_matrix.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/tenant_matrix.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/transforms.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/policies/retail_saas.yaml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/agent-sql-guard.json +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/agent-sql-guard.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.json +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.md +0 -0
- {sqlguard_ninja-0.1.1/benchmarks/baselines → sqlguard_ninja-0.2.0/benchmarks/results/v1.0.0}/native.json +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/native.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/sql-guardrail.json +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/sql-guardrail.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/architecture/ARCHITECTURE_DECISIONS.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/benchmarks/RESULTS_v1.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/AGENT_INTEGRATION.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/CI_INTEGRATION.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/POLICY_REFERENCE.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/QUERY_COST.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/release/FINAL_TECHNICAL_AUDIT.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/releases/v0.1.0.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/releases/v0.1.1.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/research/COMPETITIVE_ANALYSIS.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/security/STATIC_ANALYSIS_LIMITS.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/security/THREAT_MODEL.md +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/_shared.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/fastapi/app.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/github-actions/sql-security.yml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/langchain/guarded_tool_demo.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/langgraph/real_llm_agent.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/langgraph/sql_agent_demo.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/postgresql/plan_inspection_demo.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/sdk/quickstart.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/sqlite/text_to_sql_demo.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/pyproject.toml +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/adapters.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/builtin.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/fixtures.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/translate.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/_protocol.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/agent_sql_guard_worker.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/krish_sqlguard_worker.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/sql_guardrail_worker.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/templates.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/findings.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/guard.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/access.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/base.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/catalog.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/functions.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/statements.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/structure.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/audit.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/checkpoint.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/executors.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/fastapi.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/langchain.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/langgraph.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/policy/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/policy/model.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/suggest.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/py.typed +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/postgres.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/static.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/reporting/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/conftest.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_corpus_sqlite_validation.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_external_adapters.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_frameworks.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_postgres.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/pg_support.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/property/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/property/test_guard_properties.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/security/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/security/test_agent_boundaries.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/security/test_corpus_native.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/__init__.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/helpers.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_dataset.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_docs.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_function_policy_mechanics.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_policy.py +0 -0
- {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_rules.py +0 -0
|
@@ -3,6 +3,30 @@
|
|
|
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.2.0] — 2026-10-24
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
* **Lineage-aware privacy** (`core/lineage.py`). An `aggregate_only` column projected raw in a
|
|
10
|
+
CTE or derived table is accepted only when every downstream consumer aggregates it
|
|
11
|
+
statistically. Whole-row use, filters, ordering, windows, MIN/MAX and a raw use by any
|
|
12
|
+
consumer stay denied (issue #8).
|
|
13
|
+
* **Tenant push-down.** An outer tenant pin on an unmodified projection of the tenant column
|
|
14
|
+
satisfies the inner read when the inner scope has no aggregation, window, LIMIT, OFFSET or
|
|
15
|
+
FETCH and every consumer pins it, recursively (issue #9).
|
|
16
|
+
* The small-cohort check follows identifiers through CTEs and derived tables, so the lineage
|
|
17
|
+
relaxation cannot bypass it (found by new boundary case LIN-012).
|
|
18
|
+
* Privacy findings carry structured lineage metadata (base column, JSON path, scope, labels).
|
|
19
|
+
* Benchmark: `internal` / `independent` dataset tiers, flag basis (policy vs unsupported SQL),
|
|
20
|
+
F1, 95% Wilson intervals, throughput, CSV output (`--csv`), per-file SHA-256 dataset hashes
|
|
21
|
+
in results and `sqlninja dataset stats`.
|
|
22
|
+
* Approved-relabel workflow: `LABEL_CHANGES.yaml` (CODEOWNERS-protected) lists reviewed label
|
|
23
|
+
changes; `benchmark compare --approved-label-changes` / `ci.approved_label_changes`.
|
|
24
|
+
* Corpus 1.1.0: 21 lineage boundary cases; 2 approved relabels (PRV-026, TEN-021).
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
* Decisions changed for exactly two corpus cases (PRV-026, TEN-021: deny → allow); all other
|
|
28
|
+
1,042 evaluations are unchanged.
|
|
29
|
+
|
|
6
30
|
## [0.1.1] — 2026-10-24
|
|
7
31
|
|
|
8
32
|
Documentation and governance patch. No changes to policy decisions.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sqlguard-ninja
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.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
|
|
@@ -70,7 +70,7 @@ the *authenticated* caller: which tables and columns a role may use, which data
|
|
|
70
70
|
appear only in aggregates or only after human approval, and which tenant the caller belongs
|
|
71
71
|
to. It records an audit trail and gives the agent an explanation it can act on.
|
|
72
72
|
|
|
73
|
-
It ships with a labelled benchmark corpus (
|
|
73
|
+
It ships with a labelled benchmark corpus (551 cases, 1,044 dialect evaluations) and a
|
|
74
74
|
regression gate for CI. The same benchmark harness can evaluate other open-source guards
|
|
75
75
|
side by side.
|
|
76
76
|
|
|
@@ -83,9 +83,9 @@ side by side.
|
|
|
83
83
|
| Workstream | What you get | Status |
|
|
84
84
|
|---|---|---|
|
|
85
85
|
| **Policy engine** | Read-only enforcement, table/column grants, tenant isolation, function and catalog rules, structural limits. Built on [sqlglot](https://github.com/tobymao/sqlglot). Fails closed when analysis is incomplete. | PostgreSQL + SQLite tested |
|
|
86
|
-
| **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, small-cohort review, minimisation hints and alternatives | implemented |
|
|
86
|
+
| **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, lineage through CTEs and derived tables, small-cohort review, minimisation hints and alternatives | implemented |
|
|
87
87
|
| **Agent integrations** | `SQLCheckpoint` with block / review / audit modes, hash-bound single-use approvals, retry lock-out, redacted audit events. LangChain tool, LangGraph nodes, FastAPI router | implemented |
|
|
88
|
-
| **Benchmark engine** | Versioned corpus, metrics (recall, precision, FPR, FNR, exact match, per category/dialect
|
|
88
|
+
| **Benchmark engine** | Versioned corpus with per-file SHA-256 hashes, internal and independent tiers, metrics (recall, precision, F1, FPR, FNR with 95% Wilson intervals, exact match, throughput, latency percentiles, per category/dialect/tier), adapters for native, callable and isolated external validators, JSON, CSV and Markdown reports | implemented |
|
|
89
89
|
| **Query cost** | Explainable static score; optional PostgreSQL `EXPLAIN (FORMAT JSON)` inspection, gated and read-only | implemented |
|
|
90
90
|
| **CI** | Composite GitHub Action and CLI gate: security, usability, label-change and error regressions against an approved baseline | implemented |
|
|
91
91
|
|
|
@@ -279,22 +279,24 @@ sqlninja benchmark run --dataset builtin:v1 --adapter external:sql-guardrail
|
|
|
279
279
|
sqlninja benchmark compare --baseline benchmarks/baselines/native.json --candidate results/latest.json
|
|
280
280
|
```
|
|
281
281
|
|
|
282
|
-
Results for corpus v1.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
|
289
|
-
|
|
|
290
|
-
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
100% shows consistency with the documented semantics, not independent
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
282
|
+
Results for corpus v1.1.0 (551 cases, 1,044 evaluations; SQLGuard Ninja 0.2.0; Windows 11,
|
|
283
|
+
Python 3.11). Intervals are 95% Wilson intervals. Details, CSV and raw files:
|
|
284
|
+
[RESULTS_v1.1.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.1.md).
|
|
285
|
+
|
|
286
|
+
| Validator | Recall (95% CI) | Precision | F1 | FPR (95% CI) | Recall / FPR within declared capability | p95 ms |
|
|
287
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
288
|
+
| SQLGuard Ninja 0.2.0 | 100.0% (99.4–100.0) | 100.0% | 1.000 | 0.0% (0.0–0.9) | 100.0% / 0.0% | 3.33 |
|
|
289
|
+
| sql-guardrail 0.5.2 | 98.7% (97.4–99.3) | 85.1% | 0.914 | 24.1% (20.3–28.3) | 98.3% / 19.7% | 2.63 |
|
|
290
|
+
| agent-sql-guard 0.2.0 | 67.3% (63.4–70.9) | 85.2% | 0.752 | 16.3% (13.1–20.0) | 89.4% / 17.7% | 1.87 |
|
|
291
|
+
| krish2105/sqlguard 0.1.0 | 65.3% (61.4–69.0) | 89.6% | 0.755 | 10.5% (8.0–13.8) | 83.5% / 5.2% | 1.95 |
|
|
292
|
+
|
|
293
|
+
**All of these are internal results.** The corpus was written by this project, alongside the
|
|
294
|
+
engine. The native 100% shows consistency with the documented semantics, not independent
|
|
295
|
+
detection quality. No independently sourced dataset exists yet ([intake rules](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/benchmarks/datasets/external/README.md),
|
|
296
|
+
issue #6). Reports keep `internal` and `independent` tiers separate, and they also separate
|
|
297
|
+
policy denials from unsupported-SQL denials. Methodology and bias review:
|
|
298
|
+
[BENCHMARK_METHODOLOGY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md),
|
|
299
|
+
[BENCHMARK_BIAS_REVIEW.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md).
|
|
298
300
|
|
|
299
301
|
## How it relates to existing tools
|
|
300
302
|
|
|
@@ -14,7 +14,7 @@ the *authenticated* caller: which tables and columns a role may use, which data
|
|
|
14
14
|
appear only in aggregates or only after human approval, and which tenant the caller belongs
|
|
15
15
|
to. It records an audit trail and gives the agent an explanation it can act on.
|
|
16
16
|
|
|
17
|
-
It ships with a labelled benchmark corpus (
|
|
17
|
+
It ships with a labelled benchmark corpus (551 cases, 1,044 dialect evaluations) and a
|
|
18
18
|
regression gate for CI. The same benchmark harness can evaluate other open-source guards
|
|
19
19
|
side by side.
|
|
20
20
|
|
|
@@ -27,9 +27,9 @@ side by side.
|
|
|
27
27
|
| Workstream | What you get | Status |
|
|
28
28
|
|---|---|---|
|
|
29
29
|
| **Policy engine** | Read-only enforcement, table/column grants, tenant isolation, function and catalog rules, structural limits. Built on [sqlglot](https://github.com/tobymao/sqlglot). Fails closed when analysis is incomplete. | PostgreSQL + SQLite tested |
|
|
30
|
-
| **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, small-cohort review, minimisation hints and alternatives | implemented |
|
|
30
|
+
| **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, lineage through CTEs and derived tables, small-cohort review, minimisation hints and alternatives | implemented |
|
|
31
31
|
| **Agent integrations** | `SQLCheckpoint` with block / review / audit modes, hash-bound single-use approvals, retry lock-out, redacted audit events. LangChain tool, LangGraph nodes, FastAPI router | implemented |
|
|
32
|
-
| **Benchmark engine** | Versioned corpus, metrics (recall, precision, FPR, FNR, exact match, per category/dialect
|
|
32
|
+
| **Benchmark engine** | Versioned corpus with per-file SHA-256 hashes, internal and independent tiers, metrics (recall, precision, F1, FPR, FNR with 95% Wilson intervals, exact match, throughput, latency percentiles, per category/dialect/tier), adapters for native, callable and isolated external validators, JSON, CSV and Markdown reports | implemented |
|
|
33
33
|
| **Query cost** | Explainable static score; optional PostgreSQL `EXPLAIN (FORMAT JSON)` inspection, gated and read-only | implemented |
|
|
34
34
|
| **CI** | Composite GitHub Action and CLI gate: security, usability, label-change and error regressions against an approved baseline | implemented |
|
|
35
35
|
|
|
@@ -223,22 +223,24 @@ sqlninja benchmark run --dataset builtin:v1 --adapter external:sql-guardrail
|
|
|
223
223
|
sqlninja benchmark compare --baseline benchmarks/baselines/native.json --candidate results/latest.json
|
|
224
224
|
```
|
|
225
225
|
|
|
226
|
-
Results for corpus v1.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
|
233
|
-
|
|
|
234
|
-
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
100% shows consistency with the documented semantics, not independent
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
226
|
+
Results for corpus v1.1.0 (551 cases, 1,044 evaluations; SQLGuard Ninja 0.2.0; Windows 11,
|
|
227
|
+
Python 3.11). Intervals are 95% Wilson intervals. Details, CSV and raw files:
|
|
228
|
+
[RESULTS_v1.1.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.1.md).
|
|
229
|
+
|
|
230
|
+
| Validator | Recall (95% CI) | Precision | F1 | FPR (95% CI) | Recall / FPR within declared capability | p95 ms |
|
|
231
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
232
|
+
| SQLGuard Ninja 0.2.0 | 100.0% (99.4–100.0) | 100.0% | 1.000 | 0.0% (0.0–0.9) | 100.0% / 0.0% | 3.33 |
|
|
233
|
+
| sql-guardrail 0.5.2 | 98.7% (97.4–99.3) | 85.1% | 0.914 | 24.1% (20.3–28.3) | 98.3% / 19.7% | 2.63 |
|
|
234
|
+
| agent-sql-guard 0.2.0 | 67.3% (63.4–70.9) | 85.2% | 0.752 | 16.3% (13.1–20.0) | 89.4% / 17.7% | 1.87 |
|
|
235
|
+
| krish2105/sqlguard 0.1.0 | 65.3% (61.4–69.0) | 89.6% | 0.755 | 10.5% (8.0–13.8) | 83.5% / 5.2% | 1.95 |
|
|
236
|
+
|
|
237
|
+
**All of these are internal results.** The corpus was written by this project, alongside the
|
|
238
|
+
engine. The native 100% shows consistency with the documented semantics, not independent
|
|
239
|
+
detection quality. No independently sourced dataset exists yet ([intake rules](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/benchmarks/datasets/external/README.md),
|
|
240
|
+
issue #6). Reports keep `internal` and `independent` tiers separate, and they also separate
|
|
241
|
+
policy denials from unsupported-SQL denials. Methodology and bias review:
|
|
242
|
+
[BENCHMARK_METHODOLOGY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md),
|
|
243
|
+
[BENCHMARK_BIAS_REVIEW.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md).
|
|
242
244
|
|
|
243
245
|
## How it relates to existing tools
|
|
244
246
|
|