콘텐츠로 이동

PostgreSQL DB UDF

PostgreSQL DB UDF는 PostgreSQL 내부의 SQL, PL/pgSQL procedure, function, trigger function, batch SQL에서 DADP Engine을 호출하기 위한 연동 방식이다.

Version

현재 PostgreSQL DB UDF 기준 버전은 2.5.1이다.

설치 후에는 다음 SQL로 설치된 DB UDF 버전을 확인한다.

SELECT dadp_get_version();

Runtime Model

PostgreSQL DB UDF는 plpython3u 기반 SQL function으로 설치된다. 함수는 PostgreSQL 서버 내부에서 실행되고, HTTP로 DADP Engine API를 호출한다.

PostgreSQL SQL / PL/pgSQL
  -> PostgreSQL DB UDF function
  -> DADP Engine API
  -> encrypted or decrypted result

DB UDF는 테이블을 직접 스캔하거나 대상 컬럼을 직접 업데이트하는 자동 마이그레이션 도구가 아니다. 대상 행 조회, request JSON 생성, 결과 반영은 고객 SQL 또는 PL/pgSQL 로직이 담당한다. DB UDF는 primitive 단건 또는 primitive batch 요청을 Engine에 전달하고 결과를 반환한다.

Requirements

항목 기준
PostgreSQL PostgreSQL 11 이상 권장
Extension plpython3u
권한 CREATE EXTENSION plpython3u를 수행할 수 있는 superuser 또는 사전 설치된 extension 사용 권한
네트워크 PostgreSQL 서버에서 Engine URL로 HTTP 또는 HTTPS 접근 가능
CLI UDF 기능이 포함된 Hub CLI dadp
Engine /api/health, /api/encrypt, /api/decrypt, /api/encrypt/batch, /api/decrypt/batch 호출 가능

Download Hub CLI

DB UDF 명령은 별도 DB UDF 전용 바이너리가 아니라 Hub CLI에 포함된다.

curl -fLo dadp \
  https://dadp-artifacts.s3.ap-northeast-2.amazonaws.com/cli/v1.3.0/dadp-linux-amd64
chmod +x dadp

다운로드 후 UDF 명령이 포함되어 있는지 확인한다.

./dadp --help
./dadp udf --help

Engine URL

PostgreSQL DB UDF는 DB 내부 설정 dadp.engine_url을 사용한다. 설치 스크립트는 dadp_set_engine_url()을 호출해 현재 데이터베이스에 Engine URL을 저장한다.

예시:

SELECT dadp_set_engine_url('http://10.0.1.50:9003');
SELECT dadp_get_engine_url();

Engine URL을 지정하지 않고 CLI가 Hub에 로그인되어 있으면 CLI는 Hub의 active Engine 정보를 조회해 사용할 수 있다. 자동 조회가 불가능한 환경에서는 --engine-url을 명시한다.

Installation

Generate SQL Scripts

변경관리 또는 DBA 검토가 필요한 환경에서는 SQL 파일을 먼저 생성한 뒤 수동 반영한다.

./dadp udf generate \
  --db-type postgres \
  --db-user dadpuser \
  --engine-url http://10.0.1.50:9003 \
  --output-dir ./dadp-udf-postgres

생성되는 주요 파일은 다음과 같다.

파일 목적
README.txt 생성 산출물 기준 설치 안내
01_install.sql plpython3u extension 및 DADP function 설치
02_verify.sql 설치 버전, Engine URL, health, round trip, batch round trip 검증
99_uninstall.sql PostgreSQL DB UDF 제거

생성된 SQL은 대상 PostgreSQL 데이터베이스에서 실행한다.

psql -U postgres -d appdb -f ./dadp-udf-postgres/01_install.sql
psql -U dadpuser -d appdb -f ./dadp-udf-postgres/02_verify.sql

Direct Install

CLI가 대상 PostgreSQL에 직접 접속해 설치할 수도 있다.

./dadp udf install \
  --db-type postgres \
  --db-host 10.0.1.30 \
  --db-port 5432 \
  --db-database appdb \
  --db-user dadpuser \
  --db-password '<db-password>' \
  --db-dba-user postgres \
  --db-dba-password '<dba-password>' \
  --engine-url http://10.0.1.50:9003

비밀번호는 명령행 대신 환경 변수로 전달할 수 있다.

export DADP_DB_PASSWORD='<db-password>'
export DADP_DB_DBA_PASSWORD='<dba-password>'

Installation Options

