0Pricing
Security+ Academy · 강의

보안 비밀 관리 및 환경 변수

비밀 관리자(Vault, AWS Secrets Manager)와 실행 시 환경 변수 주입을 사용해 소스 코드에 비밀 값을 하드코딩하지 않습니다.

보안 비밀 관리 및 환경 변수은(는) CoddyKit의 무료 Security+ Academy 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Security+ Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Security+ Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

하드코딩된 Secret 문제

하드코딩된 Secret(소스 코드에 직접 삽입된 API 키, 데이터베이스 암호, TLS 개인 키 및 OAuth 토큰)은 가장 흔하고 예방 가능한 보안 취약점 중 하나입니다. 소스 코드의 Secret은 버전 관리 history에 노출되고(삭제한 후에도 남음), 저장소에 접근할 수 있는 모든 개발자에게 표시되며, 저장소가 실수로 공개될 때 자주 유출됩니다. GitGuardian 및 truffleHog와 같은 도구는 GitHub와 같은 플랫폼에서 유출된 Secret을 지속적으로 검색합니다.

# DANGEROUS: hardcoded secret in source code
# db_password = 'P@ssw0rd#2026'
# api_key = 'sk-live-abc123xyz789'
# aws_secret = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'

# These secrets are now:
# - In git history (even if later deleted)
# - Visible to all repo contributors
# - Potentially in CI/CD logs
# - Often leaked when repos go public accidentally

환경 변수: 더 낫지만 충분하지 않음

환경 변수는 호스트 OS 또는 컨테이너 오케스트레이터를 통해 런타임에 Secret을 주입하여 소스 코드에서 제거합니다. 애플리케이션은 하드코딩된 값 대신 os.environ['DB_PASSWORD']를 읽습니다. 하드코딩보다는 낫지만 환경 변수에도 약점이 있습니다. 프로세스 목록에 표시되고, 자식 프로세스에 상속되며, 장애 덤프와 디버그 로그에 남는 경우가 많고, 수동 Rotation이 필요합니다. 개발에는 적합하지만 프로덕션 Secret 관리에 단독으로 사용하기에는 충분하지 않습니다.

# Environment variable pattern:
# In .env file (NEVER commit to git):
# DB_PASSWORD=P@ssw0rd#2026
# API_KEY=sk-live-abc123xyz789

# In .gitignore:
# .env
# *.env
# .env.*

# In application code:
# db_password = os.environ.get('DB_PASSWORD')
# api_key = os.environ.get('API_KEY')

# Risk: env vars visible in 'ps aux' output,
# inherited by child processes, appear in /proc/<pid>/environ

전용 Secret Manager

Secret Manager는 Secret을 저장하고, Rotation하고, 접근을 감사하기 위해 특수 목적에 맞게 구축된 시스템입니다. 대표적인 솔루션으로는 HashiCorp Vault(오픈 소스 및 엔터프라이즈), AWS Secrets Manager, Azure Key Vault, Google Cloud Secret Manager가 있습니다. 애플리케이션은 런타임에 Secret Manager로 인증하고 Secret을 가져와 사용하므로, Secret이 디스크나 환경 변수에 저장되는 일이 없습니다. 모든 접근이 기록되므로 누가 어떤 Secret에 언제 접근했는지 감사할 수 있습니다.

# HashiCorp Vault secret retrieval (conceptual):
# Application authenticates to Vault using:
#   - AWS IAM role (in cloud environments)
#   - Kubernetes service account token
#   - AppRole credentials

# After authentication, retrieve secret:
# vault kv get -field=password secret/prod/database

# In application (Python SDK):
# client = hvac.Client(url='https://vault.company.com')
# client.auth.aws.iam_login(role='prod-app')
# secret = client.secrets.kv.read_secret('prod/database')
# db_password = secret['data']['password']

자동 Secret Rotation

환경 변수보다 Secret Manager가 제공하는 주요 이점은 자동 Rotation입니다. AWS Secrets Manager는 애플리케이션을 재배포하지 않고도 일정에 따라(예: 30일마다) RDS 데이터베이스 암호를 자동으로 Rotation할 수 있습니다. Secret Manager는 데이터베이스의 암호와 저장된 Secret을 동시에 업데이트합니다. 연결할 때마다 Secret을 가져오는 애플리케이션은 새 자격 증명을 자동으로 받습니다. 이를 통해 Rotation되지 않는 '영구적인' 서비스 계정 암호를 사용하는 흔한 관행을 없앨 수 있습니다.

# AWS Secrets Manager rotation configuration:
# Secret:         prod/app-database-credentials
# Rotation:       enabled
# Frequency:      every 30 days
# Lambda function: SecretsManager-MyRDSRotation

