[운영#2] 보안·비밀관리(.env/키 회전/권한/로그 민감정보 마스킹)

한줄 요약:
API 키·비밀번호는 코드에 남기지 말고 .env/비밀저장소, 키 회전, 최소권한, 로그 마스킹으로 지킨다.
👉 “유출돼도 피해 최소화, 유출되기 전에 탐지”가 목표!


1. 목표 : 보안·비밀관리

  • .env/환경변수/비밀저장소(Secret Manager)로 키 안전 보관
  • 키 회전(교체) 절차 자동화
  • 최소 권한(Least Privilege) 원칙 적용
  • 로그 민감정보 마스킹 & 데이터 암호화

1) 코드에 비밀번호 금지 — .env + gitignore

✅ 기본 세팅

project/
 ├─ .env                 # 키/토큰만 저장 (배포용은 별도 관리)
 ├─ .env.sample          # 키 이름만 예시, 값은 비워둠
 ├─ .gitignore           # .env 업로드 금지
 └─ app.py

.gitignore

.env
*.pem
*.key

.env.sample (공유용)

OPENAI_API_KEY=
WP_URL=
WP_USER=
WP_APP_PASS=
SLACK_WEBHOOK=

파이썬 로드

# app.py
import os
from dotenv import load_dotenv

load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
    raise RuntimeError("OPENAI_API_KEY missing")

팀에선 실제 값 없는 .env.sample만 Git에 올려서 구성 힌트만 제공.


2) 배포 환경별 분리 (.env.prod / .env.dev)

  • 로컬: .env.dev
  • 서버/배포: .env.prod (서버 환경변수로 주입, 파일 미배포)
# env_loader.py
import os
from dotenv import load_dotenv

PROFILE = os.getenv("PROFILE", "dev")  # dev / prod
load_dotenv(f".env.{PROFILE}", override=True)

서버에선:

PROFILE=prod python orchestrator.py

3) 키 회전(Rotation) — “교체가 쉬워야 안전하다”

절차(간단)

  1. 새 키 발급.env*_NEW로 추가
  2. 코드에서 우선순위: *_NEW 있으면 새 키 사용
  3. 배포/검증 후, 기존 키 폐기(비활성화)
  4. .env 정리
# secrets.py
import os
def get_key():
    new = os.getenv("OPENAI_API_KEY_NEW")
    cur = os.getenv("OPENAI_API_KEY")
    return new or cur

예약 회전: 월 1회 크론으로 새 키 생성→배포→구키 폐기 자동 스크립트화 권장.


4) 최소 권한(Least Privilege) 적용 팁

대상권한 축소 예시
워드프레스 앱 비번**필요 범위(글 생성/미디어 업로드)**만 허용, 관리 기능 금지
클라우드 키(스토리지/DB)읽기 전용/특정 버킷·테이블 한정
슬랙 웹훅채널 1개 한정, 회수·재발급 쉬운 구조
서버 사용자서비스 계정 분리, 루트 사용 금지

키는 실수로 유출될 수 있다는 가정으로 설계. 유출돼도 피해가 제한되도록 권한 최소화.


5) 로그 민감정보 마스킹 (PII/Secrets)

민감정보가 로그에 절대 남지 않도록 필터를 건다.

# logging_mask.py
import logging, re

SENSITIVE = [
    (re.compile(r"(sk-[A-Za-z0-9]{20,})"), "sk-****"),    # 예: API Key 패턴
    (re.compile(r"(\b\d{3}-\d{2}-\d{5}\b)"), "***-**-*****"), # 주민/사번 예시 패턴
    (re.compile(r"(\b\d{16}\b)"), "****-****-****-****"),     # 카드번호 등
]

class MaskFilter(logging.Filter):
    def filter(self, record):
        msg = str(record.getMessage())
        for p, repl in SENSITIVE:
            msg = p.sub(repl, msg)
        record.msg = msg
        return True

logger = logging.getLogger("secure")
handler = logging.StreamHandler()
handler.addFilter(MaskFilter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# 사용 예
logger.info("키 확인: sk-1234567890ABCDEFGHIJK, 카드 1234123412341234")
# 출력: 키 확인: sk-****, 카드 ****-****-****-****

규칙은 점진적 강화: 유출 우려가 보이면 즉시 패턴 추가.


6) 데이터 암호화(저장/전송)

  • 전송 중: HTTPS(기본), SFTP/SSH
  • 저장 시: 토큰/쿠키/식별자 등은 암호화 저장(복호화는 사용할 때만)
# encrypt.py - 대칭키 예시(Fernet)
from cryptography.fernet import Fernet

# 1회 생성 후 키는 안전 보관(환경변수/비밀저장소)
# key = Fernet.generate_key(); print(key)

from dotenv import load_dotenv; import os
load_dotenv()
FERNET_KEY = os.getenv("FERNET_KEY").encode()
f = Fernet(FERNET_KEY)

enc = f.encrypt("secret-data".encode())
dec = f.decrypt(enc).decode()

키는 .env에 보관하되 서버 환경변수 주입을 우선.
백업 시 키·데이터 분리 저장(동일 경로 보관 금지).


7) 비밀저장소(Secret Manager) 도입 고려

규모가 커지면 OS 환경변수만으로 부족하다.

  • AWS Secrets Manager / Parameter Store
  • GCP Secret Manager
  • Azure Key Vault
  • HashiCorp Vault

장점: IAM 연동, 액세스 로깅, 자동 회전, 버전 관리.
패턴: 애플리케이션 시작 시 비밀저장소에서 키 fetch → 메모리에만 보관.


8) CI/CD에서 비밀 다루기

  • GitHub Actions/파이프라인 Secrets 기능 사용
  • 배포 시 .env 파일 대신 런타임 환경변수로 주입
  • 로그에 set -x 비활성화, echo $SECRET 금지
  • 실패 워크플로 로그 자동 삭제/보관기간 단축

9) 사고(유출) 대응 플랜

  1. 즉시 폐기: 노출된 키 비활성화(회수)
  2. 로테이션: 새 키 발급 → 서비스 재배포
  3. 감사: 최근 로그/접속기록 확인
  4. 차단: WAF/IP 차단·레이트 리밋 강화
  5. 재발 방지: 마스킹 패턴/권한/리뷰 프로세스 보강

연습 중요: 월 1회 모의 회전/폐기 훈련으로 리스크 최소화.


2. 체크리스트

  • 코드/리포에 비밀번호 하드코딩 0건
  • .env는 Git에서 무시, .env.sample만 배포
  • 환경별 분리(.env.dev / .env.prod)
  • 키 회전 자동화(NEW 우선, 구키 폐기)
  • 최소 권한으로 API/계정 제한
  • 로그 마스킹 필터 적용 및 규칙 점검
  • 암호화/HTTPS 강제
  • 비밀저장소/CI Secrets 사용 검토
  • 유출 대응 시나리오 문서화 & 훈련

3. 요약 한 줄

“키는 언젠가 새는 것”을 전제로 보관/회전/권한/로그를 설계하면, 유출돼도 피해가 작고 복구가 빠르다. ✅


이전 강좌 👈 [운영#1] 모니터링·알림·코스트 관리
다음 강좌 👉 [운영#3] 장애 복구 자동화(리트라이·백오프·대체 경로·휴면 후 재시도)

댓글 남기기

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.