97 lines
5.3 KiB
Markdown
97 lines
5.3 KiB
Markdown
# mysql-readonly-tool Specification
|
|
|
|
## Purpose
|
|
|
|
Define a fail-closed, parameterized, read-only MySQL evidence Tool that reuses the stage 3A ToolBoundary and exposes only bounded ACI results.
|
|
|
|
## ADDED Requirements
|
|
|
|
### Requirement: SQL validation SHALL fail closed on a conservative SELECT subset
|
|
|
|
The Tool SHALL parse exactly one SQL statement with JSqlParser and SHALL accept only a single `SELECT` with explicit projection columns, supported predicates/grouping/ordering, `INNER JOIN` or `LEFT JOIN`, parameter placeholders and allowlisted functions. It SHALL reject writes, CTEs, subqueries, set operations, wildcard projections except `COUNT(*)`, metadata discovery, unsupported joins/functions, `FOR UPDATE`, multiple statements and unknown/ambiguous AST structures.
|
|
|
|
#### Scenario: Valid explicit-column SELECT
|
|
|
|
- WHEN a query selects allowlisted columns from an allowlisted table with matching `?` parameters
|
|
- THEN validation returns a query plan and the executor may be invoked
|
|
|
|
#### Scenario: COUNT star exception
|
|
|
|
- WHEN a query uses `SELECT COUNT(*)` against an allowlisted table
|
|
- THEN validation succeeds without treating the projection as an unrestricted wildcard
|
|
|
|
#### Scenario: Security query is rejected
|
|
|
|
- WHEN SQL contains INSERT/UPDATE/DELETE, `WITH`, a subquery, `UNION`, `SELECT *`, metadata discovery, `FOR UPDATE`, a dangerous function, multiple statements or an unknown AST node
|
|
- THEN validation fails before executor invocation
|
|
|
|
### Requirement: Data-source and identifier authorization SHALL use exact independent allowlists
|
|
|
|
The Tool SHALL accept only a logical `data_source` ID and SHALL authorize every schema, table and column used in projection, join, predicate, grouping and ordering against the configured exact allowlist. It SHALL reject unknown data sources, schemas, tables, columns, aliases and ambiguous unqualified columns. Agent input SHALL NOT provide JDBC coordinates or authorization controls.
|
|
|
|
#### Scenario: Allowlisted query
|
|
|
|
- WHEN every referenced identifier resolves to one configured schema/table/column
|
|
- THEN validation succeeds and retains the logical data-source ID only
|
|
|
|
#### Scenario: Allowlist bypass
|
|
|
|
- WHEN a query references an unconfigured table, column, schema, alias or ambiguous unqualified column
|
|
- THEN validation fails closed and the executor is not called
|
|
|
|
### Requirement: Parameter binding and JDBC execution SHALL be read-only and bounded
|
|
|
|
The executor SHALL use a configured logical datasource, a read-only JDBC connection, `PreparedStatement` parameter binding, query timeout, max rows and Run cancellation/deadline checks. Placeholder count SHALL exactly match `params`. The executor SHALL not expose connection details or raw JDBC failures to the Agent.
|
|
|
|
#### Scenario: Bound read-only execution
|
|
|
|
- WHEN a validated plan has matching parameters and an active Run
|
|
- THEN the executor binds values in order, sets read-only/timeout/max rows, and returns structured raw rows
|
|
|
|
#### Scenario: Timeout or cancellation
|
|
|
|
- WHEN the query exceeds its timeout or the Run is cancelled/deadline-expired
|
|
- THEN the statement is cancelled/closed and ToolBoundary returns a safe error without an Agent result
|
|
|
|
### Requirement: MySQL projection SHALL be bounded and evidence-aware
|
|
|
|
The projector SHALL expose only ordered columns, bounded JSON-safe rows, returned count and truncation. It SHALL enforce row, cell and total UTF-8 limits, redact sensitive column values, return `NO_EVIDENCE` for a successful empty result, and never expose raw JDBC metadata or credentials.
|
|
|
|
#### Scenario: Bounded rows are projected
|
|
|
|
- WHEN the executor returns rows within configured limits
|
|
- THEN the Agent receives `EVIDENCE_FOUND` with ordered columns and structured rows
|
|
|
|
#### Scenario: Result exceeds a limit
|
|
|
|
- WHEN row count, cell length or total bytes exceed a configured bound
|
|
- THEN the Agent receives valid bounded JSON with `truncated=true` and no oversized value
|
|
|
|
#### Scenario: Empty result
|
|
|
|
- WHEN a valid query returns zero rows
|
|
- THEN the boundary reaches `READY` with `evidence_status=NO_EVIDENCE` and an empty row list
|
|
|
|
### Requirement: MySQL Tool SHALL reuse canonical Harness ownership
|
|
|
|
The adapter SHALL pass the exact framework `tool_call_id` and RunContext through the existing ToolBoundary and canonical invocation store. It SHALL not create a second ID, use a parallel store, return raw SQL results, or modify legacy audit/public runtime paths.
|
|
|
|
#### Scenario: Successful adapter call
|
|
|
|
- WHEN a valid request passes validation and execution
|
|
- THEN the canonical record contains request/raw/bounded result under the exact framework ID and the Agent receives only the bounded result
|
|
|
|
#### Scenario: Validation or boundary failure
|
|
|
|
- WHEN validation, authorization, duplicate, budget or lifecycle preflight fails
|
|
- THEN no database call is made and the Agent receives a safe bounded error
|
|
|
|
### Requirement: The query helper script SHALL be read-only and secret-free by default
|
|
|
|
The repository query helper SHALL require connection values from environment variables, reject non-SELECT and metadata discovery SQL before connection, and SHALL NOT commit writes or expose hardcoded external connection defaults.
|
|
|
|
#### Scenario: Unsafe script query
|
|
|
|
- WHEN a caller passes a write, multi-statement, metadata or transaction command
|
|
- THEN the script exits with a safe validation error without opening a connection
|