콘텐츠로 이동

인증·CORS

인증 소유권

Gateway는 Authorization: Bearer ... 값을 추출해 형태만 분류하고, /sohri WSS Authorization 헤더에 같은 값을 전달합니다. 최종 인증 주체는 socket-backend입니다.

  • API key: sr_로 시작하고 뒤에 값이 존재
  • client-secret: eyJ로 시작하고 점(.)으로 구분된 비어 있지 않은 3개 분절
  • 그 밖의 값: 명백한 잘못된 형태로 보고 401

형태 분류는 검증이 아닙니다. Gateway는 JWT 서명·만료, API key 유효성, workspace 소속과 권한을 판정하지 않습니다. credential을 로그에 남겨서도 안 됩니다.

sequenceDiagram
    autonumber
    participant C as 브라우저/클라이언트
    participant G as Gateway
    participant B as socket-backend /sohri
    participant P as Pion

    C->>G: POST SDP + Authorization: Bearer credential
    G->>G: 헤더와 credential 형태 확인
    alt 헤더 누락 또는 형태 오류
        G-->>C: 401
    else API key 또는 JWT 형태
        G->>B: WSS handshake + 같은 Bearer credential
        alt 백엔드 401/403
            B-->>G: 인증 거부
            G-->>C: 401
        else 백엔드 인증 성공
            B-->>G: 101 Switching Protocols
            G->>P: PeerConnection과 트랙 생성
            G-->>C: 201 answer SDP
        else 백엔드 접속 장애
            B-->>G: handshake/transport 오류
            G-->>C: 502
        end
    end

이 순서 덕분에 유효하지 않은 credential 요청은 ICE 소켓, encoder, 트랙 같은 상대적으로 비싼 미디어 자원을 소비하지 않습니다.

client secret 발급 경계

POST /v1/realtime/client_secrets는 Gateway에서 제거되었으며 라우트가 등록되지 않아 404입니다. CORS를 설정해도 이 경로가 되살아나지 않습니다.

브라우저가 장기 API key를 가져서는 안 됩니다. 표준 배포에서는 app-backend가 사용자 인증과 정책 검사를 수행한 뒤 짧은 수명의 client-secret JWT를 발급합니다. 브라우저는 그 JWT를 SDP POST에 사용하고 socket-backend가 검증합니다. 서버 간 연동은 workspace API key를 사용할 수 있습니다.

브라우저 CORS

브라우저의 SDP 요청은 application/sdp와 Authorization 헤더를 사용하므로 non-simple request이며 OPTIONS preflight가 먼저 발생합니다.

CORS_ALLOWED_ORIGINS가 하나 이상일 때만 CORS가 활성화됩니다.

  • Origin은 문자열 정확 일치이며 wildcard는 지원하지 않습니다.
  • 허용 preflight는 204, 거부는 CORS 헤더 없는 403입니다.
  • 허용 메서드는 POST, OPTIONS, 허용 헤더는 Authorization, Content-Type입니다.
  • Access-Control-Max-Age: 600, Vary: Origin을 설정합니다.
  • 쿠키를 사용하지 않아 Access-Control-Allow-Credentials는 설정하지 않습니다.
  • 실제 POST의 401, 502 등 오류 응답에도 허용 Origin이면 ACAO를 먼저 추가합니다.
OPTIONS /v1/realtime/calls HTTP/1.1
Origin: https://voice.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization, content-type

CORS 목록이 비어 있으면 OPTIONS 라우트도 등록되지 않아 405이고, POST 응답에 CORS 헤더가 없습니다. 서버 간 요청은 Origin 정책의 영향을 받지 않습니다.

운영 체크리스트

  1. API key와 JWT를 쿼리 문자열에 넣지 않습니다.
  2. app-backend의 JWT 발급과 socket-backend의 검증 키·issuer·만료 정책을 맞춥니다.
  3. 허용 Origin에 scheme, host, port를 정확히 적습니다.
  4. 브라우저 콘솔의 CORS 오류와 실제 Gateway의 401/502를 구분합니다.
  5. 인증 실패가 PeerConnection 생성 전에 종료되는지 메트릭으로 확인합니다.

상태 코드와 이벤트 계약은 엔드포인트·이벤트 참조, 관련 설정은 설정 참조를 참고하세요.