TL;DR
- agent-db-scan은 AI 에이전트에 데이터베이스 연결 정보를 넘기기 전에 해당 Postgres 로그인이 가진 현재 권한과 미래 권한을 확인하는 도구임.
- 역할 소유권, 그룹 역할을 통한 상속,
PUBLIC권한, 기본 권한을 검사함. - Linux, macOS, Windows의 amd64 및 arm64용 사전 빌드 바이너리를 제공하며 Go 설치 또는 소스 빌드도 가능함.
- 표 또는 JSON 형식으로 결과를 출력하며, 스캔은 읽기 전용 트랜잭션으로 수행되고 테이블 내용은 읽지 않음.
- 행 수준 보안(RLS) 정책 평가,
SECURITY DEFINER함수 분석, 뷰 소유자 권한 추적, 열 수준 권한 검사는 지원하지 않으며, 결과가 없다고 안전이 증명되는 것은 아님.
agent-db-scan
- Postgres 로그인이 실제로 무엇을 볼 수 있고 무엇을 할 수 있는지 확인하는 도구임.
필요한 이유
- AI 에이전트에 데이터베이스 연결 문자열을 제공하면 해당 로그인 역할의 모든 권한을 상속함. 여기에는 역할이 소유한 권한, 그룹 역할을 통해 접근할 수 있는 권한,
PUBLIC에 부여된 권한, 아직 존재하지 않는 테이블에 기본 권한으로 부여될 권한이 포함됨. - 대부분은 이 권한을 모두 합쳤을 때 어떤 결과가 되는지 확인하지 않으며,
agent-db-scan은 자격 증명을 넘기기 전에 권한을 점검함.
설치
- Linux, macOS, Windows용 amd64 및 arm64 사전 빌드 바이너리는 Releases 페이지에서 제공됨.
- 사용 중인 플랫폼의 아카이브를 내려받아 압축을 풀고
agent-db-scan을PATH에 추가하면 됨. Go 도구 모음은 필요하지 않음. - Go가 설치된 경우
go install github.com/vaultkit-inc/agent-db-scan/cmd/agent-db-scan@latest로 설치할 수 있음. - 설치 후
agent-db-scan을 찾을 수 없다면$(go env GOPATH)/bin이PATH에 포함돼 있는지 확인해야 함. - 소스에서 빌드할 경우
https://github.com/vaultkit-inc/agent-db-scan.git저장소를 복제한 뒤make build를 실행하면bin/agent-db-scan이 생성됨.
사용법
DATABASE_URL환경 변수에postgres://app_service@localhost:5432/app을 설정하면agent-db-scan이 해당 값을 읽음.agent-db-scan --dsn "$DATABASE_URL" --schema app은 지정한 DSN과app스키마를 대상으로 스캔함.agent-db-scan --format json > report.json은 JSON 보고서를 파일로 출력함.- 비밀번호를 플래그로 전달하면 셸 기록과 프로세스 목록에 남으므로
--dsn보다DATABASE_URL환경 변수를 사용하는 편이 좋음.
플래그
--dsn STRING: Postgres 연결 문자열이며, 기본값은$DATABASE_URL임.--format table|json: 사람이 읽기 쉬운 보고서가 기본값이며, JSON은 전체 기계 판독용 보고서를 출력함.--schema NAME: 스캔 범위를 단일 스키마로 제한함.--include-system: 기본적으로 제외되는pg_catalog및information_schema객체를 포함함. Postgres는 이들 대부분에PUBLIC읽기 권한을 부여하므로, 기본 설정은 실제 점검 결과가 묻히는 일을 방지함.-v,--verbose: 표 출력에서만 동작하며PRIVILEGES와 전체SOURCES목록을 추가함.
종료 코드
0: 스캔이 완료됨.1: 플래그 오류, 연결 문자열 부재, 연결 실패 또는 쿼리 실패로 스캔이 실패함.- 아직 심각도 임계값이 없으므로 종료 코드는 스캔 결과를 반영하지 않음.
샘플 출력
- 두 그룹 역할에서 읽기 및 쓰기 권한을 상속하는
app_service픽스처 로그인을agent-db-scan --schema app로 스캔한 예시임. - 대상 로그인은
app_service이며, 스캔 시각은2026-09-21 16:26:42 UTC임. - 요약 결과는 객체 1개, 테이블 1개, 읽기 가능, 쓰기 가능, 관리자 접근 없음, 소유권 없음, 미래 접근 규칙 2개임.
- 현재 접근 항목은
app.widgets테이블의 쓰기 권한이며,app_reader와app_writer에서 상속되고 그 밖에 출처가 1개 더 있음. app_admin이 데이터베이스 전체 범위에서 새 객체를 만들면app_reader를 통해 상속된SELECT권한이 적용됨.app_admin이app스키마에서 새 객체를 만들 때도app_reader를 통한 상속SELECT권한이 적용됨.- 표 보기는 요약 형태로, 행마다 출처를 최대 2개까지 가장 높은 권한 순으로 표시하며 터미널 출력에서만 색상을 사용하고
NO_COLOR를 따름. - 전체 세부 정보는
--verbose로, 모든 정보는--format json으로 확인할 수 있음.
안전성
- 모든 쿼리는 문장 시간 제한이 설정된 읽기 전용 트랜잭션에서 실행되며, 트랜잭션은 커밋되지 않고 항상 롤백됨.
- 역할, 멤버십, 접근 제어 목록(ACL), 기본 권한, RLS 상태 등 카탈로그 메타데이터만 읽으며 테이블 내용은 읽지 않음.
- 네트워크 연결은 지정한 데이터베이스에만 이루어짐.
확인할 수 없는 항목
- 행 수준 보안(RLS): 테이블의 RLS 활성화 또는 강제 여부와 존재하는 정책은 보고하지만, 정책 표현식을 평가하지 않으므로 실제로 어떤 행이 보이는지는 판별할 수 없음. RLS 테이블의 접근 권한은 상한으로 간주해야 함.
SECURITY DEFINER함수: 함수가 어떤 권한으로 실행되는지 분석하지 않으므로 이를 통한 권한 상승은 드러나지 않음. 함수는 아직 객체로 스캔되지 않음.- 뷰 소유자 권한: 뷰는 소유자의 권한으로 실행되지만, 그 권한의 간접 참조는 추적되지 않음.
- 열 수준 권한: 객체 수준 ACL만 읽음.
- 발견 사항이 없다고 해서 안전성이 증명되는 것은 아님.
개발
- 통합 테스트 픽스처를 실행하려면
docker compose up -d를 사용하며, 스키마는testdata/schema.sql에 있음. - 테스트 실행 명령은
make test임.
라이선스
- 라이선스는 MIT이며, 세부 정보는
LICENSE에 있음. - VaultKit 팀이 제작함.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요