옵션 설명
--db-type postgres PostgreSQL UDF 설치 대상
--db-host PostgreSQL host
--db-port PostgreSQL port. 생략 시 5432
--db-database PostgreSQL database name
--db-user UDF를 사용할 DB 계정
--db-password DB 계정 비밀번호
--db-dba-user plpython3u extension 설정을 수행할 DBA 계정
--db-dba-password DBA 계정 비밀번호
--engine-url DB UDF가 호출할 Engine endpoint
--skip-acl extension 또는 ACL 설정 단계를 건너뜀
--skip-verify 설치 후 검증 생략
--dry-run 설치 SQL 출력만 수행
--default-batch-size primitive batch 내부 chunk 크기
--batch-transport-mode json, binary-framed, auto
--auto-binary-min-items auto 모드에서 binary frame 전환 기준 item 수

Installed Functions

함수 용도
dadp_set_engine_url(p_url TEXT) Engine URL 저장
dadp_get_engine_url() 현재 Engine URL 조회
dadp_get_version() 설치된 DB UDF 버전 조회
dadp_set_batch_transport_mode(p_mode TEXT) batch transport 모드 설정
dadp_get_batch_transport_mode() batch transport 모드 조회
dadp_set_auto_binary_min_items(p_value INTEGER) binary frame 자동 전환 기준 설정
dadp_get_auto_binary_min_items() binary frame 자동 전환 기준 조회
dadp_encrypt(p_data TEXT, p_policy TEXT) 단건 암호화
dadp_decrypt(p_data TEXT) 단건 복호화
dadp_decrypt_fpe(p_data TEXT, p_policy TEXT) FPE 데이터 복호화
dadp_health_check() Engine health 확인
dadp_batch_encrypt(p_request TEXT, p_batch_size INTEGER DEFAULT ...) primitive batch 암호화
dadp_batch_decrypt(p_request TEXT, p_batch_size INTEGER DEFAULT ...) primitive batch 복호화
dadp_ping() Engine health와 지연 시간 확인
dadp_batch_encrypt_profiled(p_run_id TEXT, p_request TEXT, p_batch_size INTEGER DEFAULT ...) batch 암호화 실행 profile 기록
dadp_batch_decrypt_profiled(p_run_id TEXT, p_request TEXT, p_batch_size INTEGER DEFAULT ...) batch 복호화 실행 profile 기록

Profiled 함수는 DADP_UDF_PROFILE_RUN, DADP_UDF_PROFILE_CHUNK 테이블에 실행 정보를 기록한다.

Single Encrypt And Decrypt

단건 암호화:

SELECT dadp_encrypt('plain text', 'default-policy') AS encrypted_value;

단건 복호화:

SELECT dadp_decrypt('hub:ABCD2345:...') AS plain_value;

FPE 복호화:

SELECT dadp_decrypt_fpe('1234567890', 'fpe-policy') AS plain_value;

dadp_decrypt()hub:, kms:, vault: prefix가 없는 값은 그대로 반환한다. 이 동작은 평문 데이터가 섞인 컬럼에서 불필요한 Engine 호출을 줄이기 위한 방어적 처리다.

Primitive Batch Encrypt

PostgreSQL batch UDF는 items 배열을 가진 request JSON을 입력으로 받는다.

SELECT dadp_batch_encrypt(
  '{
    "items": [
      { "data": "alpha", "policyName": "default-policy" },
      { "data": "beta", "policyName": "default-policy" }
    ]
  }',
  1000
) AS result_json;

응답은 Engine batch 응답을 정규화한 JSON 문자열이다.

{
  "transportMode": "json",
  "results": [
    {
      "success": true,
      "encryptedData": "hub:ABCD2345:...",
      "message": "encrypt succeeded"
    }
  ],
  "totalProcessed": 1,
  "totalSuccess": 1,
  "totalFailed": 0
}

Primitive Batch Decrypt

SELECT dadp_batch_decrypt(
  '{
    "items": [
      { "data": "hub:ABCD2345:..." },
      { "data": "hub:EFGH6789:..." }
    ]
  }',
  1000
) AS result_json;

PL/pgSQL Procedure Example

아래 예시는 고객 테이블에서 평문 값을 읽고 DB UDF로 암호화한 뒤 결과 컬럼에 저장한다.

CREATE OR REPLACE PROCEDURE encrypt_customer_card(
  IN p_customer_id BIGINT,
  IN p_policy TEXT
)
LANGUAGE plpgsql
AS $$
DECLARE
  v_plain TEXT;
  v_encrypted TEXT;
BEGIN
  SELECT card_no
  INTO v_plain
  FROM customer_card
  WHERE customer_id = p_customer_id;

  v_encrypted := dadp_encrypt(v_plain, p_policy);

  UPDATE customer_card
  SET card_no_enc = v_encrypted
  WHERE customer_id = p_customer_id;
