Skip to main content

SQL query security gateway for validating database access levels

Project description

AnomalyArmor Query Gateway

Tests Python 3.11+ License

What is this?

This is the open-source SQL security layer that AnomalyArmor uses to control access to customer databases. Every query we execute against your database passes through this gateway.

Why open source? So you can verify exactly what queries we can and cannot run. No black boxes.

What does it do?

                      ┌─────────────────────────────────┐
                      │      AnomalyArmor Platform      │
                      └─────────────────────────────────┘
                                       │
                                       │
                                       ▼
┌────-─────────────────────────────────────────-────────────────────────-───────┐
│                          Query Security Gateway                               │
│   ┌─────────────────┐    ┌─────────────────-┐    ┌────────────────────────┐   │
│   │   SQL Parser    │ -> │ Access Validator │ -> │  Allow / Block + Log   │   │
│   │   (sqlglot)     │    │  (level rules)   │    │  (audit trail)         │   │
│   └─────────────────┘    └─────────────────-┘    └────────────────────────┘   │
└─────-─────────────────────────────────────────────────────────────────────────┘
                                        │
                                        | ALLOWED OPERATIONS ONLY
                                        ▼
                       ┌────────────────-────────────────┐
                       │         Your Database           │
                       └────────────────-────────────────┘

Validates SQL queries against three access levels:

Level What We Can Query What We Cannot Query
Schema Only Table names, column types, indexes Any actual data
Aggregates COUNT(*), AVG(salary), MAX(date) SELECT email FROM users
Full Any SELECT query -

The gateway parses your SQL using sqlglot and blocks queries that violate the configured access level. If parsing fails, the query is blocked (fail-closed).

How do we know it works?

97 tests covering access level enforcement, SQL parsing, and security edge cases.

See TEST_RESULTS.md for the full breakdown, or run them yourself:

pip install -e ".[dev]"
pytest -v

Overview

The Query Security Gateway provides a transparent, auditable layer for controlling what types of SQL queries can be executed against customer databases. It supports three access levels:

Level Description Allowed Queries
schema_only Metadata access only information_schema, pg_catalog, DESCRIBE, system tables
aggregates Aggregate functions only COUNT, SUM, AVG, MIN, MAX, COUNT DISTINCT - no raw column values
full Unrestricted read access Any SELECT query

Installation

pip install anomalyarmor-query-gateway

Quick Start

from anomalyarmor_query_gateway import QuerySecurityGateway, AccessLevel

# Create gateway with desired access level
gateway = QuerySecurityGateway(
    access_level=AccessLevel.AGGREGATES,
    dialect="postgresql",
)

# Validate a query
result = gateway.validate_query_sync("SELECT COUNT(*) FROM users")

if result.allowed:
    print("Query is allowed")
else:
    print(f"Query blocked: {result.reason}")

Access Levels Explained

schema_only

Only allows queries against system/metadata tables:

  • PostgreSQL: information_schema.*, pg_catalog.*
  • MySQL: information_schema.*, mysql.*, performance_schema.*
  • Databricks: information_schema.*, system.*
  • ClickHouse: system.*
  • SQLite: sqlite_master, sqlite_schema

aggregates

Allows aggregate functions but blocks raw column values:

# Allowed
"SELECT COUNT(*) FROM users"
"SELECT AVG(salary) FROM employees"
"SELECT MIN(created_at), MAX(created_at) FROM orders"

# Blocked
"SELECT * FROM users"
"SELECT email FROM users"
"SELECT salary FROM employees WHERE id = 1"

full

Allows any valid SELECT query.

Async Support

from anomalyarmor_query_gateway import QuerySecurityGateway, AccessLevel

gateway = QuerySecurityGateway(
    access_level=AccessLevel.AGGREGATES,
    dialect="postgresql",
)

# Async validation with audit logging
result = await gateway.validate_query(
    "SELECT COUNT(*) FROM users",
    metadata={"asset_id": "123", "user_id": "456"}
)

Audit Logging

Implement the AuditLoggerProtocol to log all query validation attempts:

from anomalyarmor_query_gateway import (
    QuerySecurityGateway,
    AccessLevel,
    AuditLoggerProtocol,
)

class MyAuditLogger(AuditLoggerProtocol):
    async def log_query(
        self,
        query: str,
        access_level: AccessLevel,
        dialect: str,
        allowed: bool,
        rejection_reason: str | None,
        metadata: dict,
    ) -> None:
        # Store to your audit log
        print(f"Query {'allowed' if allowed else 'blocked'}: {query[:50]}...")

gateway = QuerySecurityGateway(
    access_level=AccessLevel.AGGREGATES,
    dialect="postgresql",
    audit_logger=MyAuditLogger(),
)

Supported Dialects

  • postgresql / postgres
  • mysql
  • databricks
  • clickhouse
  • sqlite

Security

This package is designed to be a security control layer. Key security features:

  1. Fail-closed: If parsing fails, the query is blocked
  2. Comment stripping: SQL comments are removed before parsing to prevent obfuscation
  3. Recursive validation: Subqueries and CTEs are validated against the same rules
  4. Window function blocking: Window functions blocked in aggregates mode (can expose row-level data)

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linter
ruff check src/ tests/

# Run type checker
mypy src/

License

Apache 2.0 - See LICENSE for details.

Contributing

See CONTRIBUTING.md for guidelines.

Security Issues

See SECURITY.md for reporting security vulnerabilities.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

anomalyarmor_query_gateway-1.0.1.tar.gz (29.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

anomalyarmor_query_gateway-1.0.1-py3-none-any.whl (26.7 kB view details)

Uploaded Python 3

File details

Details for the file anomalyarmor_query_gateway-1.0.1.tar.gz.

File metadata

File hashes

Hashes for anomalyarmor_query_gateway-1.0.1.tar.gz
Algorithm Hash digest
SHA256 a086da97627521f9df6ae5b50fa721ac7974a4336e7ee86819894ecb892167d4
MD5 65a0bc2dd33529141b74ca6ca7180d25
BLAKE2b-256 947f998fb0797a09a75493d51b1266add23a6dbb5e7c6cca0bfc406c3043661a

See more details on using hashes here.

Provenance

The following attestation bundles were made for anomalyarmor_query_gateway-1.0.1.tar.gz:

Publisher: publish.yml on anomalyarmor/anomalyarmor-query-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anomalyarmor_query_gateway-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for anomalyarmor_query_gateway-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ba781174295c3318e5b43e81b3475e7ecfbd3f8391524cb6731d8eeb1d0d5466
MD5 a9505cf7bd47b4cda62ce11f65754c97
BLAKE2b-256 760dfb37a9ac9aaf12ba13081dbc7e015be87078a3c4109f640f9b5f8b0eb024

See more details on using hashes here.

Provenance

The following attestation bundles were made for anomalyarmor_query_gateway-1.0.1-py3-none-any.whl:

Publisher: publish.yml on anomalyarmor/anomalyarmor-query-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page