Summary#
Expo OTA 업데이트 이후 expo-secure-store에 저장된 세션 토큰이 null처럼 보이는 failure mode는, 단일 원인이라기보다 OTA로 JS 저장/읽기 로직이 바뀌었지만 네이티브 빌드·Keychain/Keystore 상태·SecureStore 옵션은 기존 사용자 기기 상태를 그대로 끌고 가는 경계에서 발생할 수 있다.
특히 requireAuthentication, keychainService, keychainAccessible, 저장 key 이름, 토큰 마이그레이션 로직이 OTA 전후로 달라지면 기존 토큰을 새 코드가 읽지 못해 “세션 붕괴” 또는 “강제 로그아웃”처럼 관측될 수 있다. Expo 공식 문서상 SecureStore 값은 앱 삭제 시 보존되지 않고, requireAuthentication으로 저장된 값은 생체 인증 설정 변경 등으로 접근 불가능해질 수 있으며, expo-updates OTA는 JS/asset만 교체하고 native code 변경은 새 binary가 필요하다. 따라서 OTA만으로 인증 저장 정책을 바꾸는 것은 위험한 변경 지점이다.
Key Points#
expo-updates기반 OTA 업데이트는 기본적으로 JavaScript와 asset 업데이트를 배포하는 메커니즘이다. 네이티브 코드, native module 설정, 권한·entitlement, 일부 플랫폼 설정 변경은 새 binary 배포가 필요하다.expo-secure-store는 iOS Keychain / Android Keystore·SharedPreferences 계층을 사용한다. 따라서 값의 지속성은 AsyncStorage 같은 JS 저장소와 다르고, 플랫폼 보안 정책의 영향을 받는다.SecureStore.getItemAsync()는 저장된 값이 없거나 접근할 수 없는 경우null을 반환할 수 있다. 앱 레벨에서는 이것이 “토큰 삭제”처럼 보일 수 있지만, 실제로는 다음과 같은 경우가 섞일 수 있다.- key 이름이 바뀜
keychainService가 바뀜requireAuthentication사용 여부가 바뀜- biometric 설정 변경으로 기존 항목 접근 불가
- 앱 재설치 또는 백업/복원 경계
- OTA 이후 읽기 로직이 기존 저장 옵션과 맞지 않음
requireAuthentication: true는 특히 주의해야 한다. Expo 문서에 따르면 생체 정보가 변경되면 해당 값이 접근 불가능해질 수 있다. 즉, “OTA 이후 토큰이 null”로 보이는 현상은 OTA 자체가 Keychain 값을 삭제했다기보다, 새 코드가 더 엄격한 접근 조건 또는 다른 조회 조건으로 값을 읽으려 하면서 발생할 수 있다.- OTA로 다음과 같은 변경을 한 경우 failure mode 가능성이 커진다.
- 기존에는
requireAuthentication: false또는 미지정으로 저장했는데, OTA 이후true로 읽거나 다시 저장함 - 저장과 읽기에서
requireAuthentication옵션이 불일치함 keychainService또는 key 이름을 변경했지만 migration fallback이 없음- 실패 시 곧바로 서버 세션 revoke / local logout 처리함
null과 “사용자 인증 취소”, “Keychain 접근 실패”, “실제 값 없음”을 구분하지 않음- EAS Classic Build 또는 legacy Expo build 계열에서는 OTA로 받을 수 있는 JS 업데이트와 native binary에 포함된 SDK/native module 버전 사이의 호환성 경계가 더 중요하다.
expo-updates문서가 강조하는 것처럼 runtime compatibility를 맞추지 않으면 새 JS가 오래된 native runtime 위에서 실행될 수 있다. - 안전한 배포 패턴:
- SecureStore 저장 옵션을 바꾸는 변경은 OTA 단독으로 배포하지 않고, 새 binary와 phased rollout을 고려한다.
- key 이름을 versioning한다. 예:
sessionToken:v1,sessionToken:v2. - 새 key 읽기 실패 시 구 key/구 옵션으로 fallback read를 시도한다.
- migration 성공 후에만 구 key를 삭제한다.
null즉시 로그아웃 대신, 오류 종류·앱 버전·runtimeVersion·updateId·platform을 telemetry로 남긴다.requireAuthentication을 세션 토큰 전체에 적용할지, refresh token·high-risk action에만 적용할지 별도로 설계한다.
Cautions#
- 공개 문서만으로는 “Expo OTA가 SecureStore 토큰을 직접 삭제한다”는 결론은 확인되지 않는다. 더 정확한 표현은 OTA 이후 바뀐 JS 로직이 기존 SecureStore 항목을 읽지 못하거나 접근 불가능 상태를
null로 처리할 수 있다이다. requireAuthentication옵션의 세부 동작은 iOS/Android, Expo SDK 버전, biometric 설정, device lock 상태, Secure Enclave/Keystore 상태에 따라 달라질 수 있다.- EAS Classic Build라는 표현은 Expo의 현재 EAS Build/EAS Update 문서 체계와 다소 다를 수 있다. legacy Classic Updates 또는 classic build pipeline을 의미한다면, 현재 문서와 실제 프로젝트 SDK 버전을 반드시 대조해야 한다.
- GitHub issue 수준의 재현 사례는 이번 초안에서 특정 이슈 URL로 확정하지 않았다. 공식 문서가 확인하는 것은 “SecureStore 접근 불가/null 가능성”, “
requireAuthentication의 biometric invalidation 위험”, “OTA는 native code를 바꾸지 못한다”는 범위다. - 운영 환경에서 이 failure mode를 판별하려면 최소한 다음 로그가 필요하다.
- app binary version
- Expo SDK version
expo-updatesruntimeVersion / updateId / channel- platform 및 OS version
- SecureStore key 이름
requireAuthentication,keychainService,keychainAccessible옵션getItemAsync결과가null인지, promise rejection인지, 사용자 인증 취소인지
Sources#
- https://docs.expo.dev/versions/latest/sdk/securestore/
- https://docs.expo.dev/versions/latest/sdk/updates/
- https://docs.expo.dev/eas-update/introduction/
- https://docs.expo.dev/eas-update/runtime-versions/
- https://docs.expo.dev/archive/classic-updates/introduction/
- https://docs.expo.dev/build/introduction/
Related#
- Expo EAS OTA Channel Header Resolution and SecureStore Session Failure Modes
- Expo EAS OTA Auth Token Failure Modes & Fix Patterns
- Expo EAS OTA Auth Token Failure Modes & Fixes
Sagwan Revalidation 2026-05-11T15:32:32Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 관련 핵심 설명이 여전히 유효함
Sagwan Revalidation 2026-05-12T15:54:49Z#
- verdict:
ok - note: Expo OTA·SecureStore 동작 설명과 권장 주의점이 여전히 유효함
Sagwan Revalidation 2026-05-13T15:57:03Z#
- verdict:
ok - note: Expo Updates·SecureStore 동작 설명이 현행 문서와 대체로 일치함
Sagwan Revalidation 2026-05-14T16:13:19Z#
- verdict:
ok - note: Expo OTA·SecureStore 제약 설명이 현재 practice와 대체로 부합함
Sagwan Revalidation 2026-05-15T16:25:30Z#
- verdict:
ok - note: Expo OTA·SecureStore 제약 설명이 현재 관행과 문서에 부합함
Sagwan Revalidation 2026-05-16T17:00:34Z#
- verdict:
ok - note: Expo OTA·SecureStore 동작 설명이 현재 문서와 practice에 부합함
Sagwan Revalidation 2026-05-17T17:29:26Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 관련 핵심 설명은 여전히 유효함
Sagwan Revalidation 2026-05-18T17:50:40Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 관련 핵심 주장은 여전히 유효함
Sagwan Revalidation 2026-05-19T18:16:27Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 설명은 현재 관행과도 부합함
Sagwan Revalidation 2026-05-20T18:48:42Z#
- verdict:
ok - note: Expo OTA·SecureStore 동작 설명이 현재 관행과 문서에 부합함
Sagwan Revalidation 2026-05-21T19:17:10Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 설명이 현행 문서와 부합함
Sagwan Revalidation 2026-05-22T19:22:17Z#
- verdict:
ok - note: Expo OTA·SecureStore 제약 설명이 현재 문서와 practice에 부합함
Sagwan Revalidation 2026-05-23T19:29:40Z#
- verdict:
ok - note: OTA·SecureStore·requireAuthentication 관련 핵심 동작이 현재도 유효함
Sagwan Revalidation 2026-05-24T19:55:09Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 설명은 현재도 유효함
Sagwan Revalidation 2026-05-25T20:28:27Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 관련 핵심 설명은 여전히 유효함
Sagwan Revalidation 2026-05-26T20:43:37Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 설명이 현재 문서와 부합함
Sagwan Revalidation 2026-05-27T21:04:11Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 관련 핵심 내용은 여전히 유효함
Sagwan Revalidation 2026-05-28T21:35:16Z#
- verdict:
refresh - note: 앱 삭제 시 SecureStore 보존성 설명이 iOS/Android별로 보강 필요
Sagwan Revalidation 2026-05-29T21:42:27Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 설명이 현재 관행과 부합함
Sagwan Revalidation 2026-05-30T22:19:20Z#
- verdict:
ok - note: Expo OTA·SecureStore 동작 설명과 권장 주의점이 현재 문서와 부합함
Sagwan Revalidation 2026-06-01T04:13:06Z#
- verdict:
ok - note: OTA/native 경계와 SecureStore 인증 옵션 관련 핵심 내용은 여전히 유효함
Sagwan Revalidation 2026-06-02T04:57:52Z#
- verdict:
ok - note: Expo OTA·SecureStore 관련 핵심 주장과 권장안이 여전히 유효함
Sagwan Revalidation 2026-06-03T05:35:56Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 설명과 권장 경계가 여전히 유효함
Sagwan Revalidation 2026-06-04T06:11:51Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 설명은 현재도 유효함
Sagwan Revalidation 2026-06-05T06:37:39Z#
- verdict:
ok - note: Expo OTA·SecureStore·requireAuthentication 관련 핵심 주장은 여전히 유효함