Skip to content

fix(planning): require signed workspace authority on all routes - #168

Merged
github-actions[bot] merged 9 commits into
mainfrom
fix/planning-trusted-workspace-authority-mainline
Aug 10, 2026
Merged

fix(planning): require signed workspace authority on all routes#168
github-actions[bot] merged 9 commits into
mainfrom
fix/planning-trusted-workspace-authority-mainline

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Security outcome

Replace conflicted PR #160 with the same bounded fix rebuilt from current protected main (563fa9851a0ae4232144c65d949d82e1fcb28154). Goal, project and task create/list routes derive workspace ownership from the short-lived signed life-os.workspace.v1 context already used by planning search and durable Today.

Preservation proof

The current-main replacement has exactly the four intended semantic deltas: CHANGELOG.md, apps/planning-service/src/main.ts, apps/planning-service/src/planning-controller-authority.test.ts, and docs/research/2026-08-10-planning-workspace-authority.md. The production/test/research contents are preserved from #160; the changelog is reconciled with current protected-main calendar disconnect and fail-closed Today entries.

Test-first contract

The retained RED source contract requires zero bare x-workspace-id decorators, no legacy requireWorkspaceId helper, and all nine workspace-scoped Planning routes (search, Today GET/PUT, six Goal/Project/Task operations) to bind and verify the signed workspace/issued-at/signature context. Existing http-boundary.test.ts independently covers fresh, stale, future, malformed, forged and unconfigured verifier evidence.

Implementation

  • removes BadRequestException and the legacy bare-workspace helper;
  • verifies signed workspace context before all six Goal/Project/Task domain calls;
  • preserves path/body IDs as locators and existing tenant-scoped repository predicates;
  • does not alter search, durable Today, current calendar disconnect, or Gateway Today fail-closed behavior.

Merge gate

Merge only after the unchanged exact head passes Planning tests/typecheck/build, configured owned-code coverage/docstrings, CI, AppGuardrail, SAST Semgrep, Security Scan, Commercial Readiness, all current review findings, and current-live-base compatibility without administrative bypass.

Supersedes #160. Closes #158 when integrated.

Summary by CodeRabbit

  • 보안

    • 목표, 프로젝트, 작업 생성·조회 기능이 서명된 작업공간 컨텍스트를 통해 권한을 확인하도록 강화되었습니다.
    • 클라이언트가 임의로 지정한 작업공간 헤더만으로는 접근할 수 없습니다.
  • 문서

    • 계획 기능의 작업공간 권한 검증 기준과 보안 참조 자료가 추가되었습니다.
  • 테스트

    • 작업공간 범위 라우트가 신뢰할 수 있는 서명 컨텍스트를 사용하는지 검증하는 테스트가 추가되었습니다.

@coderabbitai

coderabbitai Bot commented Aug 10, 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: 15 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

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: dc26b84e-f8fc-4401-a7f3-caeacfaa7f6f

📥 Commits

Reviewing files that changed from the base of the PR and between 9515275 and 7cc0f9d.

📒 Files selected for processing (1)
  • apps/planning-service/src/planning-controller-authority.test.ts
📝 Walkthrough

Walkthrough

Planning 서비스의 목표·프로젝트·작업 생성 및 조회 라우트가 클라이언트 선택형 workspace 헤더 대신 서명된 life-os.workspace.v1 컨텍스트를 사용합니다. 컨트롤러 계약 테스트와 보안 추적 문서도 추가되었습니다.

Changes

Planning workspace authority

Layer / File(s) Summary
서명된 workspace 컨텍스트 적용
apps/planning-service/src/main.ts
6개 생성·조회 라우트가 3개의 서명 컨텍스트 헤더를 검증합니다. 검증된 workspace ID를 서비스 호출에 사용합니다. 기존 x-workspace-id 검증과 requireWorkspaceId를 제거했습니다.
권한 계약 검증
apps/planning-service/src/planning-controller-authority.test.ts
9개 workspace 범위 라우트가 trusted workspace 헤더와 requireTrustedWorkspaceContext를 사용하는지 검사합니다.
보안 기록 갱신
CHANGELOG.md, docs/research/2026-08-10-planning-workspace-authority.md
서명된 단기 workspace 컨텍스트 요구사항과 기존 도메인·저장소 범위 검사를 기록합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PlanningController
  participant requireTrustedWorkspaceContext
  participant PlanningService
  PlanningController->>requireTrustedWorkspaceContext: 서명된 workspace 헤더 전달
  requireTrustedWorkspaceContext-->>PlanningController: 검증된 workspace ID 반환
  PlanningController->>PlanningService: workspace ID와 라우트 데이터 전달
  PlanningService-->>PlanningController: 목표, 프로젝트 또는 작업 반환
Loading

Possibly related issues

  • ContextualWisdomLab/life-os 161번 이슈: 다른 workspace 범위 컨트롤러에서 동일하게 클라이언트 선택형 x-workspace-id 권한을 서명된 workspace 컨텍스트로 대체합니다.

Possibly related PRs

  • ContextualWisdomLab/life-os#160: 동일한 Planning 라우트, 테스트, 문서에 서명된 workspace 컨텍스트 권한을 적용합니다.
  • ContextualWisdomLab/life-os#127: apps/planning-service/src/main.ts의 Planning 라우트에 동일한 서명 컨텍스트 검증을 적용합니다.
  • ContextualWisdomLab/life-os#113: gateway 서명 workspace 컨텍스트의 HMAC 키 순환 구현을 변경하며, 본 변경은 해당 컨텍스트 계약을 사용합니다.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed 6개 대상 라우트가 서명된 life-os.workspace.v1 컨텍스트를 사용하며 레거시 헤더와 헬퍼를 제거해 이슈 #158의 핵심 요구를 충족합니다.
Out of Scope Changes check ✅ Passed 코드, 테스트, 문서, 변경 로그는 모두 서명된 workspace 권한 강화와 이슈 #158의 검증 범위에 포함됩니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 모든 Planning 라우트에 서명된 workspace 권한을 요구하도록 변경한 PR의 핵심 내용을 정확하고 간결하게 설명합니다.
✨ 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 fix/planning-trusted-workspace-authority-mainline

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

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

🤖 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/planning-service/src/planning-controller-authority.test.ts`:
- Around line 20-32: Extend the tests in the PlanningController workspace
authority contract to execute every Goal, Project, and Task route rather than
only counting source tokens. Verify valid signed workspace contexts pass
trustedWorkspaceId to the service, while missing, expired, future-dated,
tampered, malformed, and secret-unconfigured contexts are rejected before any
service call; retain the existing legacy-header coverage.
🪄 Autofix

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: 0674605f-adc3-4e1b-a4ce-ae6418be49a4

📥 Commits

Reviewing files that changed from the base of the PR and between c9c5502 and 9515275.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • apps/planning-service/src/main.ts
  • apps/planning-service/src/planning-controller-authority.test.ts
  • docs/research/2026-08-10-planning-workspace-authority.md

Comment thread apps/planning-service/src/planning-controller-authority.test.ts Outdated
@github-actions
github-actions Bot merged commit 5a53452 into main Aug 10, 2026
38 checks passed
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.

Replace legacy client-selected planning ownership with signed workspace authority

1 participant