OpenShip 비밀 키 관리: 플랫폼과 서버 선택

공식 설명상 OpenShip은 빌드한 이미지를 대상 서버로 전달하고 운영 서버에서는 빌드를 수행하지 않습니다. (openship.io)

증상 → 가장 빠른 해법: 키가 코드에는 없는데 이미지나 빌드 로그에서 발견된다면, 현재 값을 지우는 데 그치지 말고 키를 폐기한 뒤 실행 시 주입 방식으로 바꾸세요. 일반 애플리케이션 키는 격리된 플랫폼 비밀 기능에 두고, 서버가 직접 사용해야 하는 기반 시설 자격 증명만 서버에 남기는 구성이 기본값입니다.

이 글은 OpenShip에 처음 모델 API 키를 배포하는 개발자, 미리보기와 운영 환경을 함께 관리하는 소규모 팀, 운영 배포와 장애 복구 절차를 책임지는 기술 담당자를 위한 글입니다. 단순히 플랫폼과 서버 중 하나를 고르는 대신, 어떤 문제가 발생했을 때 어느 저장 위치가 책임을 줄이는지 판단합니다.

먼저 확인할 것: 키가 현재 파일에 없다는 말은 충분하지 않습니다

가장 위험한 사례는 .env 파일을 저장소에 올린 경우만이 아닙니다. 키를 코드에서 제거했더라도 다음 위치에 남을 수 있습니다.

  • 이전 커밋과 삭제된 파일
  • 도커 파일의 인자와 실행 명령
  • 이미지 계층과 빌드 캐시
  • 빌드 출력, 디버그 로그, 오류 추적 정보
  • 브라우저에 전달되는 공개 변수
  • 클라이언트 묶음 파일과 소스 맵

도커 공식 문서도 빌드 인자와 환경 변수를 빌드 비밀 전달 수단으로 쓰면 최종 이미지에 남을 수 있다고 설명합니다. 빌드 과정에서만 필요한 값은 임시 비밀 마운트처럼 이미지에 기록되지 않는 방식을 사용해야 합니다. (docs.docker.com)

이미 유출이 의심된다면 순서는 다음과 같습니다.

  1. 모델 제공 업체에서 기존 키를 즉시 폐기합니다.
  2. 저장소 전체와 이전 기록에서 키 형식을 검색합니다.
  3. 이미지 계층과 빌드 출력에서 값의 흔적을 찾습니다.
  4. 브라우저 묶음과 공개 환경 변수에 포함되었는지 확인합니다.
  5. 새 키를 발급하고 사용량과 호출 주소를 감시합니다.

저장소에서 현재 파일만 검색하면 부족합니다. 깃은 참조되지 않는 객체와 리플로그에 이전 데이터가 남을 수 있으므로, 기록까지 점검해야 합니다. (git-scm.com)

첫 번째 단계: 환경을 나누고 책임 경계를 고정합니다

미리보기, 테스트, 운영을 같은 변수 묶음으로 관리하면 편하지만 사고 범위가 커집니다. 미리보기 애플리케이션이 운영 데이터베이스나 정식 모델 계정에 접근하는 순간, 코드 검토만으로는 사고를 막을 수 없습니다.

OpenShip 공식 페이지는 미리보기 배포와 자체 서버 및 클라우드 배포 흐름을 설명하지만, 공개 설명만으로 각 설치 형태의 비밀 값 가림, 환경별 접근 제한, 감사 기능을 안전하게 검증했다고 볼 수는 없습니다. 특히 클라우드와 혼합 배포의 기능 입구는 사용 중인 버전에서 따로 확인해야 합니다. (openship.io)

구분 미리보기 테스트 운영
모델 키 사용량 제한 키 제한된 테스트 키 운영 전용 키
데이터베이스 가상 또는 복제 데이터 검증용 데이터 운영 데이터
권한 읽기 중심 기능 검증 범위 필요한 기능만 허용
로그 값 가림 확인 호출 실패 원인 기록 접근과 교체 기록 보존
복구 기준 다시 발급 가능 재현 가능한 설정 승인자와 복구 순서 문서화

플랫폼 환경 변수의 장점은 환경별 값을 복사하고 배포 대상에 연결하기 쉽다는 점입니다. 서버의 .env는 운영체제 권한과 파일 배치까지 직접 통제할 수 있다는 장점이 있습니다. 대신 팀원이 서버에 접속할 수 있으면 파일 읽기 권한이 곧 비밀 값 접근 권한이 되기 쉽습니다.

