친구 하나 못 쓰던 앱을, 모두에게 열었다
음악 큐레이션 챗봇을 하나 만들었다. 아이디어를 준 친구한테 “한번 써봐” 하고 배포된 주소를 건넸는데, 친구가 아무리 해도 Spotify 로그인이 안 된다고 했다.
처음엔 흔한 OAuth 설정 실수겠거니 했다. redirect URI나 환경변수. 그런데 코드를 열어보니 Authorization Code + PKCE 흐름은 교과서대로였고, 내 계정으로는 멀쩡히 로그인됐다. 친구가 못 쓴 건 버그 때문이 아니었다.
결정적 단서는 “친구는 배포된 주소로 접속만 했다”는 점이었다. Spotify Developer 앱은 기본이 Development Mode고, 이 모드에선 대시보드에 직접 등록한 사용자만 로그인된다. 앱을 만든 내 계정은 자동으로 되지만, 친구는 미등록자라 튕긴 것이다. 이건 코드가 아니라 누가 접속하느냐의 문제였다.
해결은 간단하다. User Management에 친구 계정을 추가하면 풀린다. 거기서 끝낼 수도 있었는데, 그 화면을 보다가 다른 질문이 생겼다. 친구 한 명이 아니라, 아무나 쓰게 하려면?
25명을 막는 건 25만 명이다
등록제를 벗어나 “누구나 로그인”이 되게 하려면 Extended Quota Mode를 신청해야 한다. 자격 요건을 읽고 진짜 벽을 만났다.
- 법적으로 등록된 사업자 또는 조직
- 런칭되어 운영 중인 서비스
- 월간 활성 사용자(MAU) 25만 명 이상
- 주요 Spotify 시장에서 사용 가능
그리고 결정타. 2025년 5월부터 신청은 조직만 받는다. 개인은 접수 자체가 안 된다.
요건의 구조가 잔인하다. 멀티유저 권한을 받으려면 MAU 25만 명이 있어야 하는데, 25만 명을 모으려면 애초에 멀티유저로 서비스를 굴릴 수 있어야 한다. 권한을 받으려면 이미 그 권한으로 만든 결과가 있어야 한다. 친구를 손으로 등록해주는 것까지가 개인에게 허용된 전부고, 그 위로는 길이 없다. “로그인이 안 된다”에서 시작해 닿은 바닥은 개인은 멀티유저 앱을 운영할 수 없다는 정책이었다.
같은 정책의 다른 얼굴들
이 벽은 처음이 아니었다. 만들 때 이미 같은 정책의 다른 조각들에 부딪혔는데, 하나로 연결된 줄 몰랐을 뿐이다.
추천 품질을 위해 곡의 오디오 특성(audio-features)을 쓰려 했는데 토큰이 멀쩡한데도 403이 떨어졌다. 2024년 11월 변경 이후 새로 만든 앱은 audio-features에 기본 접근이 안 된다. 같은 이유로 미리듣기 URL(preview_url)도 항상 null로 와서, 미리듣기는 진작에 공개 임베드 플레이어로 우회해둔 상태였다.
403, preview null, 로그인 벽. 제각각의 사고처럼 보였지만 전부 한 뿌리였다. Spotify가 2026년 2월 업데이트에서 댄 명분은 *“자동화와 AI가 개발자 접근의 리스크 프로파일을 근본적으로 바꿨다”*는 것이다. 같은 업데이트로 Development Mode 상한은 25명에서 5명으로 줄었고, 앱 소유자에게 Premium 계정까지 요구하게 됐다. 내 앱은 이 조이기가 끝난 이후에 태어나서, 처음부터 그 그늘 안에 있었다.
막힌 건 로그인 사용자였다, 그래서 로그인을 없앴다
정식 멀티유저는 닫혀 있으니 “친구를 손으로 등록하는 1인 도구”로 쪼그라드나 싶었는데, 막힌 지점이 어디인지가 중요했다.
Spotify가 세는 건 등록된 로그인 사용자 수다. 5명 상한도, 자격 심사도 전부 “이 앱에 OAuth로 로그인하는 사람”을 카운트한다. 그렇다면 답이 뒤집힌다. 막는 게 로그인 사용자 수라면, 로그인 자체를 없애 셀 사용자가 없게 만들면 그 카운터에 안 걸린다. 로그인을 떼면 Spotify 계정이 없는 사람도 메인에서 바로 큐레이션을 쓸 수 있다. 등록제로 막던 문을, 문 자체를 치워서 여는 셈이다.
문제는 이 앱에서 로그인이 인증이 아니라 데이터 공급원이었다는 거다. LLM이 추천한 곡이 실재하는지 Spotify Search로 검증하는 것도, 시드 곡을 해석하는 것도 사용자 토큰을 통했다. 로그인을 그냥 떼면 인증만이 아니라 그 기능들이 같이 죽는다. “로그인 제거”가 실은 “데이터를 어디서 가져올 것인가”를 다시 푸는 문제였던 것이다.
답은 **앱 자체 토큰(Client Credentials)**이었다. 로그인 없이 앱이 직접 발급받는 토큰이라 공개 검색은 사용자 없이도 호출된다. 검증은 이 앱 토큰으로 공개 /v1/search만 써서 그대로 살리고, 사용자별 OAuth/DB 토큰 machinery는 통째로 들어냈다.
대신 잃은 것도 있다. 로그인으로 받던 내 라이브러리가 사라지니 “내 곡 중에 재즈 뭐 있어?” 같은 라이브러리 탐색은 같이 죽었다. 지금 열린 건 곡 하나를 시드로 친족을 추천하는 큐레이션 한 길뿐인데, 애초에 이게 핵심 모드였고 라이브러리 탐색은 보조였다. 보조를 내주고 핵심을 모두에게 연 거래였다. 사용자 ID는 고정 익명값(local)으로 두고 관련 테이블은 비워둔 채 남겼다. 멀티유저 복원의 길은 막지 않으려고. 약 2,900줄이 사라졌다.
빼지 않기로 한 것
들어내면서 의식적으로 남겨둔 게 하나 있다. 메인 하단의 “Recent diggings”, 사람들이 판 큐레이션 기록이다.
로그인이 없으면 “누가 이걸 썼다”는 흔적도 사라진다. 처음 들어온 사람에게 텅 빈 입력창만 있으면 살아있는 도구인지 버려진 데모인지 알 수가 없다. 그래서 로그인을 떼기로 정할 때, 이 공유 기록은 빼지 않기로 같이 정했다. 익명 사용자 하나에 모두의 디깅이 쌓이게 두면, 들어온 사람은 남들이 따라간 음악 굴을 먼저 본다. 로그인이 사라지며 잃은 “사용자가 존재한다는 증거”를 공유 기록으로 대신 세운 것이다. 로그인 제거는 빼기만 한 작업이 아니었다.
돌아보며: 후퇴였을까
로그인을 떼고 기능을 덜어낸 건 후퇴 아닌가. OAuth부터 깔고 시작했는데 그걸 다 들어냈으니까.
후퇴가 아니었다. 정식 멀티유저는 애초에 개인에게 열린 적 없는 문이었고, 나는 그 문을 두드리는 대신 다른 길로 나갔다. 결과적으로 지금 이 앱은 로그인이 있던 때보다 더 많은 사람에게 열려 있다.
남은 건 코드 2,900줄의 삭제가 아니라 질문을 뒤집는 법이다. “막힌 걸 어떻게 뚫지”가 아니라 “막힌 게 뭐고 그게 꼭 필요한가”를 물었더니, 알고 보니 필요 없던 건 로그인 쪽이었다. 법인도 25만 MAU도 없는 개인에게 멀티유저의 문은 닫혀 있지만, 공개 데이터만 쓰는 도구라면 로그인을 통째로 빼서 우회할 수 있다. redirect URI 디버깅으로는 안 보이는 자리에 적힌 사실이다. 개인이 이 플랫폼 위에서 만들 수 있는 범위는, 내가 코드를 잘 짜는지와 무관하게 바깥에서 먼저 정해져 있었다.