2 분 소요

Introspection 대신 GitHub SDL로 보안 강화

기존 방식의 문제점

GraphQL Introspection 기반 스키마 조회

기존에는 GraphQL API 엔드포인트에서 Introspection을 통해 직접 스키마를 가져오는 방식을 사용했습니다.

// codegen.ts (기존)
import type { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
  schema: "https://api.example.com/graphql",
  documents: "src/**/*.gql",
  generates: {
    // TypeScript 타입, React Hooks, 로컬 스키마 생성
  },
};

이 방식은 설정이 단순하고 편리하지만 프로덕션 환경에서는 다음과 같은 문제가 있습니다.


보안 측면의 한계

GraphQL Introspection은 __schema 쿼리를 통해 API의 전체 스키마 구조를 조회할 수 있는 기능입니다.

개발 단계에서는 유용하지만 프로덕션 환경에서는 다음과 같은 문제가 존재합니다.

  • API 전체 구조 노출
  • 내부용 쿼리 / 뮤테이션 노출 가능성
  • 공격 위험 증가

이 때문에 많은 팀에서 프로덕션 환경에서는 Introspection을 비활성화하거나 제한합니다.



GraphQL 스키마 보안을 강화하는 방법들

프로덕션 환경에서 GraphQL 스키마를 안전하게 관리하는 방식은 여러 가지가 있습니다.


1. 프로덕션에서 Introspection 비활성화

  • 가장 기본적인 보안 조치
  • API 구조 노출 방지 가능

다만 이 방식만 사용할 경우 프론트엔드에서 Codegen을 실행하려면 여전히 API 서버 접근이 필요합니다.


2. 인증된 사용자에게만 Introspection 허용

  • 특정 권한(API Key, JWT 등)을 가진 요청만 허용
  • 외부 접근은 차단

하지만 이 경우에도 인증 토큰 관리가 필요하고 API 서버 상태에 Codegen이 의존하게 됩니다.


3. 로컬 SDL(schema.graphql) 파일 사용

  • Introspection 없이 로컬 SDL 파일을 스키마 소스로 사용
  • API 서버 접근 완전 제거 가능

다만 팀원끼리 스키마를 계속 동기화해야 하고, 누가 언제 뭘 바꿨는지 추적하기가 번거롭습니다.


4. GitHub 기반 SDL 관리 (선택한 방식)

이 글에서는 위 방식들 중
👉 GitHub Repository에 버전 관리된 SDL 스키마를 단일 소스로 사용하는 방식을 선택했습니다.

이 방식을 선택하면 앞서 말한 문제들을 해결할 수 있습니다.

  • 프로덕션 API에서 Introspection을 완전히 끌 수 있음
  • Codegen이 API 서버에 의존하지 않아도 됨
  • 스키마 변경 이력을 Git으로 추적할 수 있음
  • 브랜치만 바꾸면 개발 중인 스키마도 바로 확인 가능



개선한 방식: GitHub 기반 스키마 관리

백엔드 레포에 있는 GraphQL SDL 스키마 파일을 Codegen에서 직접 가져오도록 변경했습니다.


GITHUB TOKEN 발급

Private Repository에 접근하려면 GitHub Personal Access Token(PAT)이 필요해서 환경 변수로 설정했습니다.

# .env
YOUR_GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx


codegen.ts 설정

GraphQL Code Generator는 HTTP(S)를 통해 원격 SDL 스키마를 직접 가져오는 방식을 공식적으로 지원합니다.

참고: Codegen - schema field

const config: CodegenConfig = {
  schema: {
    // GitHub에 버전 관리된 GraphQL-SDL 스키마
    // https://raw.githubusercontent.com/{org}/{repo}/{branch}/path/to/schema.gql
    [GITHUB_SCHEMA_URL]: {
      method: "GET",
      handleAsSDL: true,
      headers: {
        Authorization: `token ${process.env.YOUR_GITHUB_TOKEN}`,
      },
    },
  },
  documents: "src/**/*.gql",
  generates: {
    // TypeScript 타입, React Hooks, 로컬 스키마 생성
  },
};

export default config;


작동 흐름

1. npm run gqlgen 실행
        ↓
2. codegen.ts 실행
        ↓
3. GitHub Raw URL을 통해 SDL 스키마 다운로드
        ↓
4. .gql 쿼리 파일 분석
        ↓
5. 코드 생성
   - TypeScript 타입
   - Apollo Client Hooks
   - schema.graphql (에디터 지원용)

이 과정에서 API 서버는 전혀 호출되지 않고 스키마는 GitHub에 저장된 파일만을 기준으로 사용됩니다.



장점

보안 측면

  • 프로덕션 GraphQL API에서 Introspection 완전 제거
  • API 구조 외부 노출 방지
  • Codegen 실행을 위한 서버 접근 권한 최소화


개발 생산성

이 방식의 가장 큰 장점은 브랜치만 바꿔서 바로 작업 중인 스키마를 확인할 수 있다는 점입니다.

  • 백엔드 서버 실행 없이 스키마 파악 가능
  • 프론트엔드 개발을 백엔드 환경과 분리
  • 스키마 변경 흐름을 Git PR 기준으로 추적 가능
// ex) feat/admin-user 브랜치의 스키마를 바로 참조
const GITHUB_SCHEMA_URL =
  "https://raw.githubusercontent.com/org/repo/feat/admin-user/schema.gql";



결론

백엔드에서 ApolloServer Introspection을 껐을 때 프론트에서 GitHub에 있는 SDL 스키마를 직접 가져오는 방식으로 우회하는 방법을 소개했습니다.
이 방식으로 바꾸면서 보안을 강화하고 브랜치 별로 스키마에 접근할 수 있게 되어 개발이 더욱 편리해졌습니다.

카테고리:

업데이트:

댓글남기기