콘텐츠로 이동

PostgreSQL DB UDF

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

이 문서는 PostgreSQL만 다룬다. Oracle, MySQL, MSSQL, SQream 설치 방식과 함수 계약은 이 문서에 포함하지 않는다.

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-service 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-service 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-service 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-service 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-service 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-service 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-service 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 경로부터 검증