Skip to content

Quickstart (5분)

관리형 IdP https://1pass.dev 기준. 자체 호스팅은 self-hosting.

사전 준비

bash, curl, openssl, python3.

1. 계정 만들기

https://start.1pass.dev/console/signup → 이메일 + 비밀번호.

앱(RP) 등록 전 이메일 인증 필요

개발자 콘솔에서 앱(RP)을 등록하려면 먼저 이메일 인증이 필요합니다. 가입 후 인증 메일의 링크를 클릭하거나 콘솔 /account 에서 재발송하세요. 미인증 시 등록이 차단됩니다. → 앱 등록 가이드 · 사전 요건

2. OAuth 앱 등록

https://start.1pass.dev/developer/applications/new:

  • Redirect URI: http://localhost:4000/auth/callback
  • Client type: Confidential (백엔드 보유) / Public (모바일·SPA·CLI 단독)

저장 직후 client_secret한 번만 표시 — 즉시 .env 저장. 분실 시 재발급만 가능.

앱 상세 → Scopes 관리openid, profile:basic, email 활성화.

id_token 이 필요하면 openid 필수

신원을 id_token 페이로드에서 직접 읽는 패턴(SPA·서버리스에서 흔함)은 openid scope 가 있어야 합니다. 없으면 token 응답에 id_token 이 빠지고, 신원은 userinfo 로만 조회할 수 있습니다. profileprofile:basic 의 alias 지만 등록·요청은 profile:basic 로 통일하세요. — Scope 레퍼런스

Client type 결정: Public vs Confidential.

3. 환경 변수

bash
export LOGI="https://api.1pass.dev"
export CLIENT_ID="logi_..."
export CLIENT_SECRET="..."         # Public client 면 생략
export REDIRECT="http://localhost:4000/auth/callback"

끝점 발견: $LOGI/.well-known/openid-configuration.

4. PKCE 페어 생성

bash
VERIFIER=$(openssl rand -hex 32)

CHALLENGE=$(printf '%s' "$VERIFIER" \
  | openssl dgst -sha256 -binary \
  | python3 -c 'import sys,base64; print(base64.urlsafe_b64encode(sys.stdin.buffer.read()).rstrip(b"=").decode())')

echo "verifier  = $VERIFIER"
echo "challenge = $CHALLENGE"

5. Authorization Code 받기

bash
open "$LOGI/oauth/authorize?\
client_id=$CLIENT_ID&\
redirect_uri=$REDIRECT&\
response_type=code&\
scope=openid+profile:basic+email&\
state=random_xyz&\
code_challenge=$CHALLENGE&\
code_challenge_method=S256"

http://localhost:4000/auth/callback?code=...&state=random_xyz. code 값 복사.

로그인 화면에 특정 방법만 노출하기

사내에서 Google Workspace 만 쓰는 등 특정 로그인 방법만 보여주고 싶다면 authorize URL 에 provider 파라미터를 추가하세요 (예: &provider=google → "Google로 계속" 버튼만 노출). 콘솔에서 앱 단위로 강제할 수도 있습니다. 자세한 동작은 로그인 방법 제한 참조.

6. Token 교환

bash
CODE="복사한_code"

curl -s -X POST "$LOGI/oauth/token" \
  -d grant_type=authorization_code \
  -d code=$CODE \
  -d redirect_uri=$REDIRECT \
  -d code_verifier=$VERIFIER \
  -d client_id=$CLIENT_ID \
  -d client_secret=$CLIENT_SECRET

Public client: -d client_secret=... 줄 제거. 보내면 invalid_client 거절.

bash
curl -s -X POST "$LOGI/oauth/token" \
  -d grant_type=authorization_code \
  -d code=$CODE \
  -d redirect_uri=$REDIRECT \
  -d code_verifier=$VERIFIER \
  -d client_id=$CLIENT_ID

응답:

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "refresh_token": "DWxB...",
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9...",
  "scope": "openid profile:basic email"
}

id_tokenopenid scope 를 요청했을 때만 포함됩니다.

7. 신원 조회 — 두 가지 방법

7a. id_token 에서 sub 읽기 (서명 재검증 불요)

/oauth/token 응답을 TLS 로 직접 받았다면 id_token 페이로드의 sub 를 바로 신뢰할 수 있습니다. 단 id_token 에는 sub 등 OIDC 표준 claim 만 있고 email·name 은 없습니다.

bash
echo "$ID_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool
# → {"iss":"logi","sub":"1","aud":"logi_...","exp":...,"iat":...,"at_hash":"..."}

토큰 엔드포인트에서 직접 받았다면 서명 재검증은 선택

같은 백엔드 요청에서 /oauth/token 으로부터 TLS 로 직접 수신한 id_token 은 페이로드를 신뢰해도 됩니다(OIDC §3.1.3.7 #6 예외). 서명(JWKS) 검증은 id_token 이 신뢰할 수 없는 경로(front-channel, 저장 후 재사용, 중계)로 들어올 때만 필수입니다. → JWKS 검증

7b. userinfo 로 프로필(email·name) 받기

email·name 등 프로필은 id_token 에 없으므로 access_token 으로 userinfo 를 호출합니다.

bash
ACCESS_TOKEN="위_응답의_access_token"
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" "$LOGI/oauth/userinfo"
# → {"sub":"1","nickname":"길동","name":"홍길동","email":"user@example.com","email_verified":true}

트러블슈팅

  • invalid_client: Public client 가 client_secret 전송 — 줄 제거.
  • PKCE: S256 필수, plain 거절. redirect_uri 는 https / 127.0.0.1 / localhost / custom-scheme 만 허용.

다음 단계

Identity가 제품의 신뢰를 만듭니다.