Railway에 저장해 둔 환경 변수가 노출됐을 수 있다, 무엇부터 바꿀까
HOTSecurity14분 읽기

Railway에 저장해 둔 환경 변수가 노출됐을 수 있다, 무엇부터 바꿀까

Railway 환경 변수 일부가 복호화됐고 접근은 10월 20일부터 이틀 가까이 이어졌습니다. 값은 발급처에서 폐기해야 의미가 있어, 교체 순서와 확인 명령, 막힌 배포 복구를 런북으로 적었습니다.

Railway에 올려 둔 앱의 환경 변수는 전부 노출된 것으로 보고, 값을 발급한 곳에서 폐기해 새로 받은 다음 그 값을 쓰는 서비스를 모두 다시 배포하는 것까지가 이번 대응의 최소 범위입니다. Railway 화면에서 변수를 새 값으로 덮어쓰기만 하면 복사돼 나간 옛 키는 계속 살아 있습니다. 이 글의 시각은 모두 UTC이고, 사건 경과보다 “무엇을, 어떤 순서로, 무엇으로 확인하나”에 분량을 씁니다. 10월 27일 현재 Railway가 낸 가장 최근의 사고 문서는 10월 22일 중간 보고서이고, 사용자 소스 코드 접근 여부는 최종 포렌식 보고서에서 밝히겠다고 적어 둔 상태입니다.

High · 점수 없음 플랫폼 침해 사고, CVE 없음 값 교체는 사용자 몫
영향 대상
Railway에 환경 변수·API 키·사설 레지스트리 자격 증명을 저장한 모든 사용자. 노출 가능성이 검증된 범위는 최대 1.85%(약 10만 워크스페이스)지만, 권고는 10월 21일 이전에 저장한 값 전체
공격 방식
빌드 인프라의 권한 상승 시도에서 시작해 CI 환경 자격 증명을 거쳐 암호화된 환경 변수 저장소에서 일부를 복호화
공격 시간대
10월 20일 13:58부터 10월 22일 03:32까지(UTC)
Railway가 한 일
세션·Railway 토큰 폐기, 저장소 버킷 키 재발급, GitHub 연결 초기화, 발급처에 폐기 요청
  • AI 업체·클라우드·결제 키를 발급처 콘솔에서 폐기하고 재발급
  • 새 값을 Railway에 넣고 그 값을 쓰는 모든 서비스를 재배포
  • 데이터베이스는 Regenerate, 공개 접근은 끄기
  • 10월 20일 이후 옛 키로 들어온 호출이 있는지 사용 기록 확인

이미 바뀐 값과 아직 살아 있는 값

가장 먼저 가를 것은 “Railway가 이미 처리한 값”과 “내가 처리해야 하는 값”입니다. 둘을 섞어 두면 이미 초기화됐겠지 하고 넘긴 값이 계속 유효해집니다. 아래 격자에서 색이 진할수록 사용자에게 남은 일이 많습니다.

값 종류별로 Railway가 이미 한 일과 사용자가 해야 할 일을 색 농도로 보인 격자 그림 1. 위쪽 네 줄은 Railway가 처리했고, 아래쪽 줄은 전부 사용자가 발급처에서 처리한다

Railway가 한 일은 세 갈래입니다. 모든 로그인 세션과 Railway 접근 토큰(CLI·CI용)을 폐기했고, GitHub 앱 설치와 연결 토큰을 초기화했고, 모든 환경의 저장소 버킷 S3 자격 증명(접근 키 ID와 비밀 키)을 다시 발급했습니다. 서비스에 레지스트리 자격 증명으로 넣어 둔 GitHub 액세스 토큰은 Railway에서 지워졌지만 GitHub에서는 여전히 유효하므로 직접 삭제해야 합니다. 격자의 아래쪽, 곧 AI 업체 키·클라우드 키·결제 키·데이터베이스 비밀번호·그 밖의 변수는 Railway가 바꿔 주지 않습니다. 공지가 “모든 환경 변수”를 교체하라고 했고 예외를 두지 않았으므로, 화면에서 값이 가려지는 봉인(sealed) 변수도 같은 대상으로 취급합니다.

