# 매번 .env 를 팀원들에게 알려줘야할까?

사이드 프로젝트를 진행하다보면 신규 팀원이 들어오는 경우에는 환경변수 파일에 대한 내용을 공유한다. 그런데 사실 이미 개발을 진행하다보면, 프로젝트가 점점 커지면서 어떤 환경변수가 구성되어있는지 잘 모르는 경우도 있고, 만약 누군가 새로운 환경변수를 추가한 경우에는 다른 사람에게 알림을 주지 않는 이상 잘 모르고 넘어간다.

그런데 여기서 문제는.. 나중에 빌드 상황에서 누락된 환경변수로 인해 빌드 에러가 발생하거나, 환경변수 히스토리가 누락된 경우에는 어떤 환경 변수가 있었는지에 대한 추적이 불가능하다. 여기서 매번 `.env` 파일을 공유하다 문득 궁금한 점이 생겼다. "환경 변수를 이렇게 매번 파일로 공유하고, 매번 메신저로 공유해줘야하나?"

## 클라우드 환경에서 환경변수 가져오기

보통 `.env` 의 경우에는 파일 내에 정적 정보로 저장된다. 그래서 `.env` 는 외부로 유출되면 절대적으로 안되며, 정말 중요한 정보들이 들어가는 경우가 많다. 또 실수로 환경변수가 공개된 저장소에 올라가게되면, 잠깐의 찰나라도 공격당하는 경우가 있을 수 있다. (여기서 공격 당하는 경우라고 하면, 중요한 내부 키가 탈취당해 과금이 나오는 경우 ^,^ ..)

그래서 이러한 환경변수들을 클라우드 환경에서 업데이트될 때마다 내려받고, 더이상 개발자는 환경변수가 어떤 것들이 비어져있고, 담당자는 누구인지를 체킹하지 않아도 되는 번거로움을 없앨 수 있다. 

## dotenv-vault로 환경 변수 컨트롤하기 

```
npx dotenv-vault push   # 최신 .env 업로드
npx dotenv-vault pull   # 팀원이 최신 .env 받기
```

가장 단순하면서 환경변수 파일을 가장 쉽게 관리할 수 있는 오픈소스 솔루션이다. 기존의 `.env` 워크 플로우를 유지하면서 암호화된 `.env.vault`파일만을 `git` 에 올리는 방식이다. 변경사항은 팀원이 `pull` 을 하면 항상 반영되며 도입 시에 가장 진입 장벽이 낮다.

**가장 빠르게 적용 가능하면서, 팀원들이 혼동하지 않도록 하는 방식이 제일 효율적**이었다. doppler와 같은 다른 솔루션의 경우에는 권한에 따른 환경변수 부여도 가능하지만, 내가 진행하는 사이드 프로젝트에서는 개발자 모두가 동등한 권한을 가지고 개발을 진행하는 것이기에 `dotenv-valut` 로 불편한 점들을 먼저 해결하고, 추가적으로 필요할 때 고려해보고자 했다.

비교를 하고자했던 세 가지 솔루션 모두 결국에는 해결하고자 하는 문제점이 최종 끝에서는 동일하기 때문이다.

**해당 프로젝트는 무료였는데, 유료로 변경되었다.. **

## dotenv-vault 동작 원리

```
.env (비밀값 원본)          → git에 절대 올리면 안 됨
.env.vault (암호화된 파일)  → git에 올려도 안전
.env.me (인증 파일) → 인증 여부 확인 파일
```

`dotenv-vault` 를 통해 로그인을 하게 되면 `.env.me` 를 통해 인증 여부 파일을 하나 받게 되는데, 저 파일을 기반으로 `.env.vault` 를 복호화하는데 인증을 수행하고 내부적으로는 `DOTENV_KEY` 를 통해 복호화를 진행하게 된다.

복호화 자체는 서버에서 진행을 해준다. 로컬에서는 `DOTENV_KEY` 없이도 `.env` 를 받게되는데, 이 `DOTENV_KEY` 는 서버에 직접근을 하지 못해 복호화를 하지 못하는 상황(CI/CD와 같은) 에서 사용을 하게 된다.

## dotenv-vault 사용 방법

만약 아레와 같이 환경변수 파일이 있다고 가정을 해보자.

```
// .env

// CRA는 REACT_APP_ 접두사 필수
REACT_APP_API_URL=https://api.example.com
REACT_APP_API_KEY=your_key_here

// Vite는 VITE_ 접두사 필수
VITE_API_URL=https://api.example.com
```