서버에 남겨야 하는 값은 서버 자체를 관리하는 데 필요한 자격 증명으로 제한하세요. 예를 들어 배포 대상에 접속하는 인증서, 서버 내부 서비스의 로컬 연결 정보처럼 애플리케이션 플랫폼 밖에서 먼저 필요한 값은 서버 저장이 합리적입니다. 모델 API 키, 결제 API 키, 외부 메일 발송 키처럼 애플리케이션이 실행될 때 필요한 값은 플랫폼 또는 외부 비밀 저장소가 더 적합합니다.

두 번째 단계: 저장 위치보다 교체 가능한 구조를 선택합니다

OpenShip 비밀 키 관리를 설계할 때 콘솔에 값이 저장되었다는 표시를 성공 기준으로 삼으면 안 됩니다. 실제 성공 기준은 다음 세 가지입니다.

  • 새 요청이 새 키로 처리됩니다.
  • 이전 키는 폐기되어 더 이상 사용할 수 없습니다.
  • 새 키가 실패했을 때 이전 정상 상태로 복구할 수 있습니다.

플랫폼에 저장한 키라도 애플리케이션이 시작할 때만 읽는다면 값을 바꾼 뒤 재시작이나 재배포가 필요합니다. 서버 .env도 파일만 바꾸면 끝나는 것이 아니라 프로세스가 새 값을 읽도록 재시작해야 합니다. 이 차이를 문서에 적지 않으면 담당자는 저장 성공을 서비스 반영으로 오해합니다.

교체 방식 장점 위험 통과 조건
기존 값 즉시 덮어쓰기 절차가 짧습니다 새 키 오류 시 즉시 장애가 납니다 새 요청 성공과 이전 키 거부를 확인합니다
새 키와 이전 키 병행 무중단 전환이 쉽습니다 두 키가 한동안 살아 있습니다 사용 위치를 추적한 뒤 이전 키를 폐기합니다
외부 저장소에서 실행 시 조회 이미지 재생성이 줄어듭니다 외부 저장소 장애와 권한 설정이 추가됩니다 조회 실패와 복구 경로를 시험합니다

일반적인 권장 순서는 새 키 발급, 제한된 환경에서 호출 확인, 운영 값 교체, 애플리케이션 재시작 또는 새 값 조회 확인, 이전 키 폐기, 로그와 사용량 확인입니다. 비밀 관리 권고도 새 값 생성, 적용, 시험, 이전 값 폐기를 분리한 교체 절차를 권장합니다. (cheatsheetseries.owasp.org)

주의: 새 키를 저장한 뒤 이전 키를 바로 폐기하지 마세요. 새 요청이 실제로 새 값을 사용하고 있는지 확인한 다음 폐기해야 합니다. 반대로 병행 기간을 문서화하지 않으면 폐기되지 않은 키가 장기간 남습니다.

세 번째 단계: 팀 권한을 값이 아니라 작업 단위로 나눕니다

팀원에게 비밀 값을 직접 보여주는 권한과 배포를 실행하는 권한은 분리해야 합니다. 운영 담당자가 값을 볼 필요 없이 교체 작업만 수행할 수 있다면 노출 경로가 줄어듭니다.

역할 허용할 작업 막아야 할 작업
개발 담당 미리보기 배포, 테스트 호출, 실패 로그 확인 운영 값 열람과 수정
배포 담당 운영 배포, 값 교체 요청, 재시작 팀 역할과 감사 설정 변경
관리자 역할 변경, 승인, 감사 기록 확인, 복구 승인 개인 계정 공유
자동화 계정 필요한 프로젝트의 배포와 값 갱신 전체 프로젝트 조회와 대화형 로그인

OpenShip 공식 가격 페이지는 요금제별 팀 역할과 감사 기록 기능을 소개합니다. 다만 이 설명은 현재 네가 사용하는 클라우드, 자체 서버 또는 혼합 배포에서 동일하게 동작한다는 뜻이 아닙니다. 실제 화면에서 다음을 확인해야 합니다.

  • 값 자체를 다시 볼 수 있는가
  • 환경별로 수정 권한을 나눌 수 있는가
  • 배포 실행자와 값 변경자를 구분할 수 있는가
  • 변경 시각, 계정, 대상 프로젝트가 기록되는가
  • 개인 계정이 삭제되어도 자동화 배포가 계속되는가

공개 문서에 기능이 적혀 있다는 이유만으로 보안 검증을 끝내면 안 됩니다. 권한 테스트 결과와 실제 감사 기록을 배포 승인 자료로 남겨야 합니다. 최소 권한과 비밀 값 접근 기록은 일반적인 비밀 관리 원칙에서도 핵심 항목입니다. (openship.io)

네 번째 단계: 장애 복구를 배포 절차에 포함합니다

