Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

Infisical: 오픈소스 시크릿 관리 플랫폼

얼마 전에 쓴 내가 생각하는 스타트업 미니멀 인프라 스택에서 마지막에 Infisical이라는 서비스에 대해서 언급했다. 사실 인터넷에서 어쩌다 알게 된 서비스이고 제대로 써 본 적은 없지만 처음 세팅할 때부터 비밀번호나 토큰 같은 시크릿 관리는 잘 해두는게 좋겠다는 생각이 있었고 요즘 시크릿 관리는 어떻게 하는 게 안전하겠냔 생각이 많았기 때문이기도 하다.

시크릿 관리는 이론상으로는 좋은 방법이 많이 있지만 현실에서는 쉽지 않은 부분이 많아서 어떻게 하면 안전하게 관리할 수 있는지 고민을 많이 하고 있다. 나는 틈틈이 고민하는 편이고 이렇게 시크릿 관리로 서비스를 만드는 스타트업은 아무래도 하루 종일 이 생각만 할 테니까 너무 좋아서 그대로 쓸 수 있다면 더 좋고 아니어도 인사이트를 얻을 수 있을 것 같아서 좀 더 살펴봤다.

Infisical - Open Source SecretOps

Infisical - Open Source SecretOps

위 사이트에 나온 대로 오픈소스 시크릿옵스를 내세우고 있고 팀, 기기, 인프라스트럭처에 시크릿과 구성을 안전하게 동기화하는 오픈소스 E2E 암호화 플랫폼이라고 설명한다.

Infisical Cloud에서 호스팅 서비스를 제공하지만 오픈소스 프로젝트이기 때문에 직접 설치해서 사용할 수도 있다. 내 생각에는 서비스 보안에 아주 중요한 시크릿 관리는 신생 스타트업에 맡기기에는 심리적 부담감이 있기 때문에 오픈소스로 공개해서 기술력도 보여주면서 안심하고 쓸 수 있게 하려는 것으로 생각한다.

셀프 호스팅 문서를 보면 AWS, Degita Ocean, Kubernetes, Docker Compose 등 다양하게 직접 운영할 방법을 안내하고 있다. 시크릿 관리 시스템은 꽤 중요하기 때문에 실제로 운영하면 HA나 데이터 보관 관리 등 확인해 볼 게 많지만, 다양한 옵션을 잘 준비해 놓은 것으로 보인다.

셀프 호스팅을 해도 Infisical Cloud처럼 UI도 제공하기 때문에 직접 설치 테스트는 안 해보고 Infisical Cloud로 테스트해 봤다.

UI

회원 가입을 하면 조직이 하나 만들어지고 조직 하위에 프로젝트를 생성해서 시크릿을 관리할 수 있다. 아래는 기본적으로 만들어지는 Example Project의 시크릿 화면이다.

Infisical 시크릿 화면

위 예시에서는 Development, Test, Staging, Production 4개의 환경이 만들어져 있다. 물론 이 환경은 Project Settings에서 추가/삭제를 할 수 있다.

Explore를 눌러서 각 환경에 들어가면 시크릿을 관리할 수 있다.

Development 환경의 시크릿 관리

시크릿의 키와 값을 설정하고 주석이나 태그도 입력할 수 있다. 하단에 나오듯이 .env, .json, .yml 파일을 업로드할 수 있는데 환경변수 관리할 때 로컬에서 환경 변수를 추가하면서 작업할 가능성이 높기 때문에 이를 그대로 업로드해서 설정할 수도 있고 설정한 환경변수를 .env.yml로 다운받는 것도 가능하다. 대부분의 개발자는 로컬에 환경변수 관리하는 파일을 가지고 있겠지만 뒤에서 설명할 CLI를 쓰면 이러한 프로세스도 바꿀 수 있을거라고 생각한다.

각 변경 사항은 커밋 히스토리로 관리하는데 이건 환경별로 기록되는 게 아니라 이 전체 시크릿의 변경 히스토리이다. 개인적으로는 한 프로젝트에 시크릿 그룹이 1개밖에 없는건 좀 아쉬운 부분이라고 생각했다.

시크릿 오버라이드

이 부분이 좀 흥미롭게 느껴졌는데 시크릿 별로 이 값을 다른 키로 오버라이드할 수 있는지를 설정할 수 있다.

특정 시크릿 상세 화면

시크릿의 상세 화면에 들어가면 세부 값을 볼 수 있는데 위는 일부러 오버라이드를 비활성화한 화면인데 오버라이드를 비활성화하면 설정된 시크릿의 값을 볼 수 있다.

특정 시크릿 상세 화면에서 오버라이드 설정

오버라이드를 활성화하면 내가 쓸 개인값으로 바꿀 수 있다. UI로 봤을 때 좀 헷갈렸지만, 문서를 보면 이는 로그인한 계정에 개인화된 기능이다. 즉, 여기서 Development 환경의 DB_USERNAME 환경변수의 값은 OVERRIDE_THIS이지만 내가 이 환경의 값을 받아올 때는 local_username이 되는 것이다. 개발환경 같은 경우는 로컬에 데이터베이스를 따로 띄워서 실행하는 경우가 있어서 특정 환경변수만 바꿔 쓰는 경우가 있는데 이럴 때 개인 설정도 같이 관리할 수 있는 것이다.

시크릿의 각 환경 값 비교

리스트에서도 볼 수 있긴 하지만 시크릿을 기준으로 각 환경을 비교할 수 있는 것도 재밌었지만 여기서 바로 수정하지 못하는 건 아쉬웠다.