# Rotation process:
# 1. Lambda creates new DB password
# 2. Updates secret in Secrets Manager
# 3. Updates password on RDS instance
# 4. Tests new credentials work
# 5. Deprecates old credentials
# Application: always calls GetSecretValue at runtime -> gets fresh value

The .gitignore 방어

커밋된 비밀 정보에 대한 첫 번째 방어선은 비밀 정보가 포함될 수 있는 모든 파일을 제외하도록 제대로 관리되는 .gitignore 파일입니다. 그러나 .gitignore는 향후 커밋만 방지할 뿐이며, 이미 커밋된 비밀 정보는 git 기록에 남아 있습니다. 비밀 정보가 실수로 커밋되었다면 즉시 손상된 것으로 간주해야 합니다. 먼저 비밀 정보를 교체한 다음, 필요에 따라 git filter-repo와 같은 도구를 사용해 기록을 다시 작성할 수 있습니다(규정 준수를 위해 필요하지만, 비밀 정보가 이미 추출되었을 수 있으므로 이것만으로는 충분하지 않습니다).

# Recommended .gitignore entries for secret files:
# .env
# .env.*
# *.pem
# *.key
# *.p12
# *.pfx
# credentials.json
# service_account*.json
# secrets.yaml
# config/secrets.yml
# terraform.tfvars  (may contain cloud credentials)
# .aws/credentials

# Pre-commit hook to scan for secrets before commit:
# pre-commit install
# hook: detect-secrets / gitleaks / truffleHog

코드형 인프라의 Secrets

코드형 인프라(IaC) 파일(Terraform, CloudFormation, Kubernetes 매니페스트)에는 데이터베이스 연결 문자열, 환경 변수 선언에 포함된 API 키, TLS 인증서와 같은 비밀 정보가 자주 포함됩니다. 이러한 파일은 버전 관리 시스템에 커밋되는 경우가 많아 비밀 정보 노출 위험이 발생합니다. 해결 방법으로는 Vault 동적 비밀 정보(Vault가 각 Terraform 실행에 사용할 단기 자격 증명을 생성), Kubernetes Secrets(etcd에 저장되며 저장 중 암호화해야 함), 그리고 런타임에 Secrets 관리자에서 Kubernetes로 동기화하는 external-secrets-operator가 있습니다.

Secrets에 대한 최소 권한 원칙

각 애플리케이션 또는 서비스는 명시적으로 필요한 비밀 정보에만 접근해야 합니다. 이를 비밀 정보에 적용하는 최소 권한 원칙이라고 합니다. 웹 애플리케이션에는 데이터베이스 비밀번호가 필요하지만 CA 개인 키는 필요하지 않습니다. 보고 작업에는 읽기 전용 데이터베이스 자격 증명이 필요하며 쓰기 권한은 필요하지 않습니다. Secrets 관리자는 어떤 ID(IAM 역할, 서비스 계정, AppRoles)가 어떤 비밀 정보를 읽을 수 있는지 지정하는 접근 정책을 통해 이를 강제하고, 감사를 위해 모든 접근을 기록합니다.

# Vault policy: web application can read DB password only
# policy name: web-app-policy
# path 'secret/prod/database' {
#   capabilities = ['read']
# }
# path 'secret/prod/tls-certs/*' {
#   capabilities = []  # DENY - app does not need TLS keys
# }

# This policy is assigned to the web app's AppRole.
# The reporting service gets a separate policy with
# only 'secret/prod/reporting-db-readonly' access.

동적 Secrets

동적 Secrets는 특정 요청자를 위해 요청 시 생성되며 자동으로 만료됩니다. Vault는 1시간 동안 유효하고 요청한 특정 서비스와 연결된 임시 데이터베이스 자격 증명을 생성할 수 있습니다. 만료되면 데이터베이스가 해당 자격 증명을 자동으로 폐기합니다. 따라서 탈취할 수 있는 장기 정적 자격 증명이 존재하지 않습니다. 공격자가 동적 자격 증명을 가로채더라도 빠르게 만료되며 감사 로그에서 요청 ID와 연결됩니다.

# Vault dynamic secrets: temporary DB credentials
# Application calls Vault to get a DB credential:
# vault read database/creds/web-app-role
#
# Vault response:
# username: v-web-app-x7k2m-1234567890  (unique, temporary)
# password: A1b2C3d4E5f6G7h8            (randomly generated)
# lease_duration: 1h                     (auto-expires)
#
# After 1 hour, Vault instructs DB to revoke this user.
# No static password ever exists for the attacker to steal.

CI/CD 파이프라인의 Secrets

