Cognito get_user_by_access_token failed: Aws::STS::Errors::Http408Error, #<Cupix::Auth::VerifiedAcce
RCA: Cognito get_user_by_access_token failed: Aws::STS::Errors::Http408Error
Overview#
What Happened#
2026-05-22 14:44:44 UTC에 cupixworks-api production (us-west-2)에서 Cognito 인증 과정 중 AWS STS assume_role 호출이 HTTP 408 (Request Timeout)으로 실패했다. 유효한 access token을 가진 사용자 1명의 API 요청이 인증 실패(AUTH20009)로 거부되었다. 단발성 이벤트로, 동일 에러는 3일간(May 20-23) 다른 발생 기록이 없다.
Quick Facts#
| Field | Value |
|---|---|
| exception.class | Aws::STS::Errors::Http408Error |
| exception.message | Cognito get_user_by_access_token failed: Aws::STS::Errors::Http408Error |
| top_frame | lib/cupix/auth/verification.rb:82 |
| env | production, us-west-2 |
| deploy | production-us-west-2-20260522T0559Z0-3e770a15-cupixworks |
Timeline#
- 2026-05-22T14:44:44.663Z — STS assume_role HTTP 408 timeout 발생, 사용자 인증 실패
- 2026-05-22T14:44:44.663Z — Error-sweeper가 에러 수집
- 2026-05-23 — RCA 완료
Error Log#
Cognito get_user_by_access_token failed: Aws::STS::Errors::Http408Error, #<Cupix::Auth::VerifiedAccessToken:0x00007fab07e22d18 @access_token="eyJraWQiOiJieDJJNzFWVFAxZkI1elk1eUVyZFFVMkRpSUJ0V3RoUG81WllhQnE0QkpZPSIsImFsZyI6IlJTMjU2In0...", @decoded_access_token=[{"origin_jti"=>"9722bb88-193e-4af6-bbb3-055b05b0e378", "sub"=>"267c2b38-67ad-445c-910b-05461bba48b9", "token_use"=>"access", ...}], @issuer=Cupix::Auth::Issuers::Cognito>
Impact#
- Service:
cupixworks-api - 발생 횟수: 1
- 최초 발생: 2026-05-22T14:44:44.663Z
- 최근 발생: 2026-05-22T14:44:44.663Z
- 영향 범위: 단일 사용자(sub: 267c2b38-67ad-445c-910b-05461bba48b9)의 1회 API 요청 실패. 후속 요청은 정상 처리된 것으로 추정 (추가 에러 없음).
Root Cause Summary#
AWS STS assume_role API 호출이 일시적인 네트워크/서비스 지연으로 HTTP 408 (Request Timeout) 응답을 반환했다. Cupix::Aws::Cognito.client 메서드에서 STS client 생성 시 명시적 timeout 설정이 없어 AWS SDK 기본값을 사용하며, STS 서비스 측의 일시적 지연이 timeout으로 이어졌다. 이 에러는 get_user_by_access_token 내부의 rescue 블록에서 NotAuthorizedException만 처리하고 STS 에러는 처리하지 않아, 상위의 verify_authenticated_request!까지 전파되어 사용자에게 AUTH20009 (인증 실패)로 응답되었다.
Technical Analysis#
Code Path#
- Entry point:
lib/cupix/auth/verification.rb:81— 인증된 요청 검증 시 Cognito에서 사용자 정보 조회
user_response = Cupix::Aws::Cognito.get_user_by_access_token(access_token: access_token, sub: sub)
rescue StandardError => e
Cupix::Logger.warn("Cognito get_user_by_access_token failed: #{e.message}, #{verified_access_token.inspect}",
class: 'Verification',
function: __method__,
module: 'Cupix::Auth',
error_type: e.class.name,
decoded_token_present: !verified_access_token.decoded_access_token.nil?)
raise Cupix::Errors::Unauthorized.new(code: 'AUTH20009', reason: 'AccessToken has verified but user not found', access_token: verified_access_token.access_token, module: 'Cupix::Auth', class: 'Verification', function: __method__)
- Cognito client 생성:
lib/cupix/aws/cognito.rb:9-27— STS assume_role 호출 (timeout 미설정)
def client(region: nil)
region ||= Cupix::Tesla.region
sts_client = ::Aws::STS::Client.new(region: region)
assumed_role = sts_client.assume_role(
role_arn: $AWS.fetch(:cognito).fetch(:role),
role_session_name: 'CognitoSession'
)
credentials = assumed_role[:credentials]
::Aws::CognitoIdentityProvider::Client.new(
region: region,
credentials: ::Aws::Credentials.new(
credentials[:access_key_id],
credentials[:secret_access_key],
credentials[:session_token]
)
)
end
- get_user_by_access_token:
lib/cupix/aws/cognito.rb:203-217— NotAuthorizedException만 catch, STS 에러 미처리
def get_user_by_access_token(access_token: nil, sub: nil)
sub ||= ::JWT.decode(access_token, nil, false).first['sub']
Rails.cache.fetch(user_cache_key(sub), expires_in: 1.hour) do
Cupix::Logger.info("Fetching an user from Cognito: #{sub}", function: __method__, module: 'Cupix::Aws', class: 'Cognito')
response = client.get_user(access_token: access_token)
rescue ::Aws::CognitoIdentityProvider::Errors::NotAuthorizedException
raise Cupix::Errors::Unauthorized.new(code: 'AUTH20013', reason: 'Invalid access token')
else
Cupix::Aws::Cognito::UserResponse.new(
user_response_hash(response)
)
end
end
- Failure point:
lib/cupix/aws/cognito.rb:12-13—::Aws::STS::Client.new후assume_role호출에서 HTTP 408 반환
기대 동작: STS assume_role이 성공하여 임시 자격 증명을 반환하고, 이를 사용해 Cognito get_user를 호출.
실제 동작: STS가 HTTP 408 timeout을 반환하여 Aws::STS::Errors::Http408Error 예외 발생. 이 예외는 get_user_by_access_token의 rescue에서 잡히지 않고(NotAuthorizedException만 catch), verify_authenticated_request!의 rescue StandardError에서 잡혀 AUTH20009로 변환됨.
Log Evidence#
사용한 Datadog 쿼리:
service:cupixworks-api status:error @environment:production "Aws::STS::Errors::Http408Error"
service:cupixworks-api status:error @environment:production "Cognito get_user_by_access_token failed"
핵심 로그 항목:
{
"timestamp": "2026-05-22T14:44:44.663Z",
"service": "cupixworks-api",
"status": "error",
"host": "ip-10-1-144-228.us-west-2.compute.internal",
"module": "Cupix::Auth",
"class": "Verification",
"function": "verify_authenticated_request!",
"error_type": "Aws::STS::Errors::Http408Error",
"decoded_token_present": true,
"message": "Cognito get_user_by_access_token failed: Aws::STS::Errors::Http408Error, #<Cupix::Auth::VerifiedAccessToken:...>"
}
추가 조사 결과:
- 동일 기간(May 20-23) 내 다른 STS 에러: 0건
- 동일 기간 내 다른 Http408Error: 0건
- token은 유효 (iat: 13:51:27Z, exp: 14:51:27Z, 에러 시점 14:44:44Z — 만료 7분 전)
decoded_token_present: true— JWT 디코딩은 성공, STS 호출 단계에서 실패
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | AWS STS 서비스의 일시적 지연/장애로 assume_role이 timeout | HTTP 408은 서버 측 request timeout; 단발 1회 발생; 동일 시간대 다른 STS 에러 없음 (광범위 장애 아님) | — | Confirmed |
| H2 | 만료된 access token으로 인한 인증 실패 | — | token exp=14:51:27Z, 에러 시점=14:44:44Z (7분 전에 유효); decoded_token_present: true |
Rejected |
| H3 | 네트워크 문제로 EC2 → STS 연결 실패 | 단일 호스트(ip-10-1-144-228)에서만 발생 | HTTP 408은 연결 실패가 아닌 서버 측 timeout 응답; 연결 실패라면 Seahorse::Client::NetworkingError 발생 |
Rejected |
| H4 | STS client에 timeout/retry 미설정으로 인한 취약성 | ::Aws::STS::Client.new(region: region) — timeout, retry_limit 파라미터 없음; AWS SDK 기본 retry는 3회이나 408은 retryable 에러 목록에 포함되지 않을 수 있음 |
단발 이벤트이므로 직접적 원인은 아님 (기여 요인) | Inconclusive |
Fix Recommendation#
즉시 조치 (Critical)#
- 불필요 — 단발성 일시적 STS timeout으로 시스템적 문제가 아님. 로그 레벨은 이미
warn으로 적절.
단기 개선 (1주 이내)#
lib/cupix/aws/cognito.rb:12— STS client 생성 시 retry 및 timeout 설정 추가.::Aws::STS::Client.new(region: region, retry_limit: 3, retry_mode: 'adaptive', http_open_timeout: 5, http_read_timeout: 5)형태로 명시적 설정을 통해 일시적 STS 지연 시 자동 재시도.lib/cupix/aws/cognito.rb:203-217—get_user_by_access_token에서 STS/네트워크 관련 예외(Aws::STS::Errors::ServiceError)도 catch하여 retry하거나 더 명확한 에러 메시지 반환.
장기 개선 (재발 방지)#
- STS assume_role 결과를 캐싱하여 매 요청마다 STS를 호출하지 않도록 개선. 현재는
get_user_by_access_token이 호출될 때마다(캐시 미스 시) 새로운 STS client를 생성하고 assume_role을 호출한다. 임시 자격 증명의 유효 기간(기본 1시간) 동안 캐싱하면 STS 의존성을 크게 줄일 수 있음. - Circuit breaker 패턴 적용: STS 연속 실패 시 캐시된 자격 증명으로 fallback.
Monitoring#
- STS timeout/에러 추적을 위한 Datadog 쿼리:
service:cupixworks-api @error_type:"Aws::STS::Errors::*" @environment:production
- assume_role 호출 지연 메트릭 추가 (p99 latency 모니터링)
- AUTH20009 에러 빈도가 임계치를 초과할 경우 알림 설정
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial
- 단발성 AWS STS timeout으로 시스템적 영향 없음. 사용자는 다음 요청에서 정상 인증됨. 단기 개선(retry 설정)으로 향후 동일 문제 자동 복구 가능.