Server#BE#Spring Boot#AI

OpenAPI/Swagger 보안 스키마, 전역 설정 vs 개별 어노테이션

JWT 인증 API를 Swagger로 문서화할 때 보안 스키마를 전역으로 걸지 개별로 걸지, 그리고 AI 코드 리뷰 제안을 검증 없이 반영하면 안 되는 이유

2026년 7월 14일2분 읽기조회 4
공유

들어가며

JWT 기반 인증을 쓰는 API를 Swagger(OpenAPI)로 문서화할 때, "이 API는 토큰이 필요하다"는 사실을 어떻게 표현해야 할까요? 엔드포인트마다 일일이 붙이는 방법도 있고, 전체에 한 번에 적용하는 방법도 있습니다. PLIMAP 백엔드 작업 중 AI 코드 리뷰 봇(CodeRabbit)이 "개별로 어노테이션을 추가하라"고 제안했는데, 실제로는 이미 전역 설정이 되어 있어서 불필요한 제안이었던 사례를 계기로 이 개념을 정리했습니다.

OpenAPI Security Scheme이란

OpenAPI 명세에서 "보안 스키마(Security Scheme)"는 API가 사용하는 인증 방식(API Key, HTTP Basic, Bearer Token, OAuth2 등)을 정의하는 명세 단위입니다. 정의만으로는 아무 효과가 없고, 어떤 엔드포인트에 그 스키마를 적용할지는 별도의 개념인 Security Requirement가 담당합니다.

SecurityScheme scheme = new SecurityScheme()
        .name("JWT TOKEN")
        .type(SecurityScheme.Type.HTTP)
        .scheme("bearer")
        .bearerFormat("JWT");

전역(Global) vs 개별(Per-Operation) 적용

Security Requirement는 두 곳에 선언할 수 있습니다.

  1. 문서 최상위(OpenAPI 객체) — 명시적으로 제외하지 않는 이상 모든 엔드포인트에 기본 적용됩니다.
  2. 각 operation 단위 — @SecurityRequirement로 추가 지정하거나, @SecurityRequirements(빈 배열)로 전역 설정을 오버라이드해서 제거할 수 있습니다.

즉 전역 설정이 있는 프로젝트라면 대부분의 인증 필요 API는 아무것도 안 붙여도 되고, 오히려 "로그인 없이도 되는" 소수의 공개 API만 예외로 밝혀주면 됩니다.

springdoc-openapi 구현 예시

전역 설정

@Configuration
public class SwaggerConfig {

    @Bean
    public OpenAPI swagger() {
        String securityScheme = "JWT TOKEN";
        SecurityRequirement securityRequirement =
                new SecurityRequirement().addList(securityScheme);
        Components components = new Components()
                .addSecuritySchemes(securityScheme, new SecurityScheme()
                        .name(securityScheme)
                        .type(SecurityScheme.Type.HTTP)
                        .scheme("bearer")
                        .bearerFormat("JWT"));

        return new OpenAPI()
                .addSecurityItem(securityRequirement) // 핵심: 이 한 줄이 전체 API에 적용됨
                .components(components);
    }
}

개별 오버라이드 (공개 API만 예외 처리)

@Operation(summary = "[임시] Swagger 테스트용 토큰 발급")
@SecurityRequirements // 빈 배열 → 전역 인증 요건을 이 엔드포인트에만 제거
@PostMapping("/token/test")
public ApiResponse<MemberResDTO.Login> issueTestToken(...) { ... }

실전 사례: 로그아웃 API 리뷰

PLIMAP 백엔드는 SwaggerConfig에서 이미 전역 보안 요건을 걸어둔 상태였습니다. 그런데 새로 추가한 로그아웃 API(DELETE /api/v1/auth/logout)에 CodeRabbit이 "@SecurityRequirement(name = "JWT TOKEN")을 개별로 추가하라"고 제안했습니다. 하지만:

  • 같은 파일의 다른 엔드포인트(온보딩, 약관 조회/동의)도 이 어노테이션이 없었고
  • 실제로 Swagger UI에서 Authorize 버튼으로 토큰을 넣고 호출해보면 이미 정상적으로 인증되어 200이 돌아왔습니다.

즉 이 제안은 실제 문제를 고치는 게 아니라, 이미 동작하는 것을 중복으로 적어주는 제안이었습니다. 반영하지 않기로 했습니다.

AI 코드 리뷰 도구를 다룰 때 주의할 점

CodeRabbit을 포함한 대부분의 AI 코드 리뷰 도구는 diff에 포함된 파일 위주로 문제를 판단하는 경향이 있습니다. 전역 설정이 다른 파일에 있으면, 리뷰 도구 입장에서는 "이 파일만 보면 빠진 것처럼" 보일 수밖에 없습니다. 그래서 AI 리뷰 제안을 그대로 반영하기 전에, 항상 관련된 설정 파일(SwaggerConfig, SecurityConfig 등)을 함께 확인하고, 가능하면 직접 실행/테스트해서 실제로 문제가 재현되는지 검증하는 습관이 중요하다고 느꼈습니다.

정리

  • 전역 보안 설정은 "기본값을 안전하게(인증 필요) 잡고, 예외만 명시적으로 푸는" 방식이 관리하기 편합니다.
  • 개별 오버라이드는 "이 API는 다르다"라고 말해야 할 때만 사용합니다.
  • AI 리뷰 제안은 참고는 되지만, 맥락(다른 설정 파일, 실제 동작)을 모르는 상태에서 나온 제안일 수 있으므로 검증 후 반영 여부를 결정해야 합니다.

관련 포스트

댓글

방명록을 남겨주세요