CI/CD 파이프라인에는 배포를 위한 클라우드 공급자 자격 증명, Docker 레지스트리 토큰, 서명 키와 같은 비밀 정보가 자주 필요합니다. 파이프라인 스크립트나 구성 파일에 비밀 정보를 저장하지 마십시오. 대신 파이프라인 플랫폼에 내장된 Secrets 저장소(GitHub Actions Secrets, GitLab CI Variables, Jenkins Credentials Store)를 사용하거나, 머신 ID를 사용해 런타임에 중앙 저장소에서 비밀 정보를 가져오십시오. 빌드 출력에 비밀 정보가 실수로 노출되지 않도록 로그에서 비밀 변수는 마스킹된 것으로 표시하십시오.

# GitHub Actions: using secrets in pipeline
# secrets.yml in GitHub Settings -> Secrets (encrypted storage)
# Secret: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

# In .github/workflows/deploy.yml:
# env:
#   AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
#   AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

# Best practice: use OIDC federation instead
# GitHub -> AWS trust relationship via OIDC token
# -> No static AWS keys needed at all

Secrets 접근 감사

Secrets 관리자는 모든 비밀 정보 접근 이벤트에 대한 종합 감사 로그를 제공합니다. 어떤 ID가 어떤 비밀 정보에 접근했는지, 어느 IP에서 접근했는지, 언제 접근했는지, 접근이 성공했는지 거부되었는지를 기록합니다. 이러한 로그는 규정 준수(SOC 2, PCI-DSS)와 사고 대응에 매우 중요합니다. 자격 증명이 손상된 것으로 의심될 때 감사 로그를 확인하면 해당 자격 증명에 접근한 시스템과 시점을 파악할 수 있으므로, 영향을 받았을 가능성이 있는 시스템을 신속하게 식별하고 격리 여부를 결정할 수 있습니다.

비밀 정보 방지를 위한 사전 커밋 훅

사전 커밋 훅은 각 git 커밋이 최종 확정되기 전에 자동으로 실행되는 스크립트로, 비밀 정보가 버전 관리 기록에 들어가기 전에 탐지할 수 있게 합니다. detect-secrets(Yelp), GitLeaks, git-secrets(AWS)와 같은 도구는 사전 커밋 훅으로 통합되어 스테이징된 파일에서 API 키, 연결 문자열, 개인 키, JWT 토큰과 일치하는 패턴을 검사합니다. 비밀 정보가 탐지되면 커밋이 거부되고 개발자에게 자격 증명을 제거하라는 메시지가 표시됩니다. pre-commit 프레임워크를 사용하면 팀 전체에서 훅 구성을 쉽게 추가하고 공유할 수 있습니다.

# Installing detect-secrets as pre-commit hook:
# 1. Install: pip install detect-secrets
# 2. Create baseline: detect-secrets scan > .secrets.baseline
# 3. Add to .pre-commit-config.yaml:
#    repos:
#      - repo: https://github.com/Yelp/detect-secrets
#        rev: v1.4.0
#        hooks:
#          - id: detect-secrets
#            args: ['--baseline', '.secrets.baseline']
# 4. Install hooks: pre-commit install

# Now every commit attempt is scanned:
# git commit -m 'add config'
# -> detect-secrets runs
# -> if AWS key pattern found: COMMIT BLOCKED
# -> developer must remove secret and use secrets manager

빠른 확인

이 lesson에서 다룬 CompTIA Security+ (SY0-701) 개념에 대한 이해도를 확인해 보십시오.

lesson 복습

이 lesson에서는 다음을 배웠습니다. 소스 코드에 하드코딩된 비밀 정보는 제거하고 Vault 또는 AWS Secrets Manager와 같은 Secrets 관리자로 대체해야 하며, 자동 교체를 사용하면 공격자가 최초 침해 이후에도 악용할 수 있는 장기 자격 증명이 제거되고, 동적 Secrets와 최소 권한 접근 정책은 노출된 개별 비밀 정보의 가치를 최소화합니다. 다음으로 의존성 보안과 소프트웨어 구성 분석을 살펴보겠습니다.

자주 묻는 질문

“보안 비밀 관리 및 환경 변수” 강의는 무료인가요?

네 — “보안 비밀 관리 및 환경 변수” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Security+ Academy 강의 전체를 잠금 해제할 수 있습니다. Security+ Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“보안 비밀 관리 및 환경 변수”에서 뭘 배우나요?

비밀 관리자(Vault, AWS Secrets Manager)와 실행 시 환경 변수 주입을 사용해 소스 코드에 비밀 값을 하드코딩하지 않습니다. 브라우저에서 직접 실행하는 실습 코드로 Security+ Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Security+ Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Security+ Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“보안 비밀 관리 및 환경 변수” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Security+ Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Security+ Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 입력 검증 및 출력 인코딩
  2. 보안 비밀 관리 및 환경 변수
  3. 종속성 보안 및 소프트웨어 구성 분석
  4. DevSecOps: 파이프라인에 보안을 앞단에서 통합하기
← Security+ Academy(으)로 돌아가기