키가 새어 나간 경로

왜 이렇게 넓게 바꿔야 하는지는 중간 보고서가 그린 경로를 보면 알 수 있습니다. 공격은 사용자 계정이 아니라 Railway 내부 시스템을 따라 올라갔고, 그래서 사용자 쪽의 로그인 기록으로는 피해를 가려낼 수 없습니다.

빌드 인프라에서 CI 자격 증명, 환경 변수 저장소를 거쳐 발급처의 옛 키로 이어지는 경로도 그림 2. 붉은 칸이 Railway 내부, 초록 칸이 발급처. 사용자 계정 로그인은 확인되지 않았다

첫 단계는 빌드 인프라의 권한 상승 시도였고, 모니터링이 지연 시간 증가를 잡은 10월 20일 13:58이 공격 시작 추정 시각입니다. 암호화된 상태의 비밀을 가져간 것은 10월 21일 04:2405:23 사이이고, 이때는 아직 열지 못했습니다. 05:27부터 CI 환경 자격 증명으로 추가 API 접근이 담긴 산출물을 복호화했고, 07:2509:18에 암호화된 환경 변수에 대한 비인가 조회가 확인됐으며 일부가 복호화됐습니다. 키 전체가 봉투 암호화로 보호돼 있어서 조회 기록만으로는 어느 키가 열렸는지 가려낼 수 없었습니다. 그래서 Railway는 “개별 키”가 아니라 “플랫폼이 저장한 모든 키”를 발급처에 넘겼고, 이것이 내 키가 털렸는지 알 수 없는 이유입니다.

Railway는 이 공격을 플랫폼 업체를 연달아 노려 AI 추론 업체의 키를 모으려는 흐름의 일부로 봅니다. 공격자 페이로드 로그에서 찾던 API 키 이름이 확인됐고, 초기 조사로는 증류(distillation)가 목적입니다. 증류는 값비싼 모델에 질문을 대량으로 던져 받은 답으로 자기 모델을 훈련하는 방식이라, 남의 API 키가 곧 연료가 됩니다. 이 때문에 순서에서 AI 업체 키가 맨 앞에 옵니다.

공지가 나가기까지의 시간표와 1.85%

사용자 입장에서 중요한 간격은 두 개입니다. 업체에 키 폐기를 요청한 시각(10월 21일 09:25)과 사용자 공지가 나간 시각(20:19) 사이가 약 11시간이고(편집부 계산), 공격 시간대 전체는 약 37시간 반입니다(편집부 계산).

8개 사건을 UTC 시각과 함께 나열한 타임라인 그림 3. 붉은 점 두 개가 업체 통보와 사용자 통보. 간격은 축척이 아니다

사용자에게 늦게 알린 이유로 Railway는 침입자가 아직 시스템 안에 있을 때 교체를 권하면 새로 넣은 키가 곧바로 다시 노출될 수 있다는 점을 듭니다. 10월 22일 03:32에 공격자가 더는 접근하지 못한다는 것을 확인한 뒤 내부 시스템을 최소 의존성과 새 자격 증명으로 다시 초기화했고, 같은 날 17:00~22:49에 모든 요금제의 배포가 정상으로 돌아왔습니다. 10월 23일 22:03에는 지원 사이트(station.railway.com)가 복구됐고, 같은 갱신에서 신규 가입과 일부 비핵심 기능은 계속 중지 상태로 남았습니다.