서버가 고장 난 뒤 애플리케이션 데이터를 복원해도 비밀 값이 없으면 서비스는 시작되지 않습니다. 복구 자료는 다음 세 부분으로 나누어야 합니다.

  1. 애플리케이션과 데이터베이스 백업
  2. OpenShip 프로젝트와 환경 설정의 복구 방법
  3. 외부 비밀 저장소 또는 키 발급 계정의 재승인 절차

백업 파일에 운영 키를 평문으로 넣으면 복구 편의성이 보안 사고로 바뀝니다. 백업에는 변수 이름, 사용 목적, 발급 주체, 교체 방법만 기록하고 실제 값은 별도 비밀 저장소에 두는 편이 안전합니다.

복구 시험에서는 다음을 직접 확인하세요.

  • 새 서버에서 애플리케이션이 어떤 순서로 시작되는가
  • 비밀 저장소에 접근할 수 있는 계정은 누구인가
  • 관리자 한 명이 부재해도 재승인이 가능한가
  • 키가 없는 상태에서 오류가 평문으로 노출되지 않는가
  • 운영 데이터베이스와 모델 API가 모두 정상 호출되는가

OpenShip 생산 배포 점검 항목을 별도 문서로 만들어 배포 승인 전에 확인하면, 설정 화면의 저장 여부와 실제 서비스 복구 여부를 분리해서 기록할 수 있습니다.

최종 선택: 단일 저장보다 분층 구성이 안전합니다

모든 키를 플랫폼에 몰아넣거나 모든 값을 서버 .env에 두는 방식은 각각 책임이 한곳에 집중됩니다. 다음 기준으로 분류하면 선택이 단순해집니다.

  • 애플리케이션 API 키: 환경별 플랫폼 비밀 기능
  • 서버 접속과 배포 자격 증명: 대상 서버의 운영체제 또는 배포 전용 계정
  • 짧게 쓰는 임시 토큰: 외부 Secrets Vault 또는 자동 발급 방식
  • 유출 시 피해가 큰 운영 키: 외부 비밀 저장소와 플랫폼 실행 권한의 분리
  • 브라우저에 노출되어도 되는 공개 설정: 공개 환경 변수로 명시하고 비밀 값과 분리

플랫폼 기능이 환경 격리, 최소 권한, 감사 기록, 재배포 동작을 모두 충족하면 일반적인 모델 API 키는 플랫폼 저장이 관리하기 쉽습니다. 반대로 설치 형태에서 역할과 감사 기능을 확인할 수 없거나, 복구 자료를 플랫폼에만 의존해야 한다면 외부 비밀 저장소를 추가하세요.

자체 서버에 직접 저장하는 방식은 장기 운영에서 유연하지만 파일 권한, 백업 암호화, 접속자 추적, 키 교체 자동화까지 네 팀이 책임져야 합니다. 팀 규모가 커질수록 .env 자체보다 누가 파일을 읽고 복사했는지 확인하기 어려워지는 점이 더 큰 비용이 됩니다.

배포 전 확인 목록

  • [ ] 저장소의 현재 파일과 이전 기록에서 키를 검색했습니다.
  • [ ] 도커 파일의 인자와 이미지 계층에 비밀 값이 없는지 확인했습니다.
  • [ ] 빌드 로그와 오류 추적 정보가 값을 가리는지 확인했습니다.
  • [ ] 미리보기, 테스트, 운영 키를 서로 다른 값으로 발급했습니다.
  • [ ] 미리보기 키가 운영 데이터와 정식 계정에 접근하지 못하는지 확인했습니다.
  • [ ] 새 키 적용 뒤 새 요청이 성공하는지 확인했습니다.
  • [ ] 이전 키가 폐기되었고 호출이 거부되는지 확인했습니다.
  • [ ] 개발, 배포, 관리자 역할을 개인 계정 기준으로 나눴습니다.
  • [ ] 서버 장애 뒤 비밀 값을 다시 승인하는 담당자를 정했습니다.
  • [ ] 복구 시험에서 평문 키가 백업과 로그에 남지 않았습니다.

GitHub를 사용한다면 푸시 보호 기능으로 하드코딩된 자격 증명이 저장소에 들어가는 시점을 차단할 수 있습니다. 다만 탐지 기능은 모든 키 형식을 잡는다고 보장하지 않으므로, 저장소 기록과 이미지 검사를 함께 수행해야 합니다. (docs.github.com)

원격 맥 환경의 배포 권한 관리 안내도 함께 확인하면, 비밀 값뿐 아니라 빌드 장비에 남는 개인 계정과 자동화 자격 증명까지 분리할 수 있습니다.