END;
$$;

호출:

CALL encrypt_customer_card(1001, 'default-policy');

Batch Procedure Example

아래 예시는 PL/pgSQL procedure가 request JSON을 만들고 dadp_batch_encrypt()를 호출하는 방식이다.

CREATE OR REPLACE PROCEDURE encrypt_values_batch(
  IN p_values TEXT[],
  IN p_policy TEXT,
  IN p_batch_size INTEGER,
  INOUT p_result JSONB
)
LANGUAGE plpgsql
AS $$
DECLARE
  v_request TEXT;
BEGIN
  SELECT jsonb_build_object(
           'items',
           jsonb_agg(
             jsonb_build_object(
               'data', v,
               'policyName', p_policy
             )
           )
         )::TEXT
  INTO v_request
  FROM unnest(p_values) AS v;

  p_result := dadp_batch_encrypt(v_request, COALESCE(p_batch_size, 1000))::JSONB;
END;
$$;

호출:

CALL encrypt_values_batch(
  ARRAY['alpha', 'beta', 'gamma'],
  'default-policy',
  1000,
  NULL
);

Batch Transport

PostgreSQL DB UDF는 batch 요청에서 세 가지 transport 모드를 지원한다.

모드 설명
json Engine batch API를 application/json으로 호출
binary-framed Engine batch API를 application/x-dadp-binary-frame으로 호출
auto item 수가 기준값 이상이면 binary frame, 미만이면 JSON 사용

현재 설정 확인:

SELECT dadp_get_batch_transport_mode();
SELECT dadp_get_auto_binary_min_items();

설정 변경:

SELECT dadp_set_batch_transport_mode('auto');
SELECT dadp_set_auto_binary_min_items(128);

Verification

설치 검증은 CLI 또는 SQL 파일로 수행한다.

./dadp udf verify \
  --db-type postgres \
  --db-host 10.0.1.30 \
  --db-port 5432 \
  --db-database appdb \
  --db-user dadpuser \
  --db-password '<db-password>' \
  --test-policy default-policy \
  --test-data DADP_VERIFY_TEST

직접 SQL로 확인할 때는 다음 순서로 본다.

SELECT dadp_get_version();
SELECT dadp_get_engine_url();
SELECT dadp_get_batch_transport_mode();
SELECT dadp_get_auto_binary_min_items();
SELECT dadp_health_check();
SELECT dadp_decrypt(dadp_encrypt('DADP_VERIFY_TEST', 'default-policy'));

Status

현재 설치 상태는 CLI로 확인할 수 있다.

./dadp udf status \
  --db-type postgres \
  --db-host 10.0.1.30 \
  --db-port 5432 \
  --db-database appdb \
  --db-user dadpuser \
  --db-password '<db-password>'

Update

기존 PostgreSQL DB UDF를 갱신할 때는 update 명령을 사용한다. 기본값은 현재 설치된 runtime config를 보존한다.

./dadp udf update \
  --db-type postgres \
  --db-host 10.0.1.30 \
  --db-port 5432 \
  --db-database appdb \
  --db-user dadpuser \
  --db-password '<db-password>' \
  --preserve-config true

Engine URL 또는 transport 설정을 바꿔야 하는 경우에만 명시적으로 override한다.

./dadp udf update \
  --db-type postgres \
  --db-host 10.0.1.30 \
  --db-port 5432 \
  --db-database appdb \
  --db-user dadpuser \
  --db-password '<db-password>' \
  --engine-url http://10.0.1.50:9003 \
  --batch-transport-mode auto

Uninstall

./dadp udf uninstall \
  --db-type postgres \
  --db-host 10.0.1.30 \
  --db-port 5432 \
  --db-database appdb \
  --db-user dadpuser \
  --db-password '<db-password>' \
  --yes

PostgreSQL uninstall은 DB UDF function과 profiling table을 제거한다. 업무 테이블의 데이터는 제거하지 않는다.

Troubleshooting

증상 확인 항목
plpython3u 생성 실패 PostgreSQL superuser 권한 또는 extension 사전 설치 여부
dadp_health_check()FAIL 반환 PostgreSQL 서버에서 Engine URL로 접근 가능한지 확인
단건 암호화 결과가 평문과 동일 Engine 연결 실패, 정책명 오류, Engine 응답 실패 여부 확인
배치 결과 일부 실패 results[]success, message를 항목별로 확인
dadp_get_engine_url()이 기대값과 다름 dadp_set_engine_url() 재실행 또는 ALTER DATABASE ... SET dadp.engine_url 확인
binary frame 실패 dadp_set_batch_transport_mode('json')으로 전환해 JSON 경로부터 검증