아래와 같이 순차적으로 명령어를 실행하게 되면, 초기 사용자는 push 명령어와 함께 `.env.vault` 파일을 받게 되고 새로운 사용자는 로그인 후, pull 명령어와 함꼐 `.env.vault` 파일을 받게 된다.

```
# 설치 (초기에 환경변수 프로젝트를 구성할 때)
npm install dotenv --save
npx dotenv-vault new

# 로그인 (이미 누군가 구성을 해놓았다면 로그인 진행)
npx dotenv-vault login

# .env 파일 push (신규 업로드 또는 환경변수 업데이트 시)
npx dotenv-vault push

# 다른 팀원이 pull (다운로드)
npx dotenv-vault pull

# 만약 `.env.vault` 파일이 없다면 아래 명령어를 실행해보자
npx dotenv-vault build  
```

![Image](https://upload.cafenono.com/image/slashpagePost/20260504/125342_VAO0GeTmKRFp5B3aNV?q=80&s=1280x180&t=outside&f=webp)

로컬환경에서는 로그인한 사용자의 `.env.me` 를 통해 `.env.vault` 파일을 기반으로 내부적으로 복호화 key 값을 통해 `.env` 파일을 서버에서 내려준다.

## 만약 빌드 환경에도 자동으로 적용하고 싶다면?

현재 서비스에서는 `.env` 를 소스코드에 포함시키고 있지 않아, `vercel` 에서 배포될 경우에는 환경변수를 명시적으로 입력하여 서비스를 프로덕션 환경으로 배포하고 있다. 그런데 만약 `.env.vault` 를 읽어 자동으로 환경변수를 매핑하고 싶다면 어떻게 해야할까?

```
# 현재 환경변수의 복호화 키를 조회할 수 있다.
npx dotenv-vault keys

# 환경 별로 키가 달라, 환경 별로도 확인 가능하다.
npx dotenv-vault keys development
npx dotenv-vault keys production

/**
* 환경 별로 키가 출력이 된다.
* dotenv://:key_development_xxx…?environment=development
* dotenv://:key_production_xxx…?environment=production
*/
```

```
DOTENV_KEY = dotenv://:key_xxx…?environment=production
```

> `**.env**`** 은 암호화되어 해당 파일에 작성을 해주는 것이 아니라, 배포 플랫폼의 환경변수 설정 삽입하기**

- Vercel

Settings → Environment Variables

DOTENV_KEY = dotenv://:key_xxx…?environment=production

- Netfilfy

Site Settings → Environment Variables

DOTENV_KEY = dotenv://:key_xxx…?environment=production

- Git Actions

```
# .github/workflows/deploy.yml
env:
  DOTENV_KEY: ${{ secrets.DOTENV_KEY }}
```

### 빌드 시에, 환경변수를 읽는 흐름은 이렇게 진행된다.

매번 `vercel` 에 환경변수를 명시적으로 주입하는 방법보다, 
이렇게 하나의 복호화 키로 모든 플로우를 `dotenv-vault` 로 묶을 수도 있다.

```
배포 플랫폼 환경 변수에 DOTENV_KEY 등록
    ↓ 빌드 시
.env.vault (Git에 커밋된 파일) 복호화
    ↓
환경 변수 주입 완료
```

프로젝트를 만들고, 최종적으로 환경변수가 업로드되면 UI 환경으로도 쉽게 파악이 가능하다.

물론 `npx dotenv-vault pull` 을 하게 되면 `.env` 를 로컬 환경에서도 확인할 수 있다.

![Image](https://upload.cafenono.com/image/slashpagePost/20260504/130832_cB9g6jewNeuNcC4gpu?q=80&s=1280x180&t=outside&f=webp)

정말 편리하고 좋은 서비스이지만, 반면 걱정해야하는 부분도 있다.

환경변수 파일을 클라우드 환경으로 믿고 업로드를 하는 행위가, 과연 보안상 안전하다는 것이냐에 대한 물음이다.

사이드 프로젝트이면서, 사용하고 있는 환경변수들의 플랫폼이 플랜제를 마음대로 바꿀 수 있는 종량제의 플랜이 아니기 때문에 비교적 민감한 데이터들이 아니어서 `dotenv-vault` 를 사용해도 된다고 판단을 했었다.

하지만 `dotenv-vault` 서버가 해킹당하거나, 서비스가 종료하게 되면 의존성으로 인한 문제 · `dotenv-vault`  계정이 털리게 되면 `.env` 내용에 접근이 가능한 부분 등이 보안상의 문제점이라 생각이 들었는데.. 마침 이에 따른 대안이 나와있길래 추가로 찾아보았

## 보안 문제로 등장한 dotenvx

클라우드 서버에 의존하고, 또 이로 인해 `.env` 파일이 유출될 가능성이 있기 때문에 (유료화 문제도 ^^,,) `dotenv-vault` 가 클라우드 환경으로 구성되었었다면 `dotenvx` 는 클라우드 없이 `Git` 환경으로만 구성이 되었다.

`dotenvx` 는 아래 세가지 문제들을 중점적으로 해결하게 된다.

- 플랫폼 불일치 문제 : 어떤 언어 · 프레임워크에도 종속받지 않고 동일하게 동작할 수 있다.

- 멀티 환경 관리 : `.env.production` , `.env.staging` 등의 명시적 파일 분리

- 파일 유출 : 암호화로 `Git` 에 올려도 안전하게 관리

또 AI 코딩 도구들의 발전으로 인해, `.env` 파일을 읽어서 LLM에 시크릿이 노출될 수 있는 위험이 생겼고, 암호화된 `.env` 파일은 에이전트가 읽어도 내용을 해석할 수 없어 프롬프트나 모델 컨택스트로 시크릿이 유출되는 것을 막을 수 있다.

### dotenvx의 암호화 흐름

dotenvx의 암호화 및 복호화 흐름은 아래와 같다.

```
.env (평문 작성)
  → dotenvx encrypt → .env (암호화됨) + .env.keys (비밀키)
  → .env는 Git 커밋 ✅, .env.keys는 커밋 ❌
  → 배포 플랫폼에 DOTENV_PRIVATE_KEY 등록
  → 빌드/런타임에 자동 복호화
```

### 설치 방법

먼저 `.env` 를 정의한다.

```
# .env (개발용)
VITE_API_URL=https://dev-api.example.com

# .env.production (프로덕션용)
VITE_API_URL=https://api.example.com
```

그리고 `.env` 를 암호화하게 위해  `dotenvx` 를 설치한다.

```
# 설치
npm install @dotenvx/dotenvx

# 개발용 .env 암호화
npx dotenvx encrypt

# 복호화는 아래 커맨드로
npx dotenvx decrypt

# 프로덕션용 암호화
npx dotenvx encrypt -f .env.production
```

암호화 후에는 아래와 같이 `.env` 파일 내부 내용이 변환된다.

```
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
DOTENV_PUBLIC_KEY="037cfbfc90234..."

# .env
VITE_API_URL="encrypted:BAZb6wDPFaFeFzq8..."
```

그리고 새로운 파일로  `.env.key`  파일이 생기게 된다. `.env.key` 파일에는 정말 중요한 비밀 복호화 키가 생성되기 떄문에 해당 키 파일은 외부로 절대 유출되어서는 안된다. ( `.gitignore` 파일을 통해 `Git` 에 올라가지 않도록 하자)

`.env` 가 암호화되었다면, 암호화된 환경변수 그대로 프로젝트를 실행하게 되면 오류가 발생한다.

프론트엔드 프로젝트에서 실행 전  `.env` 를 복호화해주면서 실행해주는 스크립트를 추가해줘야한다.

```
{
  "scripts": {
    "dev": "dotenvx run -- vite",
    "build": "dotenvx run -- vite build"
  }
}
```

그러면 내부적으로 `.env.keys` 파일을 통해 복호화된 환경변수를 가지고 프로젝트를 실행한다.

## 만약 빌드 환경에도 자동으로 적용하고 싶다면?

`dotenvx` 도 마찬가지로 똑같이 `.env.keys` 의 비밀 복호화 키를 배포 플랫폼의 환경변수에 아래와 같이 넣어주면 된다.

```
Vercel 환경변수 설정:
DOTENV_PRIVATE_KEY = "bd7c50b352..."
```

그리고 빌드 스크립트에서는 아래와 같이 명시를 해준다.

```
# package.json scripts에 직접 명시
"build": "dotenvx run -- vite build"
```

현업에서는 Zookeeper 을 통해 환경변수를 동적으로 제어하고 있는데, 사이드 프로젝트에서는 매번 `.env`  문서를 어떻게 공유해야할까 걱정이 들었다. 역시 개발자들은 문제가 있으면 어떻게 해결할 수 있을까에 대한 해답을 다양한 방법으로 많이 만들어내는 것 같다. 

당장은 `dotenv` 를 적용하여 해결하였고, 조만간 `dotenvx` 를 적용해 `.env` 파일을 저장소에 암호화된 상태로 올려 배포할 생각이다. 더 좋은 솔루션이나, 문제 상황이 맞는 솔루션이 나오게 되면 그걸 한번 적용해봐야겠다.

For the site tree, see the [root Markdown](https://slashpage.com/timmy.md).
