# PostgreSQL을 해커와 싸우는 방패로 만든 방법 – 에이전트 인증(Agent Auth) 구현기

*SEO 키워드: **PostgreSQL 보안**, **에이전트 인증**, **데이터베이스 해킹 방지***

---

# # 1️⃣ 서론 – “데이터베이스가 공격 표적이 된다면?”

최근 클라우드 환경이 확대되면서 **데이터베이스 해킹** 사례가 급증하고 있습니다. 특히 웹 애플리케이션이 직접 DB에 접근하도록 설계된 경우, 인증·인가 로직에 작은 실수만 있어도 해커가 손쉽게 중요한 정보를 탈취할 수 있죠.

그렇다면 **데이터베이스 자체에 보안 방어막**을 걸어두는 방법은 없을까요?

이번 포스팅에서는 **PostgreSQL**을 활용해 **에이전트 인증(Agent Auth)**이라는 새로운 접근 방식을 구현하고, 실제로 해커의 침입을 차단한 사례를 공유합니다. 초보자도 이해할 수 있도록 단계별로 설명하니, 지금 바로 읽어보세요!

---

# # 2️⃣ 본론

## # 2.1 PostgreSQL 보안의 기본 – 인증·인가·감사

| 단계 | 설명 | PostgreSQL 적용 포인트 |

|------|------|------------------------|

| 인증 (Authentication) | 사용자가 누구인지 확인 | `pg_hba.conf`에 MD5, SCRAM‑SHA‑256, LDAP 등 설정 |

| 인가 (Authorization) | 인증된 사용자가 무엇을 할 수 있는지 결정 | 역할(Role)·권한(Privilege)·Row‑Level Security(RLS) |

| 감사 (Audit) | 누가 언제 어떤 작업을 했는지 기록 | `pg_audit` 확장 혹은 로깅 설정 |

이 세 가지가 제대로 갖춰져야 **데이터베이스 보안**이 완성됩니다. 하지만 대부분의 프로젝트는 인증과 인가만 구현하고, **세밀한 접근 제어**와 **실시간 감시**는 놓치기 쉽습니다.

## # 2.2 에이전트 인증(Agent Auth)이란?

**에이전트 인증**은 “클라이언트 애플리케이션(에이전트)이 자체적으로 발급한 토큰을 DB에 전달하고, DB가 토큰을 검증해 권한을 판단”하는 방식입니다.

- **장점**

  1. **중간자 공격 방지** – 토큰은 서명된 JWT(JSON Web Token) 형태이므로 변조가 어렵습니다.

  2. **세밀한 권한 제어** – 토큰에 포함된 클레임(claim)으로 행 수준(Row‑Level)까지 제한 가능.

  3. **감사 로그와 연동** – 토큰 검증 시점에 사용자·에이전트 정보를 자동 기록.

## # 2.3 구현 흐름 – 전체 아키텍처

```

[클라이언트] ──(JWT)──► [API 서버] ──(SQL)──► [PostgreSQL]

               │                │

               │                └─► pgjwt 확장 (JWT 검증)

               │

               └─► 토큰 발급 (RSA 비밀키)

```

1. **API 서버**가 로그인 요청을 받으면, 사용자 정보를 DB에서 조회하고 **RSA 개인키**로 서명된 JWT를 발급합니다.

2. 클라이언트는 이후 모든 요청에 `Authorization: Bearer <JWT>` 헤더를 포함시켜 전송합니다.

3. PostgreSQL은 **`pgjwt`** 확장을 이용해 **함수 `jwt_verify()`** 로 토큰을 검증하고, 토큰에 담긴 `role`·`tenant_id` 등을 기반으로 **Row‑Level Security 정책**을 적용합니다.

## # 2.4 단계별 구현 가이드

### # 2.4.1 pgjwt 확장 설치

```
bash

# Ubuntu 기준

sudo apt-get install postgresql-14-pgjwt

# 또는 소스 컴파일

git clone https://github.com/michelp/pgjwt.git

cd pgjwt

make && sudo make install

```

설치 후 DB에 확장을 활성화합니다.

```
sql

CREATE EXTENSION IF NOT EXISTS pgjwt;

```

### # 2.4.2 JWT 발급 로직 (Node.js 예시)

```
javascript

const jwt = require('jsonwebtoken');

const fs = require('fs');

const privateKey = fs.readFileSync('./private.key');

function generateToken(user) {

  const payload = {

    sub: user.id,          // 사용자 고유 ID

    role: user.role,       // admin, user 등

    tenant_id: user.tenant_id,

    iat: Math.floor(Date.now() / 1000),

    exp: Math.floor(Date.now() / 1000) + (60 * 60) // 1시간 유효

  };

  return jwt.sign(payload, privateKey, { algorithm: 'RS256' });

}

```