1.85%라는 숫자는 두 가지를 같이 읽어야 합니다. 하나는 “확인된 피해”가 아니라 노출 가능성이 있다고 검증한 범위의 상한이라는 점입니다. 다른 하나는 발급처에 넘긴 범위가 그보다 훨씬 넓다는 점입니다. GitHub·GitLab·Anthropic·OpenAI·OpenRouter·Stripe 등에서 “키가 폐기됐다”는 알림을 받았다고 내 키가 털렸다는 뜻은 아니고, 못 받았다고 안전하다는 뜻도 아닙니다. 확정 영향과 고위험 고객에게는 Railway가 따로 연락하며, 고위험 부류는 변수가 매우 많은 워크스페이스와 AI 업체 키가 많은 환경입니다.

서비스가 내려갔는지도 자주 묻습니다. 실행 중이던 서비스는 계속 온라인이었고 멈춘 것은 새 빌드와 배포입니다. Railway는 영향받은 시스템을 다시 배포해 검증했고 빌더를 4세대 단일 테넌트 환경으로 옮겼다고 밝혔습니다. 다만 이것과 무관하게 값 교체는 해야 합니다.

바꾸는 순서

한꺼번에 못 바꾼다면 “새면 곧바로 돈이나 문이 열리는 값”부터 갑니다. 공격자가 노린 것이 AI 업체 키였다는 사실이 순서의 근거입니다.

  1. AI 업체 API 키. OpenAI, Anthropic, xAI의 Grok, OpenRouter 키는 유출되면 곧바로 내 비용으로 호출됩니다. 가장 먼저 처리합니다.
  2. 클라우드·결제 키. AWS 접근 키, GCP 서비스 계정 키, Stripe 비밀 키는 다른 시스템의 문을 엽니다.
  3. 데이터베이스. 공개 접근(TCP 프록시)이 켜져 있으면 인터넷 어디서나 쓸 수 있으니 접근을 끄고 비밀번호를 Regenerate합니다.
  4. GitHub와 컨테이너 저장소 토큰. Railway가 지운 것은 Railway 쪽 사본이므로 GitHub 설정에서 직접 폐기합니다.
  5. 나머지. 세션 서명 키, 웹훅 비밀값, 내부 토큰. 세션 서명 키를 바꾸면 모든 사용자가 로그아웃되고, 웹훅 비밀값은 보내는 쪽에서도 같이 바꿔야 어긋나지 않습니다.

키 하나를 폐기하는 일곱 동작

모든 값에 같은 한 바퀴가 적용됩니다. 위험한 구간은 두 곳입니다. 새 키를 만든 뒤 옛 키를 지우기 전까지 옛 키가 누구에게나 통하는 구간, 그리고 옛 키를 지운 뒤 재배포가 끝나기 전까지 내 서비스가 인증 실패를 내는 구간입니다.

사용자, 발급처 콘솔, Railway 변수, 실행 중인 서비스 사이에서 키 교체 일곱 동작이 오가는 순서도 그림 4. 2번에서 변수를 미리 올려 두면 3번에서 5번까지의 인증 실패 구간이 짧아진다

Railway의 변수 변경은 “스테이징” 상태로 쌓이고 배포를 눌러야 적용됩니다. 그래서 2번에서 새 값을 올려만 두고, 3번의 폐기 직후에 4번의 배포를 붙여서 합니다. 컨테이너는 시작할 때 읽은 변수를 계속 쓰기 때문에 재배포하지 않으면 옛 값이 그대로 돌고, 그 상태에서 옛 키를 지우면 서비스가 인증 실패를 내기 시작합니다. 방금 배포한 서비스 하나가 아니라 그 키를 가리키는 모든 서비스를 재배포해야 합니다. 여러 서비스가 쓰는 공유 변수라면 프로젝트 설정에서 한 번만 고칩니다.

