앱 사용자 인증
app-auth 카테고리의 API 작업 6개를 다룹니다.
| 메서드 | 경로 | 설명 |
|---|---|---|
| GET | /v1/orgs/{orgSlug}/projects/{projectName}/auth | 최종 사용자 인증 상태 (runlot auth) |
| POST | /v1/orgs/{orgSlug}/projects/{projectName}/auth | 인증을 켭니다 (runlot deploy가 "auth": true 선언을 읽은 뒤 이를 호출합니다) |
| PATCH | /v1/orgs/{orgSlug}/projects/{projectName}/auth | 설정을 변경합니다 (runlot auth set) |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/auth | 인증을 끕니다 (runlot auth delete) |
| PUT | /v1/orgs/{orgSlug}/projects/{projectName}/auth/providers/{provider} | 소셜 제공자를 등록하거나 교체합니다 (runlot auth provider set) |
| DELETE | /v1/orgs/{orgSlug}/projects/{projectName}/auth/providers/{provider} | 로그인 제공자 연결을 해제합니다 (runlot auth provider rm) |
GET /v1/orgs/{orgSlug}/projects/{projectName}/auth
허용 여부, 설정 여부, 등록된 제공자, 콜백을 가리킬 호스트 (docs/auth.md §9).
구독자 테이블은 이 API의 일부가 아닙니다. 사용자 정보는 프로젝트 Postgres의 runlot_auth 스키마에 저장되며(docs/auth.md §6), CP는 이 테이블을 조회하지 않습니다. 현재 사용자 목록은 워커의 env.auth.users.*와 runlot pg shell을 통해 확인할 수 있습니다.
providers는 클라이언트 id만 담고 있습니다. 클라이언트 시크릿은 봉인되어 있으며 어떤 응답에도 노출되지 않습니다(시크릿 노출면 규칙).
viewer 이상 — 이 앱에 로그인 기능이 있는지는 org의 누구나 알 수 있어야 하는 사실입니다.
operationId getAuth
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | Auth 상태 | AuthStatus |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core — cp-core에 연결되지 않음 | Error |
POST /v1/orgs/{orgSlug}/projects/{projectName}/auth
이 요청은 멱등입니다 — 두 번 호출해도 설정과 로그인 제공자는 변하지 않습니다. 활성화 여부를 나타내는 유일한 표현이 레코드의 존재 여부이므로(migration 0024), "켜져 있지만 비활성화된" 상태는 없습니다.
데이터베이스가 필요합니다. 데이터베이스가 없으면 409 database_required를 반환합니다. 구독자 테이블은 프로젝트 DB 안에 있으므로(docs/auth.md §1), auth만 활성화하면 워커는 시작 시 필요한 테이블 없이 실행됩니다. 이런 이유로 "auth": true를 선언하면 데이터베이스도 함께 활성화되며, 배포는 이 순서대로 부여하므로 이 409는 배포 경로에서는 발생하지 않습니다.
활성화되면 노드는 다음 수렴 시점에 auth 시스템 워커를 소켓의 진입 서비스로 시작합니다. env.db, env.storage와 마찬가지로 재배포는 필요하지 않습니다. 테이블 초기화는 멱등이므로 두 번 활성화해도 한 번만 수행됩니다.
요청 본문은 없습니다. 설정은 기본값(AuthSettings의 기본값)에서 시작하며, 변경은 PATCH로 수행합니다.
member 이상. auth.grant로 감사 기록됩니다.
operationId grantAuth
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 부여 상태(이미 있었다면 기존 값) | AuthStatus |
| 403 | — | — |
| 404 | — | — |
| 409 | database_required — 이 프로젝트에는 데이터베이스가 없습니다. runlot.json에 "database": true를 설정하고 배포하세요. | Error |
| 503 | no_core | Error |
PATCH /v1/orgs/{orgSlug}/projects/{projectName}/auth
부분 업데이트입니다. 보낸 필드만 변경되고 나머지는 그대로 유지됩니다. UI가 스위치 하나만 바뀌어도 브랜드 설정 세 개를 매번 모두 전송한다면, 두 사용자가 같은 설정을 편집할 때 나중 저장이 이전 저장을 덮어쓸 수 있습니다.
사용 설정이 존재하지 않으면 404 not_granted를 반환합니다. 설정 값은 사용 설정 레코드와 함께 저장되므로 설정만 미리 저장할 수는 없습니다.
sessionDays는 세션 테이블의 크기도 결정하는 설정입니다(docs/auth.md §13 — 150 MB 한도 내로 유지됩니다).
member 이상이 필요합니다. auth.settings로 감사 기록됩니다.
operationId updateAuthSettings
요청 본문: application/json · AuthSettingsPatch
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 변경된 상태 | AuthStatus |
| 400 | — | — |
| 403 | — | — |
| 404 | not_granted — 이 프로젝트에는 auth가 없습니다. 프로젝트 자체가 존재하지 않을 때는 이 코드가 아니라 not_found가 반환됩니다. | Error |
| 503 | no_core | Error |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/auth
구독자 데이터는 삭제되지 않습니다. runlot_auth 테이블은 프로젝트 DB에 그대로 남습니다(docs/auth.md §9) — 데이터는 DB에 속하며, 삭제는 runlot pg가 할 일입니다. 다시 켜면 이전과 같은 사람들이 그대로 로그인할 수 있습니다.
다음 수렴부터 auth 시스템 워커는 내려가고, /__runlot/auth/*는 사용자 워커로 그대로 통과합니다 — 해당 경로에 라우트가 없으면 404가 됩니다.
비활성화도 멱등입니다. auth가 활성화되어 있지 않았어도 204를 반환합니다.
admin 이상 — 활성화에는 member면 충분하지만, 비활성화하면 로그인해 있는 모든 사용자가 로그아웃됩니다. auth.revoke로 감사 기록됩니다.
operationId revokeAuth
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 분리됨 | — |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |
PUT /v1/orgs/{orgSlug}/projects/{projectName}/auth/providers/{provider}
프로젝트는 자체 OAuth 앱을 등록합니다. 동의 화면, 심사, 개인정보 처리가 모두 앱 소유자의 책임이므로 공유되는 플랫폼 앱은 없습니다(docs/auth.md §12).
제공자에 등록할 콜백 URL은 호스트별로 다릅니다: https://<host>/__runlot/auth/callback/<provider>. 호스트 목록은 AuthStatus.hosts에 있습니다.
clientSecret은 project_secrets와 동일한 DEK와 동일한 AAD로 봉인되며(예약된 접두사 auth/<provider>로 명명됨), 이후 어떤 응답에도 다시 나타나지 않습니다. 로테이션도 동일한 PUT을 사용합니다 — 멱등이므로 재시도해도 안전합니다.
admin 이상이 필요합니다 — 이는 자격 증명입니다. auth.provider.set으로 감사 기록됩니다(시크릿 자체는 기록되지 않습니다).
operationId setAuthProvider
요청 본문: application/json · AuthProviderPut
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 200 | 변경된 상태 | AuthStatus |
| 400 | invalid_provider — 이름이 github, google, kakao 범위를 벗어나거나 clientId/clientSecret이 비어 있습니다. | Error |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |
DELETE /v1/orgs/{orgSlug}/projects/{projectName}/auth/providers/{provider}
해당 로그인 제공자만 사용하던 사용자는 더 이상 로그인할 수 없게 됩니다. 사용자 레코드는 남아 있으며, identities의 해당 항목만 삭제됩니다. 다시 등록하면 동일한 계정으로 로그인이 복원됩니다.
존재하지 않는 로그인 제공자를 삭제해도 204를 반환합니다.
admin 이상. auth.provider.delete를 감사합니다.
operationId deleteAuthProvider
| 상태 코드 | 설명 | 응답 본문 |
|---|---|---|
| 204 | 분리됨 | — |
| 403 | — | — |
| 404 | — | — |
| 503 | no_core | Error |