QueryShield
QueryShield
AI 에이전트와 기업용 데이터베이스 사이의 보안 SQL 프록시입니다.
에이전트는 일반 영어(또는 구조화된 SQL)로 단일 엔드포인트를 호출합니다. QueryShield는 다음을 수행합니다:
프롬프트 캐싱을 사용하여 Claude를 통해 자연어를 SQL로 변환합니다.
모든 쿼리를 AST 수준에서 검증합니다.
SELECT만 허용되며, 문장 결합, 금지된 함수 사용은 불가하고, LIMIT이 필수입니다.에이전트별 행 수준 보안을 적용합니다: 스키마/테이블 화이트리스트 및
WHERE절 주입.고객 DB에 대해 실행하고 행을 반환합니다.
모든 시도를 추가 전용 감사 테이블에 기록합니다. 메타데이터만 기록하며, 행 내용은 절대 기록하지 않습니다.
에이전트는 연결 문자열을 절대 볼 수 없습니다.
퀵스타트
pip install -r requirements.txt
cp .env.example .env
# Set ANTHROPIC_API_KEY, DATABASE_URL, VAULT_KEY (see below)
python -m queryshield.startVAULT_KEY에 대한 Fernet 키를 한 번 생성하고 절대 분실하지 마십시오:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"엔드투엔드 흐름 (curl)
# 1) Boot a tenant. Returns the admin API key — copy it.
curl -X POST localhost:8000/v1/tenants?name=Acme
# 2) Register the customer DB. Connection string is encrypted at rest.
curl -X POST localhost:8000/v1/databases \
-H 'X-Admin-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{
"alias": "prod",
"db_type": "postgresql",
"connection_string": "postgresql://reader:secret@db.acme.internal:5432/app",
"allowed_tables": ["users", "orders"]
}'
# 3) Provision a scoped agent (different from admin) for your AI app.
curl -X POST localhost:8000/v1/agents \
-H 'X-Admin-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{ "name": "reporting", "tenant_id": "<tenant>" }'
# 4) Set the agent's RLS policy.
curl -X POST localhost:8000/v1/policies \
-H 'X-Admin-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{
"agent_id": "<agent>",
"database_alias": "prod",
"allowed_tables": ["users", "orders"],
"row_filters": { "users": "tenant_id = 42" }
}'
# 5) The agent queries.
curl -X POST localhost:8000/v1/query \
-H 'X-API-Key: qs_...' \
-H 'Content-Type: application/json' \
-d '{
"database_alias": "prod",
"query": "how many active users do we have?",
"mode": "nl",
"max_rows": 10
}'MCP 통합
공식 MCP 레지스트리에 io.github.bch1212/queryshield로 등록되어 있습니다.
클라이언트 설치:
pip install queryshield-mcp그런 다음 Claude Desktop / Cursor / 에이전트 설정에 다음을 추가하십시오:
{
"queryshield": {
"command": "queryshield-mcp",
"env": { "QUERYSHIELD_API_KEY": "qs_..." }
}
}독립형 PyPI 패키지 소스는 packages/queryshield-mcp/에 있습니다.
MCP 통합 (레거시)
MCP 지원 클라이언트(Claude Desktop, Cursor, 커스텀 에이전트)에 다음을 추가하십시오:
{
"queryshield": {
"command": "python",
"args": ["-m", "queryshield.mcp_server"],
"env": {
"QUERYSHIELD_API_KEY": "qs_...",
"QUERYSHIELD_BASE_URL": "https://api.queryshield.io"
}
}
}노출된 도구:
query_database(database_alias, question, max_rows)— 자연어query_database_sql(database_alias, sql, max_rows)— 사전 빌드된 SELECTget_audit_log(limit)— 호출 에이전트에 대한 최근 시도
보안 모델
위협 | 방어 |
에이전트가 | sqlglot AST가 SELECT가 아닌 경우 거부 |
에이전트가 | 파서가 |
에이전트가 | AST 노드 수준에서 함수 거부 목록 적용 |
에이전트가 범위를 벗어난 테이블을 읽음 | RLS 스키마 + 테이블 화이트리스트 |
에이전트가 다른 테넌트의 행을 읽음 | AST |
스택 추적을 통해 연결 문자열 유출 | Fernet 암호화, API에서 절대 반환되지 않음 |
감사 로그가 데이터 유출 벡터가 됨 | 메타데이터만 저장 — 행은 절대 저장 안 함 |
| 새 키로 행 재암호화 (스크립트 기반) |
safety.py는 가장 중요한 단일 모듈입니다. 여기에 추가되는 모든 검사는 tests/test_safety.py의 테스트와 함께 제공되어야 합니다.
요금
등급 | 월간 | 데이터베이스 | 쿼리 / 월 | 비고 |
Starter | $500 | 3 | 1,000,000 | |
Pro | $1,500 | 10 | 10,000,000 | 감사 내보내기 |
Enterprise | $3,500 | 무제한 | 무제한 | SSO, SIEM 웹훅 |
15개 고객(Pro 10개 + Enterprise 5개) 기준 월 32,500달러 MRR을 목표로 합니다.
배포
이 저장소는 Railway 준비가 완료되었습니다. python -m queryshield.start가 진입점입니다 (Railway는 셸 없이 시작 명령을 실행하므로 os.getenv를 통해 PORT를 읽습니다). Railway 마켓플레이스에서 Postgres + (선택 사항) Redis를 프로비저닝하면 나머지는 환경 변수로 설정됩니다.
railway up/health는 활성 상태 확인입니다. /ready는 제어 평면 DB에 연결할 수 없는 경우 503을 반환합니다.
테스트
pip install pytest
python -m pytest tests/42개의 테스트가 다음을 다룹니다:
AST 안전성 (24개 사례 — 직접적인 DDL, 주석, 인코딩된 키워드, 다중 문장, 금지된 함수, 누락된 LIMIT)
RLS 엔진 (6개 사례 — 화이트리스트 강제, WHERE 주입, 기존 술어와의 결합)
SQLite "고객 DB"에 대한 프록시 엔드투엔드 (5개 사례 — 정상 경로, 차단된 DML, RLS 행 필터링, 테이블 화이트리스트, 캐시 적중)
FastAPI TestClient를 통한 HTTP 통합 (7개 사례 — 전체 프로비저닝 → 쿼리 흐름, RLS가 적용된 에이전트, 인증 실패)
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/bch1212/queryshield'
If you have feedback or need assistance with the MCP directory API, please join our Discord server