OpenAI 키로 풀어 쓰면 이렇게 됩니다.

  1. API keys 화면에서 프로젝트를 먼저 고른 뒤 같은 프로젝트에 새 비밀 키를 만들고 그 자리에서 복사한다. 화면을 닫으면 다시 볼 수 없다.
  2. Railway 서비스의 Variables 탭에서 값을 새 키로 바꾸되 배포는 아직 누르지 않는다.
  3. OpenAI로 돌아가 노출된 키 옆 휴지통으로 삭제한다. 삭제는 즉시 적용된다. 프로젝트 키와 오래된 사용자 키는 다른 화면이므로 둘 다 본다.
  4. 곧바로 Railway에서 스테이징된 변경을 배포한다.
  5. 새 배포가 활성화되면 로그에서 호출이 성공하는지 보고, 사용량을 키별로 본다.

같은 틀이 쓰이지만 발급처마다 안전 장치가 다릅니다. Anthropic은 Console의 API keys에서 삭제하고, 관리자 키(sk-ant-admin01-로 시작)는 따로 있어 따로 지웁니다. OpenRouter는 삭제하면 사용 기록도 함께 사라지므로, 삭제 전에 키 조회(/api/v1/key)로 누적·일간·주간·월간 사용량을 확인하고 비활성화부터 한 뒤 삭제합니다. 새 키에는 지출 한도와 만료일을 겁니다. xAI는 키를 비활성화하면 되돌릴 수 있고 사용 기록이 키에 남습니다.

클라우드와 결제 키는 “다운타임을 감수하느냐”에 따라 갈라집니다. 유출이 확실하다면 짧은 중단을 감수하고 옛 자격을 즉시 끊는 쪽이 맞습니다. 예방 차원이고 중단이 곤란하다면 다음 방법이 있습니다.

  • AWS: 사용자당 접근 키를 두 개까지 가질 수 있으므로 새 키를 먼저 만들고 옛 키는 삭제가 아니라 비활성화합니다. 잊고 있던 서비스가 깨져도 잠깐 되살릴 수 있습니다.
  • GCP: 서비스 계정 키는 기본적으로 만료되지 않고 콘솔에서는 비활성화할 수 없어 gcloud iam service-accounts keys disable KEY_ID --iam-account=이메일을 씁니다. 이미 발급된 단기 토큰은 최대 한 시간 유효해서, 즉시 끊으려면 서비스 계정 자체를 비활성화하고 60분 넘게 기다렸다가 되살립니다.
  • Stripe: 키를 교체할 때 옛 키의 만료 시점을 고를 수 있습니다. 확정 유출이면 “지금”, 예방이면 재배포에 필요한 유예 시간을 줍니다.

발급처별로 열어 볼 기록

폐기만으로 끝나지 않습니다. 공격 시간대가 시작된 10월 20일 13:58(UTC) 이후에 내가 부르지 않은 호출이 있었는지 봐야 합니다. 발급처마다 기록이 남는 방식과 보관 기간이 달라서, 어디를 여는지만 알면 한 곳에 몇 분이면 됩니다.

발급처 열 곳 의심 신호 알아 둘 것
Anthropic Console의 Usage를 키별로 묶기, Cost, Logs 한 모델만 쓰던 키에 다른 모델이 보임 GitHub 비밀 스캔이 노출 키를 알려 비활성화된 경우도 있음
OpenAI Usage를 프로젝트·키 단위로, Billing의 크레딧 토큰 양·요청 수·모델 구성이 평소와 다름 키 삭제는 즉시 적용
OpenRouter 키 조회 API로 누적·일·주·월 사용량 평소에 쓰지 않던 때의 사용량 삭제하면 사용 기록도 사라지므로 비활성화 먼저
xAI(Grok) 키에 남은 사용 기록 내가 보내지 않은 호출 비활성화는 되돌릴 수 있음
Stripe 폐기한 옛 키의 요청 로그 낯선 IP·엔드포인트, 결제·환불·정산 계좌·웹훅 변경 웹훅 서명 비밀은 API 키와 별개라 따로 교체
AWS CloudTrail 이벤트 기록(90일, 리전별), 자격 증명 보고서, Cost Explorer RunInstances, CreateUser, CreateAccessKey, AttachUserPolicy, CreateRole, PutBucketPolicy 쓰지 않는 리전에도 자원이 만들어졌을 수 있어 모든 리전 반복
GCP Logs Explorer(주체 이메일로 조회), Activity Analyzer, 결제 보고서 새 서비스 계정·키·IAM 바인딩, Compute·GPU·Vertex AI 사용량 흔한 표적이 이 세 곳
GitHub 개인 보안 로그(90일), 조직 감사 로그(180일) 모르는 OAuth 앱, SSH·GPG 키, 개인 액세스 토큰, 배포 키, 웹훅, 협업자 지우기 전에 로그를 내려받기. 웹훅·시크릿은 비밀번호를 바꿔도 남음
Railway 워크스페이스 감사 로그(요금제별 보존) 우리 팀이나 Railway Staff가 아닌 주체의 변수 조회·레지스트리 자격 증명 변경·배포 버킷 키 재발급은 행위자가 “Railway Staff”로 남음