시크릿 오딧 로그

Audit 로그도 제공하고 있어서 누가 시크릿을 조회하고 수정했는지에 대한 기록을 볼 수 있다.

CLI

Infisical에서는 CLI를 제공하고 있는데 로컬 환경뿐 아니라 다양한 프레임워크와 통합할 때도 사용할 수 있도록 제공하고 있기 때문에 Infisical에서 의도하는 시크릿 통합에서 중요한 역할을 하는 것으로 보인다.

macOS라면 Homebrew를 이용해서 설치할 수 있다.

$ brew install infisical/get-cli/infisical

CLI를 설치했으면 infisical login으로 인증을 한다.

$ infisical login
Use the arrow keys to navigate: ↓ ↑ → ←
? Current INFISICAL_API_URL Domain Override: :
    Use Domain
  ▸ Change Domain

오픈소스로 설치형으로도 쓸 수 있기 때문에 이런 안내가 나오는 것인데 Infisical을 설치한 도메인을 INFISICAL_API_URL 환경변수로 설정할 수 있는 것으로 보인다. 지금은 INFISICAL_API_URL를 설정하지 않았고 SaaS로 제공되는 Infisical을 사용하므로 "Change Domain"을 선택한다.

$ infisical login
✔ Change Domain
✔ Infisical Cloud
Email: my@email.com
Password: ***
>>>> Welcome to Infisical! You are now logged in as outsideris@gmail.com <<<<

Quick links
- Learn to inject secrets into your application at https://infisical.com/docs/cli/usage
- Stuck? Join our slack for quick support https://infisical.com/slack

이제 사용할 프로젝트에서 초기화한다. 앞에서 "Example Project" 프로젝트만 있었기 때문에 목록에서 이를 선택했다.

$ infisical init
✔ Example Project

이제 해당 로컬 환경에 Infisical 프로젝트와 연결되었다. CLI를 쓰면 시크릿을 관리할 수 있는데 이를 이용해서 시크릿을 추가, 수정, 삭제가 가능하다. infisical export 명령어를 사용하면 환경변수를 로컬로 가져오는 것이 가능하다.

$ infisical export --env "dev" --format dotenv
TWILIO_AUTH_TOKEN='example_twillio_token_test'
WEBSITE_URL='http://localhost:3000'
ENV='dev'
DATABASE_URL='mongodb+srv://local_username:local_password@mongodb.net'
DB_USERNAME='local_username'
DB_PASSWORD='local_password'

여기서 플래그를 일부러 주었는데 기본값인 dev환경(Development 환경의 slug를 지정할 수 있다.)의 시크릿을 dotenv 형식으로 출력하게 했다. 환경변수가 다 출력되기도 했지만 여기서 DB_USERNAMEDB_PASSWORD는 원래의 값이 아닌 아까 오버라이드한 개인 값으로 받아온 것을 알 수 있다. 실제값은 그대로 두고 내가 사용할 개발환경의 값을 받아올 수 있고 따로 관리할 수 있다는 점이 좋아 보였다. 이걸 바로 파일로 저장하려면 infisical export --env "dev" --format dotenv > .env와 같이 실행하면 된다.

마지막으로 infisical run 명령어를 사용하면 서버에 저장된 시크릿을 받아와서 바로 사용할 수 있다.

$ env | grep DB

$ infisical run --env "dev" -- env | grep DB
DB_USERNAME=local_username
DB_PASSWORD=local_password

infisical run -- <COMMAND>로 연결하면 환경변수를 서버에서 받아와서 환경변수로 설정해 준다. 기존에는 환경 변수가 없었지만, 앞에서 오버로드 설정한 대로 설정된 것을 볼 수 있다. 원격으로 받아오는 것에 대한 딜레이가 좀 신경 쓰일 수 있지만 dotenv에 대한 지원은 기존 개발환경을 위한 거로 생각하고 infisical run 명령어가 Infisical에서 의도하는 부분인 거라는 생각이 들었다. npm run dev로 서버를 실행한다면 infisical run -- npm run dev로 실행하면 그만이다. 기존 환경을 바꾸긴 쉽지 않지만, 처음부터 여기에 맞춘다면 로컬에선 아예 환경 변수를 관리하지 않고 협업하면서 환경변수를 관리하는 게 가능할거라고 생각한다.

최근에 시크릿 관리에 대해 고민도 하는 편인데 결국 다른 곳을 다 막아도 엔지니어 로컬에는 상당한 시크릿이 파일로 보관되어 있기 쉽고 유출되는 많은 환경이 직접 환경 변수를 복사하거나 이동하는 경우라고 생각한다. 그런 부분을 감춰주어 직접 다룰 필요가 없게 만들어 주는 것은 보안 관점에서는 꽤 장점이 보였다.

이 외에도 Kubernetes도 오퍼레이터로 지원하고 각종 CI나 GitHub, Fly.io, AWS 등의 플랫폼도 시크릿 동기화를 지원하기 때문에 Infisical을 중심으로 시크릿을 관리하고 각 서비스를 연동하는 것도 나쁘지 않아 보인다. 물론 서비스에서 쓰는 것은 훨씬 고려해야 할 것이 많기 때문에 여기서는 가볍게 살펴보는 정도로만 정리했다.(시크릿을 관리하는 좋은 방법을 찾고 싶다...)

2023/04/29 00:25 2023/04/29 00:25