### # 2.4.3 Row‑Level Security 정책 정의

예시 테이블 `orders`에 대해 **테넌트별**·**사용자별** 접근을 제한합니다.

```
sql

-- 1. 테이블에 RLS 활성화

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- 2. 기본 정책: 토큰이 없으면 접근 차단

CREATE POLICY deny_all ON orders

  USING (false);

-- 3. tenant_id가 일치하고, role이 'admin'이면 전체 접근 허용

CREATE POLICY admin_all ON orders

  USING (jwt_claim('role') = 'admin');

-- 4. 일반 사용자는 자신의 tenant_id와 user_id에 해당하는 행만 조회

CREATE POLICY user_own ON orders

  USING (

    jwt_claim('tenant_id') = tenant_id

    AND jwt_claim('sub') = user_id

  );

```

`jwt_claim()` 함수는 `pgjwt`가 제공하는 함수로, 현재 세션에 전달된 JWT에서 원하는 클레임을 추출합니다.

### # 2.4.4 세션에 JWT 전달하기

PostgreSQL은 **`SET`** 명령으로 세션 변수를 설정할 수 있습니다. API 서버는 매 요청마다 아래와 같이 실행합니다.

```
sql

SET jwt.claims = '<JWT 문자열>';

```

이후 실행되는 모든 쿼리는 위에서 정의한 RLS 정책에 따라 자동으로 필터링됩니다.

### # 2.4.5 감사 로그와 연동

```
sql

-- pg_audit 설치 (감사 로그)

CREATE EXTENSION IF NOT EXISTS pgaudit;

-- 감사 설정: 모든 SELECT, INSERT, UPDATE, DELETE 로그

ALTER SYSTEM SET pgaudit.log = 'read, write';

SELECT pg_reload_conf();

```

이렇게 하면 **누가, 언제, 어떤 토큰으로** 어떤 데이터를 조회했는지 로그에 남겨, 사후 분석이 용이합니다.

## # 2.5 실제 효과 – 해커 공격 차단 사례

| 공격 시나리오 | 기존 방식 | 에이전트 인증 적용 후 |

|--------------|-----------|----------------------|

| **SQL Injection** | 토큰 검증 없이 직접 DB 연결 → 권한 상승 | RLS 정책이 토큰 기반이므로, 변조된 쿼리라도 권한 없는 행은 반환되지 않음 |

| **Credential Leak** | DB 사용자 비밀번호 탈취 → 전체 DB 접근 | 토큰은 **짧은 유효기간**·**RSA 서명** → 비밀번호가 없어도 DB 접근 불가 |

| **Privilege Escalation** | 역할(role) 변경 쿼리 실행 가능 | `jwt_claim('role')` 로 검증 → 토큰에 없는 역할은 정책에서 차단 |

위와 같이 **PostgreSQL 자체에 에이전트 인증을 삽입**함으로써, 해커가 DB에 직접 접근하더라도 최소 권한만 부여받게 되어 실제 데이터 탈취를 방지할 수 있었습니다.

---

# # 3️⃣ 결론 – 지금 바로 적용해 보세요!

1️⃣ **pgjwt**와 **Row‑Level Security**를 활용하면, 애플리케이션 로직을 최소화하고 DB 차원에서 강력한 접근 제어가 가능합니다.

2️⃣ **JWT** 기반 토큰은 짧은 수명과 서명 검증으로 **Credential Leak** 위험을 크게 낮춥니다.

3️⃣ **감사 로그**와 연동해 실시간 모니터링을 구축하면, 침입 시도 자체를 빠르게 감지할 수 있습니다.

> **행동 유도**

> - 아직 `pgjwt`를 설치하지 않으셨다면, 오늘 바로 테스트 환경에 적용해 보세요.

> - 기존 프로젝트에 RLS 정책을 추가할 때는 **백업**을 반드시 수행하고, 단계별로 정책을 검증하세요.

> - 보안 담당자와 협업해 **감사 로그**를 SIEM 시스템에 연동하면, 더욱 강력한 **데이터베이스 해킹 방지** 체계를 완성할 수 있습니다.

데이터베이스를 단순히 “저장소”가 아니라 **보안 방어막**으로 활용한다면, 해커와의 전쟁에서 한 발 앞서 나갈 수 있습니다. 지금 바로 **PostgreSQL 보안**을 강화하고, 안전한 서비스를 제공해 보세요! 🚀