내 서비스가 쓰는 고정 출구 IP가 있다면 그 밖의 IP에서 온 호출이 단서입니다. 고정 출구 IP가 없으면 서비스가 Railway 공용 IP로 나가므로 낯선 IP는 단서일 뿐 증거가 아닙니다. 새 키를 걸면서 발급처마다 월 사용 한도와 알림을 같이 걸어 두면, 같은 일이 다시 생겨도 피해가 한계 안에서 멈춥니다.

읽기 전용 조회 명령

클라우드 두 곳은 콘솔에서 눈으로 훑는 대신 질의로 좁힐 수 있습니다. 아래는 아무것도 바꾸지 않는 명령이고, 키 ID와 서비스 계정 이메일만 내 것으로 바꿔 넣습니다. AWS는 이벤트 기록이 리전별이라 반복문으로 돌립니다.

# AWS: 노출된 접근 키로 일어난 이벤트를 리전마다 조회 (읽기 전용)
for r in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
  echo "== $r"
  aws cloudtrail lookup-events --region "$r" \
    --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIAEXAMPLEKEYID \
    --query 'Events[].[EventTime,EventName,Username]' --output text
done

# GCP: 서비스 계정 키가 마지막으로 인증된 날짜 확인 (읽기 전용)
gcloud policy-intelligence query-activity \
  --activity-type=serviceAccountKeyLastAuthentication --project=my-project

GCP의 Logs Explorer에는 아래 질의를 그대로 넣고 주체 이메일만 바꿉니다. 이 서비스 계정이 한 모든 일이 시간순으로 나옵니다.

logName:"cloudaudit.googleapis.com"
protoPayload.authenticationInfo.principalEmail="railway-uploads@my-project.iam.gserviceaccount.com"

이 글에서 쓰는 Railway CLI 명령도 한자리에 모아 둡니다. 출력은 계정마다 달라 적지 않았고, 그림의 마지막 두 줄은 명령을 돌렸을 때 만나게 될 오류 문자열입니다.

이 글에서 쓰는 Railway CLI 명령 네 개와 대표 오류 문자열을 모은 터미널 화면 그림 5. 노란 줄은 서비스가 옛 키로 돌고 있을 때, 붉은 줄은 데이터베이스 비밀번호가 어긋났을 때 나타난다

데이터베이스는 Regenerate 한 번

