Skip to content

feat(identity): add secure OAuth HTTP boundary - #22

Merged
seonghobae merged 13 commits into
mainfrom
feat/oauth-http-boundary
Aug 3, 2026
Merged

feat(identity): add secure OAuth HTTP boundary#22
seonghobae merged 13 commits into
mainfrom
feat/oauth-http-boundary

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Begins issue #18 with the browser-facing security boundary required before provider callback orchestration.

Included

  • bounded, duplicate-rejecting opaque Cookie parsing
  • strict OAuth callback query parsing with no arbitrary redirect input
  • secure browser-binding and application-session cookie serialization
  • fixed HTTPS post-login destination
  • credential-free RFC 9457-compatible problem bodies
  • authorization-start coordination over existing state, PKCE, nonce, and transaction primitives
  • token-free session introspection and idempotent server-side logout
  • unit coverage and an implementation plan for the subsequent production controller/callback slice

Scope boundary

This PR does not yet expose production NestJS callback endpoints or implement Google JWKS verification, provider HTTP transport, or account provisioning orchestration. Those remain in issue #18 and are explicitly documented as the next slice.

Verification

Do not merge until CI, SAST Semgrep, Security Scan, AppGuardrail, Commercial Readiness, CodeRabbit, and all review feedback pass on the exact current head.

Refs #18.

Summary by CodeRabbit

  • 새로운 기능

    • OAuth 로그인 시작, 세션 조회, 로그아웃 기능을 추가했습니다.
    • 로그인 후 안전한 고정 리다이렉트를 지원합니다.
    • 브라우저 바인딩과 보안 쿠키를 통해 인증 세션을 보호합니다.
    • 인증 상태를 공개 가능한 세션 정보로 제공합니다.
  • 보안 및 오류 처리

    • OAuth 콜백, 쿠키, 리다이렉트 주소를 엄격히 검증합니다.
    • 표준화된 오류 응답을 제공하며, 로그아웃 시 세션 쿠키를 확실히 삭제합니다.
  • 테스트 및 문서

    • 인증 경계와 예외 상황에 대한 테스트와 관련 계획 문서를 추가했습니다.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@seonghobae, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 11a8b5e9-6929-44b6-8d31-34c2db9f65f8

📥 Commits

Reviewing files that changed from the base of the PR and between f2e8c35 and 3cd277b.

📒 Files selected for processing (3)
  • apps/identity-service/src/oauth-http-application.ts
  • apps/identity-service/src/oauth-http-boundary.test.ts
  • apps/identity-service/src/oauth-http-boundary.ts
📝 Walkthrough

Walkthrough

OAuth HTTP 경계와 애플리케이션 계층을 추가했습니다. 쿠키와 콜백 입력을 검증하고, OAuth 시작·세션 조회·로그아웃·고정 리디렉션을 처리합니다. 관련 테스트, 계획 문서와 포맷 검사 대상도 추가했습니다.

Changes

OAuth HTTP 경계

Layer / File(s) Summary
경계 계약과 보안 처리
apps/identity-service/src/oauth-http-boundary.ts, apps/identity-service/src/oauth-http-boundary.test.ts
쿠키와 OAuth 콜백 쿼리를 엄격하게 검증합니다. 보안 쿠키, 브라우저 바인딩, 세션 쿠키 삭제, HTTPS 고정 리디렉션, 세션 공개 뷰와 RFC 9457 문제 응답을 추가했습니다.
OAuth 애플리케이션 흐름
apps/identity-service/src/oauth-http-application.ts, apps/identity-service/src/oauth-http-boundary.test.ts
OAuthHttpApplication이 제공자 설정을 검증하고 OAuth 인증 시작, 세션 조회, 로그아웃과 로그인 후 리디렉션을 조정합니다. 테스트는 PKCE, 브라우저 바인딩 재사용, bearer token 비노출과 멱등 로그아웃을 검증합니다.
범위 문서와 포맷 검사
docs/superpowers/plans/2026-08-03-oauth-http-boundary-slice.md, package.json
OAuth HTTP 경계의 범위와 후속 작업을 문서화했습니다. 관련 소스, 테스트와 계획 문서를 format:check 대상에 추가했습니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • ContextualWisdomLab/life-os#18 — 인증 시작, 세션 조회, 고정 리디렉션, 보안 쿠키와 로그아웃 요구사항을 구현한 변경입니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 보안 OAuth HTTP 경계 추가라는 변경의 주요 내용을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/oauth-http-boundary

Comment @coderabbitai help to get the list of available commands.

Comment thread .github/workflows/format-oauth-http-boundary.yml Fixed

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/identity-service/src/oauth-http-application.ts (1)

47-60: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

알 수 없는 provider 값에 대한 방어가 없습니다.

requireProviderConfigurationconfiguration.providers[provider]가 없을 때를 확인하지 않습니다. provider가 실제로 'google' 또는 'github'가 아니면 providerConfigurationundefined가 되고, 다음 줄의 providerConfiguration.clientId가 처리되지 않은 TypeError를 던집니다.

