29 KiB
Baron SSO 전체 시스템 백업 및 복구 설계
목적
Baron SSO의 전체 시스템 백업/복구는 CSV export/import의 확장판이 아니라, 서비스 저장소 전체를 일관된 시점으로 보존하고 복원하는 재해 복구 기능이다.
핵심 목표는 다음과 같다.
- 사용자, 조직, 권한, RP, WORKS 연동 참조에 쓰이는 UUID를 그대로 보존한다.
- Kratos identity subject와 Baron local user ID가 어긋나지 않게 복구한다.
- Hydra/Keto/Oathkeeper 기반 인증/인가 상태를 서비스 가능한 수준으로 복원한다.
- 복구 후 WORKS externalKey 기반 비교/동기화가 기존 연동과 이어지도록 한다.
- 백업 산출물의 무결성, 보안, 복구 가능성을 검증 가능한 절차로 만든다.
배경과 결론
사용자 CSV는 user_id를 포함해 내보낼 수 있지만, 실제 사용자 계정의 주체 ID는 Kratos identity ID다. Kratos Admin API의 identity 생성 요청은 id 필드를 받지 않으므로, CSV import만으로 기존 사용자 UUID를 보장할 수 없다.
따라서 사용자 UUID 보존이 필요한 복구는 반드시 Kratos DB까지 포함한 full backup/restore로 처리해야 한다. CSV import는 운영 편의 기능으로 유지하되, 재해 복구나 WORKS 연동 보존 목적의 원장 복구 수단으로 간주하지 않는다.
백업 대상
필수 저장소
| 대상 | 저장소 | 포함 이유 | 복구 필수 여부 |
|---|---|---|---|
| Baron 애플리케이션 DB | baron_postgres |
users, tenants, user_login_ids, user_groups, api_keys, outbox, WORKS mapping, RP metadata 등 | 필수 |
| Kratos DB | ory_postgres의 ory_kratos |
identity UUID, credentials, verifiable/recovery addresses, sessions | 필수 |
| Hydra DB | ory_postgres의 ory_hydra |
OAuth2 clients, consent, token/session 관련 상태 | 필수 |
| Keto DB | ory_postgres의 ory_keto |
ReBAC relation tuple 원장 | 필수 |
| Baron ClickHouse | baron_clickhouse |
감사 로그, 운영 추적 데이터 | 운영 정책상 필수 |
| Ory ClickHouse | ory_clickhouse |
Ory/Oathkeeper/Vector 계열 로그 | 운영 정책상 필수 |
| 설정/비밀값 | .env, generated Ory config, WORKS private key, gateway/Oathkeeper config |
동일 환경 재기동과 외부 연동에 필요 | 필수 |
선택 저장소
| 대상 | 처리 원칙 |
|---|---|
| Redis | 로그인 pending state, cache, short code 등 휘발성 데이터다. full restore에서는 원칙적으로 제외하고 재시작 시 비운다. 무중단 이전 시나리오에서만 snapshot을 검토한다. |
| 프론트 빌드 산출물 | 소스/이미지 태그로 재생성한다. 별도 보관은 배포 재현성을 위한 선택 항목이다. |
| 로컬 개발 산출물 | reports, coverage, test-results 등은 백업 대상에서 제외한다. |
백업 산출물 형식
백업 단위는 압축된 디렉터리 또는 object storage prefix로 관리한다.
baron-sso-backup-YYYYMMDD-HHMMSSZ/
manifest.json
checksums.sha256
postgres/
baron.dump
ory_kratos.dump
ory_hydra.dump
ory_keto.dump
globals.sql
clickhouse/
baron_clickhouse/
ory_clickhouse/
config/
env.redacted
env.encrypted
ory/
gateway/
reports/
row-counts.json
restore-readiness.json
manifest.json에는 최소한 다음 정보를 기록한다.
- backup format version
- 생성 시각, git commit, 이미지 태그
- 서비스별 DB schema/migration version
- 각 dump 파일의 checksum, 크기, 생성 명령 버전
- 백업 모드:
offline,maintenance,online-best-effort - 암호화 방식과 key id
- 복구 대상 환경 제한:
same-env-only,staging-rehearsal,cross-env
Dump 대상별 복구 flow 및 영향도
make dump의 서비스 필터는 저장소별 복구 단위를 명확히 나누기 위한 운영 인터페이스다. 전체 재해 복구는 DUMP_SERVICES=all을 기본으로 하되, staging rehearsal이나 부분 장애 분석에서는 개별 대상을 분리해서 검증할 수 있다.
대상별 요약
| 서비스 필터 | 주요 dump 산출물 | 포함 데이터 | 복구 중요도 | 복구 영향도 |
|---|---|---|---|---|
postgres |
postgres/baron.dump |
Baron users, tenants, membership, user_login_ids, user_groups, RP metadata, API keys, WORKS mapping/outbox, Keto outbox, consent read model 등 | 필수 | Ory에 저장되지 않거나 조회가 불가능한 Baron control plane 데이터와 처리 상태를 담는다. 누락되면 사용자/테넌트/RP/WORKS 참조가 끊기고 Ory DB만 복구해도 서비스 의미가 깨진다. |
ory-postgres |
postgres/globals.sql, postgres/ory_kratos.dump, postgres/ory_hydra.dump, postgres/ory_keto.dump |
Kratos identity/credential/session, Hydra client/consent/token state, Keto relation tuple | 필수 | 인증 주체, OAuth2/OIDC 상태, ReBAC 권한 원장이다. Baron DB와 시점이 다르면 로그인/인가/consent 불일치가 발생한다. |
clickhouse |
clickhouse/baron_clickhouse/schema/*.sql, clickhouse/baron_clickhouse/data/*.native |
Baron audit_logs, RP usage event/aggregate 등 | 운영 정책상 필수 | 인증 자체를 막지는 않지만 감사 추적, 사용량 집계, 사고 분석 이력이 손실된다. |
ory-clickhouse |
clickhouse/ory_clickhouse/schema/*.sql, clickhouse/ory_clickhouse/data/*.native |
Oathkeeper/Ory/Vector 접근 로그 | 운영 정책상 필수 | Ory edge 접근 로그와 장애 분석 근거가 손실된다. 인증 원장은 Postgres에 있으므로 직접 로그인 기능 영향은 제한적이다. |
config |
config/env.redacted, config/generated-ory.*, config/gateway.*, config/compose/* |
환경 변수 redacted snapshot, generated Ory config, gateway/Oathkeeper 설정, compose 파일 | 필수 | DB만 복구해도 secret/config가 맞지 않으면 Ory Stack, WORKS 연동, callback URL, gateway routing이 정상 기동하지 못한다. |
postgres: Baron 애플리케이션 DB
Dump flow:
baron_postgres컨테이너 실행 상태를 확인한다.${DB_NAME:-baron_sso}를pg_dump -Fc로postgres/baron.dump에 저장한다.pg_stat_user_tables기준 row count를reports/baron-postgres-row-counts.txt에 기록한다.checksums.sha256에 dump와 report checksum을 기록한다.
Restore flow:
- restore 전용 빈 Baron Postgres DB를 준비한다.
make restore ... RESTORE_SERVICES=postgres CONFIRM_RESTORE=baron-sso로pg_restore --clean --if-exists를 실행한다.- 복구 후 backend migration 자동 실행은 금지하고, dump 시점의 schema version과 현재 binary가 호환되는지 먼저 확인한다.
- Kratos identity와 Baron
users.id의 참조 검증을 수행한다. - WORKS relay, Keto outbox relay는 post-restore 검증 전까지 재개하지 않는다.
영향도:
- 사용자, 테넌트, 소속, RP metadata, WORKS mapping의 기준 원장이므로 full restore에서 가장 먼저 Baron/Ory 시점 정합성을 확인해야 한다.
- Baron DB만 과거 시점으로 되돌리면 Kratos identity, Hydra consent, Keto tuple과 불일치할 수 있다.
- WORKS mapping/outbox 상태가 과거로 돌아가면 외부 WORKS와 중복 upsert/delete 후보가 생길 수 있으므로 comparison dry-run이 필수다.
검증 포인트:
users.id와 Kratosidentities.id일치tenants.parent_id, membership, user group 참조 무결성- RP metadata와 Hydra client 연결성
- WORKS mapping의 BaronResourceID 참조 유효성
ory-postgres: Kratos/Hydra/Keto DB
Dump flow:
ory_postgres컨테이너 실행 상태를 확인한다.pg_dumpall --globals-only로 role/권한 정보를postgres/globals.sql에 저장한다.${KRATOS_DB:-ory_kratos},${HYDRA_DB:-ory_hydra},${KETO_DB:-ory_keto}를 각각pg_dump -Fc로 저장한다.- 각 DB의 row count report를
reports/ory_*-row-counts.txt에 기록한다.
Restore flow:
- restore 전용 빈 Ory Postgres DB를 준비한다.
- 필요 시
globals.sql을 먼저 적용한다. - Kratos, Hydra, Keto DB를 각각 복구한다.
- migration은 자동 실행하지 않고, Ory binary version과 dump schema version을 확인한다.
- Ory Stack을 backend보다 먼저 기동해 admin/public endpoint health를 확인한다.
영향도:
- Kratos DB는 사용자 subject와 credential 원장이므로 누락되면 비밀번호, recovery/verifiable address, identity UUID 보존이 불가능하다.
- Hydra DB는 client, consent, OAuth2 token/session 상태를 담으므로 누락되면 기존 RP 로그인/consent 상태가 재생성되거나 만료될 수 있다.
- Keto DB는 ReBAC tuple 원장이므로 누락되면 사용자/테넌트/RP 권한 판단이 실패한다.
- Ory DB만 복구하고 Baron DB가 맞지 않으면 identity는 있으나 Baron user가 없거나, Baron user는 있으나 identity가 없는 상태가 된다.
검증 포인트:
- Kratos identity 수와 Baron users 수 비교
- Hydra client와 Baron RP metadata 비교
- Keto tuple subject/object가 복구된 사용자/테넌트/RP를 참조하는지 확인
- 대표 사용자 password login, 대표 RP OIDC login/consent smoke
clickhouse: Baron ClickHouse
Dump flow:
baron_clickhouse컨테이너 실행 상태를 확인한다.system.tables에서 Baron ClickHouse table 목록과 engine을 조회한다.- 일반 table은
SHOW CREATE TABLE과FORMAT Native데이터를 함께 저장한다. - view 계열 engine은 restore insert 위험을 피하기 위해 schema만 저장한다.
- table별 row count를
reports/baron_clickhouse-row-counts.txt에 기록한다.
Restore flow:
- restore 전용 ClickHouse DB를 준비한다.
- database를 생성한 뒤 table schema를 먼저 적용한다.
- 일반 table의
.native데이터를 insert한다. - materialized view나 view는 schema만 복구하고, 대상 table 데이터가 들어간 뒤 재계산/재생성 정책을 별도로 확인한다.
- row count와 주요 기간의 min/max timestamp를 비교한다.
영향도:
- Baron audit log와 RP usage 집계가 손실되면 보안 감사, 운영 추적, 사용량 화면의 신뢰도가 떨어진다.
- 인증 기능 자체의 필수 원장은 아니지만, 사고 대응과 운영 증적 측면에서는 필수 백업 대상이다.
- aggregate/materialized view는 원본 event table과 복구 순서가 맞지 않으면 중복 집계나 누락 집계가 생길 수 있다.
검증 포인트:
audit_logs,rp_usage_events, aggregate table row count 비교- 주요 기간별 min/max timestamp 비교
- AdminFront/DevFront의 사용량 조회 smoke
ory-clickhouse: Ory ClickHouse
Dump flow:
ory_clickhouse컨테이너 실행 상태를 확인한다.- Ory/Oathkeeper/Vector 계열 table schema와 일반 table data를 저장한다.
- table별 row count를
reports/ory_clickhouse-row-counts.txt에 기록한다.
Restore flow:
- restore 전용 Ory ClickHouse DB를 준비한다.
- schema를 적용한 뒤 일반 table data를 insert한다.
- Vector/Oathkeeper 기동 후 신규 로그가 같은 table로 유입되는지 확인한다.
영향도:
- Ory edge 접근 로그와 gateway 관측 자료가 손실된다.
- 인증/인가 원장은 Postgres에 있으므로 서비스 기동 자체 영향은 제한적이다.
- 보안 사고 분석, OIDC redirect 장애 분석, rate/anomaly 분석에는 영향이 크다.
검증 포인트:
- Oathkeeper access log row count 비교
- Oathkeeper 경유 요청 후 신규 로그 유입 확인
- Vector pipeline 재기동 후 error log 확인
config: 설정 snapshot
Dump flow:
.env가 있으면 secret 성격 key를REDACTED로 치환해config/env.redacted를 만든다.config/.generated/ory,gateway, 주요 compose 파일을 tar snapshot 또는 file copy로 보존한다.- 실제 secret 원문은 1차 로컬 구현의
env.redacted에 포함하지 않는다. 운영 백업에서는 별도 암호화 산출물로 보관해야 한다.
Restore flow:
make restore ... RESTORE_SERVICES=config실행 시 운영 파일을 직접 덮어쓰지 않는다.- snapshot은
config-restored/에 풀어 운영자가 diff로 검토한다. - secret 원문은 승인된 secret manager 또는 암호화 백업에서 별도 복원한다.
make validate-auth-config,make verify-auth-config로 callback/redirect/gateway mapping을 검증한다.- Ory Stack과 gateway를 기동한 뒤 대표 callback과 OIDC flow를 확인한다.
영향도:
- DB가 정상이어도 Hydra system secret, Kratos config, Oathkeeper rule, WORKS private key, callback URL이 맞지 않으면 서비스가 정상 동작하지 않는다.
env.redacted만으로는 운영 복구가 완성되지 않는다. 운영 복구용 secret은 별도 암호화 저장소가 필요하다.- config를 운영 파일에 바로 덮어쓰면 현재 환경의 도메인, callback, gateway rule을 깨뜨릴 수 있으므로 수동 검토가 기본이다.
검증 포인트:
make validate-auth-configmake verify-auth-config- gateway/Oathkeeper route smoke
- WORKS credential dry-run 또는 외부 호출 차단 상태 검증
제외 대상의 복구 영향
| 제외 대상 | 제외 이유 | 복구 후 영향 | 운영 대응 |
|---|---|---|---|
| Redis | cache, pending login, short code 등 휘발성 상태 | 진행 중인 login/link/short code flow가 만료되거나 재시작된다. | 사용자에게 재시도 안내, 서비스 기동 후 cache 재수렴 확인 |
| 프론트 빌드 산출물 | 소스와 이미지 태그로 재생성 가능 | 기존 정적 파일을 그대로 보존하지 않는다. | 동일 commit/image tag로 재배포 |
| 로컬 reports/coverage/test-results | 운영 원장이 아님 | 운영 서비스 영향 없음 | CI artifact나 별도 관측 저장소 기준으로 확인 |
전체 복구 순서와 의존성
Full restore는 다음 순서를 기본으로 한다.
- restore 전용 빈 환경과 volume을 준비한다.
configsnapshot을config-restored/에 풀고 운영자가 secret/config 차이를 검토한다.ory-postgres를 복구한다.postgres를 복구한다.ory-clickhouse와clickhouse를 복구한다.make dump-verify와make restore-verify로 산출물 무결성을 확인한다.make validate-auth-config,make verify-auth-config로 Ory/gateway 설정을 확인한다.- Ory Stack을 먼저 기동하고 Kratos/Hydra/Keto health를 확인한다.
- backend와 app을 기동한다.
- super admin login, 일반 사용자 login, 대표 RP OIDC login/consent를 확인한다.
- WORKS comparison dry-run을 수행한다.
- 대량 delete/upsert 위험이 없을 때 relay worker와 외부 동기화를 재개한다.
부분 복구는 원칙적으로 장애 분석 또는 rehearsal에서만 사용한다. 운영에서 특정 저장소만 과거 시점으로 되돌리면 cross-store 정합성이 깨질 수 있으므로, 실제 운영 restore는 같은 backup directory에서 나온 동일 시점의 산출물을 함께 적용하는 것을 기본으로 한다.
Restore 입력과 report:
make dump,make restore,make upload-cloud는 기본적으로 Debian Trixie slim 기반baron-sso-backup-tools:local컨테이너에서 실행한다.- 호스트 요구사항은 Docker와 Docker socket 접근 권한으로 제한한다.
zstd,jq,curl,openssl,postgresql-client,docker-cli는 backup-tools image에 포함한다. make restore BACKUP=<backup-dir>는 압축 해제된 백업 디렉터리를 입력으로 사용한다.make restore DUMP_FILE=<backup>.tar.zst는 archive를 임시 디렉터리에 풀어 복구한다.BACKUP과DUMP_FILE은 동시에 지정하지 않는다.- restore report 기본 위치는
BACKUP입력일 때<backup-dir>/reports/restore-report.json,DUMP_FILE입력일 때reports/restore/<archive-name>-restore-report.json이다. - restore report JSON이 생성되면 같은 경로에
.md확장자의 Markdown 요약도 함께 생성한다. RESTORE_REPORT=<path>로 report 경로를 명시할 수 있다.- restore report는 checksum 검증, 서비스별 복구 대상, 복구 후 row count 비교, config snapshot copy 위치를 기록한다.
- 외부 접속을 막은 상태에서 복구하려면 app/Ory serve/gateway를 먼저 중지하고 Postgres/ClickHouse/Redis만 기동해 restore를 수행한 뒤 검증 통과 후 Ory/backend/frontend를 순차 기동한다.
외부 분산 저장: WORKS Drive 업로드
로컬 dump가 끝난 뒤 같은 백업 디렉터리를 외부 저장소에 분산 보관하기 위해 scripts/backup/upload_cloud.sh를 사용한다. 현재 1차 대상은 WORKS Drive다.
Upload flow:
make dump BACKUP=...또는make dump-upload-cloud BACKUP=...로 백업 산출물을 만든다.dump.sh가reports/backup-report.md를 생성한다. report에는 사용자 수, 테넌트 수, RP 수, Hydra client 수, WORKS 관련 row count, 서비스별 수행 시간이 Markdown 표로 기록된다.upload_cloud.sh가 백업 디렉터리를baron-sso-backup-*.tar.zst로 압축한다.- Drive API용 access token을 확인한다.
WORKS_DRIVE_ACCESS_TOKEN,WORKS_DRIVE_ACCESS_TOKEN_FILE,WORKS_DRIVE_ACCESS_TOKEN_CMD는 항상 최우선이다.WORKS_DRIVE_AUTH_MODE=auto기본값은 service account credentials가 완비되어 있으면WORKS_DRIVE_OAUTH_*서비스 계정 JWT 토큰 발급을 먼저 사용하고, 없으면WORKS_DRIVE_OAUTH_REFRESH_TOKEN갱신으로 fallback한다.WORKS_DRIVE_AUTH_MODE=service-account는 service account JWT 토큰 발급을 강제한다.WORKS_DRIVE_AUTH_MODE=refresh-token은 service account 설정이 있어도 refresh token 갱신을 강제한다.
- WORKS Drive upload URL 생성 API를 호출한다.
- 발급받은 upload URL에 multipart
Filedata로.tar.zstarchive를 업로드한다. WORKS_DRIVE_UPLOAD_REPORTS=true이면 대상 폴더 아래WORKS_DRIVE_REPORT_FOLDER_NAME하위 폴더를 찾거나 생성한 뒤reports/*.md만 업로드한다.- 업로드 파일명은
backup-report-YYYYMMDD-HHMMSSZ.md처럼 업로드 시각을 붙인다. reports/cloud-upload.json은 로컬 실행 기록이며 Drive 업로드 대상에서 제외한다.
- 업로드 파일명은
- 업로드 결과를
reports/cloud-upload.json에 기록한다.
대상 drive 선택:
WORKS_DRIVE_TARGET |
필요 변수 | 업로드 URL 생성 API |
|---|---|---|
sharedrive |
WORKS_DRIVE_SHARED_DRIVE_ID, 선택 WORKS_DRIVE_PARENT_FILE_ID |
/v1.0/sharedrives/{sharedriveId}/files[/<folderFileId>] |
mydrive |
선택 WORKS_DRIVE_USER_ID, 선택 WORKS_DRIVE_PARENT_FILE_ID |
/v1.0/users/{userId}/drive/files[/<folderFileId>] |
group |
WORKS_DRIVE_GROUP_ID, 선택 WORKS_DRIVE_PARENT_FILE_ID |
/v1.0/groups/{groupId}/folder/files[/<folderFileId>] |
sharedfolder |
WORKS_DRIVE_USER_ID, WORKS_DRIVE_SHARED_FOLDER_ID, 선택 WORKS_DRIVE_PARENT_FILE_ID |
/v1.0/users/{userId}/drive/sharedfolders/{sharedFolderId}/files[/<folderFileId>] |
운영 주의:
- 업로드 archive는
.tar.zst로 고정한다.zstd가 없으면 실패해야 한다. - Drive API는
filescope가 필요하다. WORKS_DRIVE_PARENT_FILE_ID는 폴더 이름이나 경로가 아니라 WORKS Drive API가 반환하는 폴더fileId여야 한다.- 계정 동기화용
WORKS_ADMIN_OAUTH_*와 백업 업로드용WORKS_DRIVE_OAUTH_*는 용도가 다른 앱/키로 분리한다. - 운영 기본 경로는 Drive용 access token을 명시 주입하거나 service account JWT를 사용하는 방식이다.
- refresh token을 재발급해 사용하는 경우
make works-drive-refresh-token을 사용한다. WORKS OAuth refresh token은 Authorization Code Flow에서 발급되며, WORKS Token 설정의 Refresh Token Rotation 상태에 따라 갱신 응답에 새 refresh token이 포함될 수 있다.- 기존 refresh token이 아직 유효하면
make works-drive-refresh-token WORKS_DRIVE_TOKEN_GRANT=refresh-token로.env의WORKS_DRIVE_OAUTH_REFRESH_TOKEN을 자동 갱신한다. - 기존 refresh token이 폐기되어 401이 발생하면
WORKS_DRIVE_TOKEN_GRANT=print-authorize-url scripts/backup/refresh_works_drive_token.sh로 출력된 URL을 브라우저에서 승인한 뒤, callback의code를make works-drive-refresh-token WORKS_DRIVE_TOKEN_GRANT=authorization-code WORKS_DRIVE_AUTH_CODE=<code>에 전달한다. - callback URL 전체를 복사할 수 있으면
WORKS_DRIVE_AUTH_CALLBACK_URL=<callback-url>을 사용해도 된다. - 토큰 갱신 도구는 짧게 만료되는 access token을
.env에 저장하지 않고 refresh token과WORKS_DRIVE_AUTH_MODE=refresh-token만 갱신한다.
- 기존 refresh token이 아직 유효하면
- 서비스 계정 JWT는 Drive 업로드 앱 정책에서 Drive scope 위임이 허용되고 Client ID, Service Account, Private Key가 같은 앱에서 발급된 조합일 때만 성공한다.
- 파일 크기가 WORKS Drive 단일 파일 제한에 걸릴 수 있으면
WORKS_DRIVE_MAX_SINGLE_FILE_BYTES또는WORKS_DRIVE_FORCE_SPLIT=true로 split part 업로드를 사용한다. - Markdown report 업로드 기본 폴더명은
reports이며WORKS_DRIVE_REPORT_FOLDER_NAME으로 바꿀 수 있다. - 외부 업로드 성공은 복구 가능성을 보장하지 않는다. 업로드 후에도
make dump-verify BACKUP=...와 restore rehearsal을 별도로 수행해야 한다.
백업 모드
1. Offline backup
가장 안전한 모드다. 모든 writer를 중지한 뒤 dump한다.
순서:
- gateway 또는 Oathkeeper에서 maintenance mode 활성화
- backend, relay worker, vector 등 write producer 중지
- Kratos/Hydra/Keto public/admin 요청 차단 또는 컨테이너 중지
- Baron Postgres dump
- Ory Postgres의 Kratos/Hydra/Keto DB dump
- ClickHouse backup
- 설정/비밀값 백업
- checksum과 row count 생성
- 서비스 재개
이 모드는 사용자 UUID, WORKS mapping, Keto relation, OAuth consent 상태의 일관성이 가장 좋다.
2. Maintenance backup
짧은 점검 모드에서 writer만 막고 read는 제한적으로 허용한다. 운영 기본 모드로 권장한다.
필수 조건:
- 사용자 생성/삭제/수정 차단
- 테넌트/조직 변경 차단
- WORKS outbox relay 중지
- Keto outbox relay 중지
- OAuth client 변경 차단
3. Online best-effort backup
무중단 스냅샷이다. 저장소가 여러 개라 cross-store 일관성을 보장할 수 없다. 감사 로그나 분석용 백업에는 가능하지만, 재해 복구용 원본으로는 사용하지 않는다.
Postgres 백업 전략
Postgres는 논리 dump를 기본으로 한다.
pg_dump -Fc형식 사용- DB별 dump 파일 분리
pg_dumpall --globals-only로 role/extension/권한 정보 별도 보관- 백업 전후 row count와 핵심 UUID sample 기록
대상 DB:
- Baron DB:
DB_NAME - Kratos DB:
ory_kratos - Hydra DB:
ory_hydra - Keto DB:
ory_keto
복구는 빈 DB에 pg_restore --clean --if-exists로 수행한다. 기존 운영 DB에 덮어쓰는 in-place restore는 금지한다.
ClickHouse 백업 전략
ClickHouse는 감사 로그 성격이 강하므로 정책을 분리한다.
- 재해 복구: ClickHouse native backup 또는 volume snapshot 사용
- 장기 보관: 파티션 단위 export 또는 object storage backup
- 복구 검증: 날짜 파티션별 row count와 min/max timestamp 비교
ClickHouse 백업 실패가 인증 기능 복구를 막지는 않지만, 감사 로그 보존 정책상 별도 실패로 취급한다.
Redis 처리 원칙
Redis는 기본적으로 백업하지 않는다.
복구 후 영향:
- 로그인 pending flow 만료
- short code/link login flow 재시작 필요
- headless JWKS cache 재생성
- 세션 cache miss 발생 가능
Kratos/Hydra 자체 session/token 원장은 Postgres 쪽에 있으므로 Redis가 비어 있어도 서비스는 재수렴해야 한다.
설정과 비밀값
DB dump만으로는 복구가 불완전하다. 다음 항목은 암호화해서 함께 보관한다.
.env또는 배포 환경 변수- Ory generated config
- Hydra system secret, cookie secret
- Kratos courier/config secret
- Keto config
- Oathkeeper rules/config
- WORKS Admin OAuth client private key
- API gateway 설정
- object storage backup key id
env.redacted는 검토용이고, 실제 복구에는 env.encrypted만 사용한다.
복구 절차
Full restore 기본 절차
- 대상 환경을 새로 준비한다.
- 모든 애플리케이션 서비스를 중지한다.
- 기존 DB가 있으면 별도 보관 후 빈 DB를 만든다.
- Postgres globals를 복구한다.
- Baron DB를 복구한다.
- Kratos/Hydra/Keto DB를 복구한다.
- ClickHouse를 복구한다.
- 설정/비밀값을 복호화해 배치한다.
- migration은 자동 실행하지 않고 현재 dump의 schema version을 확인한다.
- Ory Stack을 기동한다.
- backend를 기동한다.
- relay worker는 아직 켜지 않는다.
- post-restore verification을 수행한다.
- WORKS comparison dry-run을 수행한다.
- 문제가 없을 때 relay worker와 외부 동기화를 재개한다.
Post-restore verification
필수 검증:
- Kratos identity 수와 Baron users 수 비교
- Baron
users.id가 Kratosidentities.id에 존재하는지 확인 - tenant parent tree 참조 무결성 확인
user_login_ids.user_id,user_login_ids.tenant_id참조 무결성 확인- Keto relation subject/object가 복구된 사용자/테넌트를 참조하는지 확인
- Hydra client와 Baron RP metadata 참조 확인
- WORKS mapping의 BaronResourceID가 복구된 사용자/테넌트를 참조하는지 확인
- super admin 로그인 확인
- 일반 사용자 로그인 확인
- 대표 RP OIDC login/consent 확인
- WORKS comparison dry-run에서 externalKey 기준 대량 삭제/생성 후보가 없는지 확인
WORKS 연동 복구 정책
WORKS 자체 데이터는 Baron 백업으로 복구하지 않는다. Baron이 보존해야 하는 것은 WORKS와 연결되는 참조 키다.
필수 보존:
- 사용자 UUID
- 테넌트 UUID
- WORKS resource mapping
- WORKS outbox 처리 상태
- WORKS domain mapping/config
복구 직후 정책:
- relay worker 자동 실행 금지
- comparison dry-run 먼저 실행
- externalKey 기준으로 Baron/WORKS가 매칭되는지 확인
- 대량 delete/upsert가 감지되면 동기화 중단
- 확인 후 필요한 사용자/조직만 재동기화
outbox는 복구 모드에 따라 처리한다.
| 복구 모드 | outbox 정책 |
|---|---|
| 같은 운영 환경 재해 복구 | outbox 상태 보존, 단 relay 재개 전 dry-run 필수 |
| staging rehearsal | outbox relay 비활성화, 외부 WORKS 호출 금지 |
| cross-env migration | outbox는 보존하되 실행하지 않고 별도 remap 정책 필요 |
CSV export/import의 위치
CSV는 다음 목적으로만 사용한다.
- 운영자가 사용자/조직을 일괄 등록하거나 보정
- 일부 필드를 검토하기 위한 추출
- dry-run 입력 보조 자료
CSV는 다음 목적에 사용하지 않는다.
- Kratos identity UUID 보존 복구
- 비밀번호/credential 복구
- OAuth consent/token/session 복구
- Keto relation 원장 복구
- WORKS mapping 원장 복구
구현 계획
Phase 1: 백업/복구 스크립트와 문서화
Estimate Time: 3~5d
scripts/backup/full-backup.shscripts/backup/full-restore.shscripts/backup/verify-backup.shscripts/backup/verify-restore.shmanifest.json생성기- checksum 생성
- row count report 생성
Phase 2: staging restore rehearsal
Estimate Time: 3~5d
- 백업 파일로 격리된 staging stack 복구
- Ory/Baron/Postgres/ClickHouse 복구 검증
- 로그인/OIDC/관리자 화면 smoke test
- WORKS 외부 호출 차단 상태에서 comparison dry-run
Phase 3: 운영 자동화
Estimate Time: 5~8d
- 정기 백업 스케줄링
- 암호화 및 object storage 업로드
- retention 정책
- 실패 알림
- restore rehearsal 주기화
Phase 4: 관리 UI
Estimate Time: 5~8d
- backup 목록 조회
- backup 생성 요청
- restore readiness report 조회
- staging rehearsal 결과 조회
- 운영 restore는 UI에서 직접 실행하지 않고 승인 절차와 runbook으로 제한
테스트 전략
단위 테스트
- manifest 생성 검증
- checksum 검증
- row count report 비교
- restore readiness parser 검증
통합 테스트
- fixture DB 생성
- full backup 실행
- 빈 DB로 restore
- 핵심 테이블 row count 비교
- 사용자/테넌트 UUID 동일성 비교
- Kratos identity와 Baron user ID 일치 검증
E2E 테스트
- super admin 로그인
- 일반 사용자 로그인
- AdminFront 사용자 목록 조회
- UserFront 로그인
- 대표 RP OIDC 로그인
- WORKS comparison dry-run
실패 테스트
- 누락된 dump 파일
- checksum 불일치
- schema version 불일치
- 일부 DB만 복구된 상태
- Kratos identity는 있는데 Baron user가 없는 상태
- Baron user는 있는데 Kratos identity가 없는 상태
- WORKS mapping이 복구되지 않은 상태
운영 정책
- 백업은 암호화하지 않은 상태로 저장하지 않는다.
- 운영 restore는 빈 환경 또는 새 볼륨에만 수행한다.
- restore 전 현재 운영 DB는 별도 snapshot으로 보존한다.
- restore 후 WORKS relay는 수동 승인 전까지 비활성화한다.
- 월 1회 이상 staging restore rehearsal을 수행한다.
- schema migration 직전 수동 backup을 강제한다.
남은 결정 사항
- RPO/RTO 목표값
- 백업 저장 위치와 암호화 key 관리 방식
- ClickHouse 장기 보관 기간
- WORKS outbox replay 정책의 운영 기본값
- 운영 restore 승인자와 절차
- restore rehearsal 자동 실행 주기