Railway 템플릿으로 만든 PostgreSQL·MySQL·Redis·MongoDB는 Regenerate가 가장 안전합니다. 데이터베이스 탭의 Config에서 Connection의 비밀번호 옆 버튼을 누르면 데이터베이스 안의 비밀번호와 서비스 변수가 함께 바뀌고, 데이터베이스가 재시작되면서 열려 있던 세션이 모두 끊깁니다. 공격자가 쥐고 있던 연결도 여기서 끊깁니다. 순서는 이렇습니다.

  1. 교체 전에 Variables 탭에서 이 데이터베이스를 쓰는 서비스를 찾고, Settings의 Networking에서 공개 접근이 켜져 있는지, 외부 도구가 DATABASE_PUBLIC_URL을 쓰는지 적어 둡니다.
  2. Regenerate를 누릅니다. 손으로 POSTGRES_PASSWORD를 고치거나 ALTER USER를 직접 실행하면 변수와 데이터베이스가 따로 놀기 때문에 쓰지 않습니다.
  3. 의존하는 서비스를 모두 재배포합니다. Regenerate는 데이터베이스만 재배포합니다. 연결 문자열을 붙여 넣은 서비스는 ${{ Postgres.DATABASE_URL }} 같은 참조 변수로 바꾼 뒤 배포합니다.
  4. 외부 도구에는 새 DATABASE_PUBLIC_URL을 직접 넣습니다. 공개 접근이 필요 없다면 이 기회에 끕니다.

참조 변수로 연결돼 있었다면 다음 교체부터는 Regenerate와 재배포만으로 끝납니다. 교체 뒤의 점검은 분기가 둘입니다. 서비스의 배포 로그에 password authentication failed가 보이면 그 서비스가 옛 비밀번호를 쥐고 있다는 뜻이니 재배포하거나 붙여 넣은 값을 참조로 바꿉니다. 로그가 깨끗하면 railway connect Postgres로 접속해 아래 질의로 지금 붙어 있는 세션을 봅니다. 재시작으로 이전 세션이 모두 끊겼으니 낯선 세션은 새 비밀번호로 들어온 것이어서 비밀번호가 어디서 새고 있는지 찾아야 하고, 그 세션은 SELECT pg_terminate_backend(12345);(숫자 자리에 조회에서 본 pid)로 끊습니다.

SELECT pid, usename, client_addr, application_name, backend_start, state
FROM pg_stat_activity
WHERE datname = current_database();

SELECT rolname FROM pg_roles;   -- 내가 만들지 않은 역할이 있는지

PostgreSQL은 기본 설정에서 성공한 접속과 클라이언트 주소를 로그에 남기지 않으므로, 과거에 누가 들어왔는지는 이 질의로 알 수 없고 낯선 역할·확장·행 변경으로 흔적을 찾습니다. 데이터가 바뀐 것을 발견하면 증거를 보존한 뒤 백업이나 특정 시점 복구로 되돌립니다. 비밀번호가 새지 않았다고 판단하고 중단을 피하고 싶다면 Railway의 무중단 교체 안내(이중 역할 방식)가 있지만, Railway 자신이 유출이 의심될 때는 옛 자격을 끊는 쪽이 짧은 중단보다 중요하다고 권합니다.

버킷 키와 ghcr 토큰

저장소 버킷은 Railway가 이미 키를 다시 발급했으므로 남은 일은 “새 값을 쓰게 만드는 것”입니다.

  1. 버킷과 환경마다 Credentials 화면이나 railway bucket credentials --bucket 이름으로 새 값을 봅니다.
  2. 서비스의 Variables에서 ${{ 버킷.SECRET_ACCESS_KEY }} 같은 참조나 AWS_SECRET_ACCESS_KEY 같은 라이브러리용 변수를 찾고, 옛 키가 평문으로 붙어 있으면 참조로 바꿉니다.
  3. 해당 서비스를 railway redeploy --service 이름으로 재배포하고, Railway 밖(로컬 개발, CI, S3 파일 탐색기)의 옛 키도 바꿉니다.
  4. 목록이나 쓰기가 성공하는지 확인합니다. InvalidAccessKeyId나 SignatureDoesNotMatch가 나오면 서비스가 옛 배포에서 돌고 있거나 옛 값을 붙여 넣은 것입니다.
  5. 버킷의 Files 화면에서 내가 올리지 않은 객체나 사라진 파일이 없는지 봅니다. 버킷에는 자동 백업이 없어서, 발견한 즉시 메모해야 합니다.

