Bach 운영 컨테이너 보안을 강화한다

백엔드는 내부 네트워크에만 두고 Docker 비밀 파일의 API 키를 프록시에서 주입한다. 프론트엔드는 루프백 포트 18102만 사용한다.
This commit is contained in:
이창현
2026-10-03 07:32:36 +09:00
parent 7679397074
commit ba887cc6f9
6 changed files with 55 additions and 7 deletions
+18 -2
View File
@@ -45,9 +45,25 @@ _API_KEY_HEADER = APIKeyHeader(name="X-API-Key", auto_error=False)
_auth_warned = False
def _get_backend_api_key() -> str | None:
"""환경 변수 또는 Docker 비밀 파일에서 백엔드 인증 키를 읽는다."""
direct = os.environ.get("BACKEND_API_KEY")
if direct is not None:
return direct
secret_file = os.environ.get("BACKEND_API_KEY_FILE")
if not secret_file:
return None
try:
with open(secret_file, encoding="utf-8") as handle:
return handle.read().strip()
except OSError:
logging.exception("백엔드 인증 키 파일을 읽지 못했습니다")
return ""
def _require_api_key(key: str | None = Security(_API_KEY_HEADER)) -> None:
global _auth_warned
expected = os.environ.get("BACKEND_API_KEY")
expected = _get_backend_api_key()
# T1-1: only treat *absent* key (None) as "auth disabled".
# An empty string means a deployment misconfiguration, not "no auth".
if expected is None:
@@ -72,7 +88,7 @@ def _startup_checks() -> None:
"""Log warnings for optional external binaries that are absent at launch."""
# M1: fail fast if auth is explicitly required but no key is configured
if os.environ.get("REQUIRE_AUTH", "").strip().lower() in ("1", "true", "yes"):
if not os.environ.get("BACKEND_API_KEY"):
if not _get_backend_api_key():
raise SystemExit(
"FATAL: REQUIRE_AUTH is set but BACKEND_API_KEY is empty. "
"Set BACKEND_API_KEY or unset REQUIRE_AUTH."