AVAILABLE

Security

SQL Read-Only Guard & Analyzer

Inspect, normalize, compare, and extract SQL structure, or enforce explicit read-only policy without executing a query or connecting to a database.

CONTRACT

Predictable for agents. Legible for reviewers.

REST
POST /v1/sql/policy-check
MCP tool
check_sql_read_only_policy
Inputs
Up to 128 KiB of SQL under an explicit supported dialect, plus optional table, function, wildcard, multi-statement, system-catalog, and literal row-limit policy.
Returns
CLEAR, REVIEW_REQUIRED, or BLOCKED with parsed statement evidence, relations, columns, functions, limits, locks, policy findings, hashes, and an agent-readable next action.
Latency
Synchronous
Usage unit
SQL operation

The focused suite also exposes /v1/sql/inspect, /v1/sql/normalize, /v1/sql/dependencies, and /v1/sql/compare plus the separate /mcp/sql server. It supports explicit generic, PostgreSQL, MySQL, SQLite, BigQuery, Snowflake, Redshift, DuckDB, Spark, Databricks, Trino, T-SQL, and Oracle parsing. It never executes SQL, connects to a database, resolves a live schema, accesses a network, stores the payload, or claims semantic equivalence. A CLEAR result is static preflight evidence—not runtime authorization or a guarantee of database safety.

AGENT-READABLE EXCEPTIONS

SQL_PARSE_ERRORSQL_NON_READ_ONLY_BLOCKEDSQL_MULTIPLE_STATEMENTS_BLOCKEDSQL_SELECT_STAR_BLOCKEDSQL_LIMIT_REQUIREDSQL_TABLE_NOT_ALLOWEDSQL_SYSTEM_CATALOG_BLOCKEDSQL_FUNCTION_DENIEDSQL_OUTPUT_TOO_LARGE
HTTP request
POST /v1/sql/policy-check
Authorization: Bearer apc_...
Content-Type: application/json

{
  "sql": "SELECT id, email FROM app.users WHERE status = 'active' LIMIT 100",
  "dialect": "postgres",
  "require_limit": true,
  "max_limit": 500,
  "allow_select_star": false,
  "require_table_allowlist": true,
  "allowed_tables": [
    "app.users"
  ]
}
cURL (bash)
curl --request POST \
  --url 'https://api-production-9502.up.railway.app/v1/sql/policy-check' \
  --header 'Authorization: Bearer ${AP_CONTROL_API_KEY}' \
  --header 'Content-Type: application/json' \
  --data '{
  "sql": "SELECT id, email FROM app.users WHERE status = 'active' LIMIT 100",
  "dialect": "postgres",
  "require_limit": true,
  "max_limit": 500,
  "allow_select_star": false,
  "require_table_allowlist": true,
  "allowed_tables": [
    "app.users"
  ]
}'
Representative response
{
  "status": "COMPLETED",
  "decision": "CLEAR",
  "permitted": true,
  "dialect": "postgres",
  "statement_count": 1,
  "statements": [
    {
      "index": 1,
      "statement_type": "SELECT",
      "query_expression": true,
      "read_only_candidate": true,
      "tables": [
        "app.users"
      ],
      "columns": [
        "email",
        "id",
        "status"
      ],
      "functions": [],
      "common_table_expressions": [],
      "projection_count": 2,
      "contains_select_star": false,
      "has_limit": true,
      "literal_limit": 100,
      "has_locking_clause": false,
      "has_select_into": false
    }
  ],
  "findings": [],
  "static_analysis_only": true,
  "query_executed": false,
  "database_connection_performed": false,
  "network_access_performed": false,
  "payload_stored": false,
  "next_action": "Send only through a read-only database identity with parameter binding, row-level authorization, timeout, and database-native resource limits."
}
No execution or connectionSQL is parsed in memory only; the API never connects to a database, runs a statement, resolves a live schema, or accesses the network.
Explicit dialect and boundsCallers select the dialect, and byte, statement, AST, table, column, function, projection, finding, and output limits are enforced.
Static evidence onlyA CLEAR result still requires a read-only database identity, parameter binding, row authorization, timeout, and database-native resource limits.

Use SQL Read-Only Guard & Analyzer through RapidAPI.

Choose a capped marketplace plan, copy the generated request, and route the structured result through your own authorized workflow.