나중에 다시 바꿔야 하면 railway bucket credentials --reset이 현재 키를 무효화하고 새 키를 만듭니다. ghcr.io에서 비공개 이미지를 받으려고 서비스에 GitHub 토큰을 넣어 둔 경우는 GitHub 쪽 일이 남습니다.

  • GitHub의 Personal access tokens에서 옛 토큰을 삭제한다(Railway에서는 지워졌지만 GitHub에서는 아직 유효)
  • 범위를 read:packages로 한 새 토큰을 만든다
  • 서비스의 Settings > Source > Registry Credentials의 GitHub Access Token에 새 토큰을 넣고 저장한다(사용자 이름은 Railway가 채운다)
  • 서비스를 재배포하고, ghcr.io에서 받는 서비스마다 반복한다(사설 레지스트리 자격 증명은 Pro 요금제 기능)

배포가 안 뜰 때 증상별 처방

공격과 별개로, 많은 사람이 이번 사고를 “배포가 안 되는 문제”로 먼저 겪었습니다. 중지 동안 푸시한 커밋은 대기열에 쌓이지 않아서 서비스가 마지막 성공 배포를 그대로 돌렸고, 그사이 예약된 크론 작업은 실행되지 않고 다음 예약 시각부터 다시 돕니다.

증상 원인 처방
푸시해도 새 배포가 안 뜨고 빌드 오류에 “unable to pull repository” GitHub 연결 폐기 계정 설정에서 GitHub 재연결, 서비스 Settings > Source에서 Disconnect 후 Connect Repo, GitHub의 Railway 앱 권한 확인, Command Palette(CMD/CTRL + K)에서 “Deploy Latest Commit”
연결은 됐는데 자동 배포만 안 됨 자동 배포에는 저장소 기여자 권한의 GitHub 계정이 연결된 멤버가 최소 한 명 필요 그 멤버가 GitHub를 다시 연결하고 Settings에서 autodeploy를 Enable
CI의 railway up이 인증 오류 프로젝트 토큰(RAILWAY_TOKEN)과 계정·워크스페이스 토큰(RAILWAY_API_TOKEN)이 모두 폐기됨 같은 범위로 새 토큰을 만들어 CI 시크릿의 옛 값을 바꾸고 파이프라인 재실행
로컬 CLI가 로그인 안 됨 저장된 세션 폐기 railway logout 후 railway login
서비스는 떴는데 저장소 호출이 InvalidAccessKeyId 버킷 키가 바뀌었는데 옛 배포가 돌고 있음 해당 서비스 재배포
이메일로 로그인해야 계정이 이어짐 GitHub 앱 설치가 모두 초기화돼 GitHub 이메일과 Railway 이메일이 다름 “Log in using email” 사용
GitHub 로그인이 무한 반복 OAuth 앱 승인 상태 꼬임 GitHub의 OAuth 앱에서 Railway를 폐기하고 다시 시도
로그인했더니 프로젝트가 없음 처음 가입한 것과 다른 신원(Gmail·GitHub·이메일)으로 로그인해 빈 계정이 새로 생김 새 프로젝트를 만들지 말고 로그아웃한 뒤 원래 신원으로 로그인

계정에 못 들어갈 때 지원팀에 보내는 증명

표의 마지막 줄 처방으로도, 곧 원래 신원으로도 들어갈 수 없다면 지원팀이 계정을 복구해 줍니다. 지원 사이트(station.railway.com)는 10월 23일 22:03에 복구돼 다시 요청을 올릴 수 있고, 메일은 support@railway.com입니다. 이때 소유 증명 수단이 GitHub 계정입니다. 그 계정으로 이름이 Railway-2FA-Reset인 빈 공개 저장소를 만들어 그 주소를 요청서에 적고, 복구가 확인되면 저장소를 지웁니다. 요청서에는 비밀번호·로그인 코드·복구 코드·API 토큰을 절대 적지 않습니다.

#Railway#환경 변수#API 키#자격 증명 교체#배포 플랫폼