beginAuthorization(82-96번째 줄)은 이 함수를 런타임 provider 인자로 호출합니다. 생성자 호출(75-76번째 줄)은 고정 리터럴만 사용하므로 안전하지만, beginAuthorization은 향후 컨트롤러 슬라이스에서 라우트 파라미터를 그대로 받을 가능성이 높은 지점입니다. 현재 방어가 없으면 잘못된 provider 값이 자격 증명 없는 RFC 9457 문제 응답 대신 처리되지 않은 예외로 이어집니다.

🛡️ 제안하는 수정
 function requireProviderConfiguration(
   provider: IdentityProvider,
   configuration: OAuthHttpApplicationConfiguration,
 ): OAuthProviderStartConfiguration {
   const providerConfiguration = configuration.providers[provider];
+  if (!providerConfiguration) {
+    throw new Error('OAuth provider is not supported');
+  }
   const clientId = providerConfiguration.clientId.trim();

Also applies to: 82-96

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/identity-service/src/oauth-http-application.ts` around lines 47 - 60,
Update requireProviderConfiguration to validate that
configuration.providers[provider] exists before accessing clientId, and reject
unknown provider values with the established handled error or RFC 9457
problem-response path used by beginAuthorization. Preserve the existing client
ID trimming and redirect URI validation for configured providers.
apps/identity-service/src/oauth-http-boundary.ts (1)

108-124: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

일반 객체를 쿠키 맵으로 사용하면 프로토타입 체인 속성과 충돌합니다.

cookies는 일반 객체 리터럴({})입니다. 쿠키 이름이 constructor, toString, __proto__ 같은 Object.prototype 속성명과 같으면, cookies[name] !== undefined 검사가 항상 참이 되어 정상적인 첫 쿠키도 중복으로 오판하고 거부됩니다. COOKIE_NAME_PATTERN은 이런 이름을 허용하므로 실제로 발생할 수 있습니다.

현재는 이 오판이 failInvalidCookie()로 이어져 실제 프로토타입 오염까지는 차단되지만, 이는 우연한 방어이며 향후 로직 변경 시 위험해질 수 있습니다. Object.create(null)을 사용하거나 Object.prototype.hasOwnProperty.call(cookies, name)으로 중복 검사를 하십시오.

🛡️ 제안하는 수정
-  const cookies: Record<string, string> = {};
+  const cookies: Record<string, string> = Object.create(null);
   for (const segment of header.split(';')) {
     const separator = segment.indexOf('=');
     if (separator <= 0) {
       return failInvalidCookie();
     }
     const name = requireCookieName(segment.slice(0, separator).trim());
     const value = segment.slice(separator + 1).trim();
     if (
       !value ||
       !OPAQUE_COOKIE_VALUE_PATTERN.test(value) ||
-      cookies[name] !== undefined
+      Object.prototype.hasOwnProperty.call(cookies, name)
     ) {
       return failInvalidCookie();
     }
     cookies[name] = value;
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/identity-service/src/oauth-http-boundary.ts` around lines 108 - 124,
Update the cookies map and duplicate-name check in the cookie parsing loop to
avoid prototype-chain collisions for names such as constructor, toString, and
__proto__; use a null-prototype object or an own-property check while preserving
rejection of actual duplicate cookie names.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/identity-service/src/oauth-http-boundary.ts`:
- Around line 94-137: Update readOpaqueCookie to scan cookie segments directly
and skip unrelated cookie names, applying OPAQUE_COOKIE_VALUE_PATTERN validation
only to the requested cookie before returning it. Preserve invalid-header
handling for malformed structure and invalid target values, and add coverage for
headers containing unrelated RFC 6265 cookie values such as periods, equals
signs, or percent-encoding.

---

Nitpick comments:
In `@apps/identity-service/src/oauth-http-application.ts`:
- Around line 47-60: Update requireProviderConfiguration to validate that
configuration.providers[provider] exists before accessing clientId, and reject
unknown provider values with the established handled error or RFC 9457
problem-response path used by beginAuthorization. Preserve the existing client
ID trimming and redirect URI validation for configured providers.

In `@apps/identity-service/src/oauth-http-boundary.ts`:
- Around line 108-124: Update the cookies map and duplicate-name check in the
cookie parsing loop to avoid prototype-chain collisions for names such as
constructor, toString, and __proto__; use a null-prototype object or an
own-property check while preserving rejection of actual duplicate cookie names.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 97d9d739-4279-475e-864a-c95d5e173547

📥 Commits

Reviewing files that changed from the base of the PR and between 0efb6d1 and f2e8c35.

📒 Files selected for processing (5)
  • apps/identity-service/src/oauth-http-application.ts
  • apps/identity-service/src/oauth-http-boundary.test.ts
  • apps/identity-service/src/oauth-http-boundary.ts
  • docs/superpowers/plans/2026-08-03-oauth-http-boundary-slice.md
  • package.json

Comment thread apps/identity-service/src/oauth-http-boundary.ts

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants