Skip to content

fix(security): bind invite acceptance to invited identity - #593

Open
seonghobae wants to merge 22 commits into
developfrom
fix/invite-identity-binding-592
Open

fix(security): bind invite acceptance to invited identity#593
seonghobae wants to merge 22 commits into
developfrom
fix/invite-identity-binding-592

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Fixes #592.

Focused security hotfix from protected develop@2c328875e00e86537df3e965170be80532571cad.
Exact contributor head: a7bc39d16fe5240832ef08f0ee80e9c64dea7181.

Verified protected defects

Protected develop exposes pending invite bearer tokens in GET /api/orgs/:id/members and allows any authenticated token-holder to redeem POST /api/invites/:token/accept, enabling cross-identity privilege acquisition.

The existing users.email TEXT UNIQUE rule is case-sensitive, so historical accounts that differ only by email case can coexist. A simple lowercased equality check is therefore insufficient: either colliding account could otherwise redeem the same canonical invite.

The structured request logger also persisted raw secret-bearing paths. Current-head review further proved that endpoint-shaped regex redaction was insufficient because malformed/trailing paths such as /api/invites/TOKEN/accept/extra, /api/invites/TOKEN/accept/, and /api/shared/TOKEN/extra could still copy live bearer material into durable logs.

TDD repair

tests/api/invite-identity-security.test.mjs covers:

  • a legitimate viewer never receives a pending invite token;
  • a different authenticated account holding the token receives the generic 404 {"error":"invalid or used invite"} and gains no membership;
  • two historical accounts with the same canonical email are both rejected for that ambiguous invite;
  • a unique historical mixed-case identity can accept exactly once and receives the invited role;
  • replay and missing tokens preserve protected develop's existing fail-closed 404 behavior;
  • invite/share bearer tokens are redacted from structured request logs on valid, trailing-slash, and extra-segment malformed paths; and
  • ordinary non-secret paths remain intact for operational triage.

RED sequencing is retained in predecessor test-only commits rather than promoted as current passing evidence: canonical-account collision in bebc2074a276eafc62de6e36134ae91d7abe2d0c, and request-log redaction strengthening in 2333d32874d3ab10a83071e075d4e39f2daf6b60 / d0e1a732d63d2da0c9a2b987ea00a556b029bafc. Their hosted runs were cancelled by branch movement/concurrency, so only source/test sequencing is claimed from them.

The production repair on current head:

  • removes token from the pending-invite roster projection;
  • canonicalizes the invite email, loads at most two matching persisted user ids, and proceeds only when exactly one canonical account exists and its id equals the authenticated uid;
  • performs that check before member-limit checks, membership insertion, audit/delivery, or invite consumption;
  • preserves the generic invalid-invite response to avoid an identity oracle; and
  • redacts the secret-bearing third path segment for both api/invites and api/shared, preserving any suffix for operational route-shape visibility while removing the bearer value.

Fresh current-source verification confirms the latest malformed-path redaction finding is addressed on a7bc39d16fe5240832ef08f0ee80e9c64dea7181; all inline review threads are resolved. The latest informational review observation correctly notes that zero or multiple canonical-email matches fail closed and does not require a source change.

Current exact-head evidence boundary

For exact contributor head a7bc39d16fe5240832ef08f0ee80e9c64dea7181, GitHub currently reports terminal success for Dependency Review 33204300753, Fuzz 33204300875, OSV Scanner 33204301500, SAST Semgrep 33204301020, Security Scan 33204300744, Server Tests 33204300763, Required Noema Review 33204299303, Close Empty PR 33204299417, Required PR Review Merge Scheduler 33204299299, and the dynamic CodeQL/code-quality checks.

Those successful workflow conclusions are not all promoted to merge-authorizing exact-contributor-checkout evidence. Repository Server Tests still requires the exact-head checkout/attestation correction owned by ScopeWeave PR #523 before a green result can prove the tested checkout contract rather than only the PR-associated run. Central reusable exact-head evidence defects remain owned by the existing .github repair/control lanes.

Two inherited required gates are explicitly non-passing on this exact head: Required Strix Security Scan run 33204299340 completed cancelled, and Required OpenCode Review run 33204299375 completed failure. Required Noema is exact-head success, but no formal review submission is a qualifying independent current-head APPROVED review.

Lane history

This focused lane was previously closed only because #589 carried the same behavior. #589 is closed unmerged while protected develop still has the defect, so #593 remains the narrow current owning lane. #587 does not contain this lane's invite/share request-log bearer redaction, so #593 is not semantically superseded.

Merge boundary

Do not merge or enable auto-merge until the unchanged exact contributor head remains reconciled to live protected develop, all applicable repository and inherited required checks are substantively terminal-passing under corrected evidence contracts, current valid unresolved review findings are zero, and live branch protection/rulesets have the required qualifying independent current-head approval. Pending, queued, skipped-required, cancelled, absent, neutral-required, failed, stale, predecessor, synthetic-only, status-only, author-only, model-only, rate-limited, or infrastructure-only evidence is non-passing.

Summary by CodeRabbit

  • 보안 개선

    • 초대 및 공유 링크의 비밀 토큰이 요청 로그에 노출되지 않도록 보호합니다.
    • 조직 구성원 목록에서 초대 토큰이 표시되지 않습니다.
    • 초대 수락 시 초대 이메일과 인증 사용자 정보가 일치하는 경우에만 처리됩니다.
    • 등록되지 않은 계정에는 초대가 발송되지 않으며, 초대 생성이 409 오류로 거부됩니다.
    • 유효하지 않거나 일치하지 않는 초대 요청은 404 오류로 처리됩니다.
    • Unicode 이메일 주소의 대소문자 및 표기 차이를 올바르게 처리합니다.
  • 문서

    • Cloud 모드의 최소 Node.js 버전 요구 사항을 23.5+로 업데이트했습니다.
    • 웹훅 검증 헤더 문서를 수정했습니다.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

요청 로그에서 초대 및 공유 토큰을 :token으로 치환합니다. 조직 구성원 목록에서 초대 토큰을 제거합니다. 초대 수락은 정규화된 이메일과 현재 인증 사용자가 고유하게 일치할 때만 허용합니다. Unicode 정규화와 관련 API 검증을 추가합니다.

Changes

초대 신원 및 토큰 보안

Layer / File(s) Summary
이메일 정규화 및 조회 흐름
server/email_identity.mjs, server/db.mjs, server/app.mjs
canonicalizeMailbox가 Unicode CaseFolding 매핑과 NFKC 정규화를 사용합니다. SQLite에 결정적 정규화 함수를 등록하고 기능 인덱스를 생성합니다. 초대 생성과 수락은 기존 계정의 정규화된 이메일을 확인합니다.
초대 보안 및 Unicode 회귀 검증
server/app.mjs, tests/api/invite-identity-security.test.mjs, tests/api/smoke.mjs
토큰 로그 노출을 방지하고 대기 중 초대에서 token을 제거합니다. API 테스트는 계정 기반 초대, 경로 redaction, Unicode 매칭, 잘못된 인증 신원 거부, 사용되었거나 존재하지 않는 초대의 404 응답을 검증합니다.
API 계약 및 실행 환경 검증
package.json, tests/unit/coverage-script-contract.test.mjs, docs/api.md, README.md
API 문서에 계정 기반 초대 계약과 webhook 헤더 이름을 반영합니다. API 테스트 실행 목록과 c8 계측 대상을 갱신합니다. Node.js 23.x 최소 버전을 23.5.0으로 변경합니다.

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

Merge Risk: 🟡 Moderate · up to 1aec9

The change prevents token-only invite redemption and improves secret-path logging, but an invite can still be redeemed by a replacement account after the original invited account is deleted, and equivalent Cherokee email forms may be treated inconsistently. The current head also lacks all passing required checks and qualifying approval, so it is not merge-ready.

Suggested reviewers: cursoragent

Sequence Diagram(s)

sequenceDiagram
  participant Client as API 요청자
  participant App as server/app.mjs
  participant Database as SQLite 사용자 및 초대 데이터
  participant Logs as 요청 로그

  Client->>App: 토큰 포함 요청 전송
  App->>Logs: 토큰을 :token으로 치환한 경로 기록
  Client->>App: 초대 수락 요청 전송
  App->>Database: 정규화 이메일과 인증 사용자 조회
  Database-->>App: 사용자 조회 결과 반환
  App-->>Client: 조건 충족 시 수락, 아니면 404
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 6 files. (3 skipped: 3… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 초대 수락을 초대된 계정에 연결하는 핵심 변경을 정확하고 간결하게 설명합니다. 이는 풀 리퀘스트의 주요 목적과 일치합니다.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 6 files. (3 skipped: 3 unsupported.)

✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/invite-identity-binding-592

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

Superseded by the established #589 security lane after exact-head comparison. #5892d39860 already carries the same executable #592 contract: viewer-visible roster responses strip pending invite bearer tokens; mismatched authenticated identities receive the generic invalid/used response before membership mutation; mixed-case intended identities can redeem once; replay is rejected. Its tests/api/invite-security.test.mjs covers the same attack chain, and #589 is already the review-bearing lane for this trust-boundary repair alongside its related protected security fixes. Keeping this Draft would duplicate the same product behavior and force avoidable conflict/restack against #589 without preserving a distinct buyer-visible capability. No code from this branch is being treated as merge evidence; #589 remains subject to fresh exact-head CI/review/security gates.

@seonghobae seonghobae closed this Aug 23, 2026
@seonghobae seonghobae reopened this Aug 25, 2026
@seonghobae
seonghobae marked this pull request as ready for review August 25, 2026 13:25
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 0 new potential issues.

Open in Devin Review

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Review-only request for exact head 0064af31cba25242075f24f25222e6b490c4891a against protected develop@2c328875e00e86537df3e965170be80532571cad. Bind any verdict to this exact head and live base. Re-verify canonical invitee uniqueness before mutation, pending-invite token non-disclosure, invite/share bearer-token path redaction in structured logs, legitimate mixed-case acceptance, attacker/collision rejection, replay behavior, and the fully resolved current review-thread set. Do not transfer predecessor-head, model-only, synthetic-merge, or status-only evidence into current approval.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Review-only request for exact current contributor head a7bc39d16fe5240832ef08f0ee80e9c64dea7181 against protected develop@2c328875e00e86537df3e965170be80532571cad. Bind any verdict to this exact head/base pair. Re-verify the invite-identity uniqueness boundary, pending-invite token non-disclosure, and invite/share bearer-token path redaction including trailing/extra path segments. All currently posted inline threads are resolved; do not transfer predecessor-head, synthetic-merge, status-only, author-only, or model-only evidence into a current approval.

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 0 new potential issues.

Devin Review

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please review exact current head 2ce9f1dab362ef208d1fc68e8c7b6df815f1b3b7 against protected develop@2c328875e00e86537df3e965170be80532571cad. Do not reuse predecessor-head evidence. All currently enumerated inline threads are resolved and the latest current-head Devin pass reported 0 new findings, but the required OpenCode check is fail-closed because no authenticated current-head verdict exists.

Verify from current source before issuing a SHA-bound verdict:

  • invite/share bearer-token redaction, including malformed/trailing/extra path suffixes;
  • unique authenticated identity binding before any membership/audit/delivery/invite-consumption mutation;
  • deterministic indexed canonical-user lookup and ambiguity rejection;
  • canonicalizeMailbox() as an identity policy for the entire email address, especially whether NFKC plus mappings such as final-sigma normalization and ß -> ss can conflate distinct legitimate mailbox identities or otherwise exceed ScopeWeave's intended email-identity contract; and
  • the exact current API regressions and database-expression-index behavior.

If the Unicode canonicalization policy is too broad or incomplete, identify the smallest standards-defensible identity rule and a realistic RED case rather than accepting an ad-hoc partial case-fold table.

@devin-ai-integration devin-ai-integration 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.

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

Devin Review found 0 new potential issues.

Devin Review

coderabbitai[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

OpenCode reviewed the current-head product diff. Coverage is a separate gate.

Changed files

  • README.md — repository behavior
  • package-lock.json — repository behavior
  • package.json — repository behavior
  • server/app.mjs — TypeScript or JavaScript runtime
  • server/db.mjs — TypeScript or JavaScript runtime
  • server/email_identity.mjs — TypeScript or JavaScript runtime
  • tests/api/invite-identity-security.test.mjs — regression suite
  • tests/unit/coverage-script-contract.test.mjs — regression suite

Changed behavior

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Repository file: README.md"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Repository file: README.md"]
  R1 --> V1["required checks"]
  Evidence --> S2["Repository file: package-lock.json"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: package-lock.json"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: package.json"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: package.json"]
  R3 --> V3["required checks"]
  Evidence --> S4["TypeScript/JavaScript: app.mjs (3 files)"]
  S4 --> I4["TypeScript or JavaScript runtime"]
  I4 --> R4["Review risk: TypeScript/JavaScript: app.mjs (3 files)"]
  R4 --> V4["package test plus coverage"]
  Evidence --> S5["Test: invite-identity-security.test.mjs"]
  S5 --> I5["regression suite"]
  I5 --> R5["Review risk: Test: invite-identity-security.test.mjs"]
  R5 --> V5["targeted test run"]
  Evidence --> S6["Test: coverage-script-contract.test.mjs"]
  S6 --> I6["regression suite"]
  I6 --> R6["Review risk: Test: coverage-script-contract.test.mjs"]
  R6 --> V6["targeted test run"]
Loading

Findings

No source-backed product finding is synthesized from the coverage gate. A coverage miss belongs in the status comment.

  • Head SHA: 27e581a7298b9faa309d9c838e1f5f05d3c0f355
  • Workflow run: 33232630124
  • Workflow attempt: 1
  • Coverage gate: failure

Review outcome

Coverage is a gate, not the review. This body reviews the changed product files.

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Repository file: README.md"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Repository file: README.md"]
  R1 --> V1["required checks"]
  Evidence --> S2["Repository file: package-lock.json"]
  S2 --> I2["repository behavior"]
  I2 --> R2["Review risk: Repository file: package-lock.json"]
  R2 --> V2["required checks"]
  Evidence --> S3["Repository file: package.json"]
  S3 --> I3["repository behavior"]
  I3 --> R3["Review risk: Repository file: package.json"]
  R3 --> V3["required checks"]
  Evidence --> S4["TypeScript/JavaScript: app.mjs (3 files)"]
  S4 --> I4["TypeScript or JavaScript runtime"]
  I4 --> R4["Review risk: TypeScript/JavaScript: app.mjs (3 files)"]
  R4 --> V4["package test plus coverage"]
  Evidence --> S5["Test: invite-identity-security.test.mjs"]
  S5 --> I5["regression suite"]
  I5 --> R5["Review risk: Test: invite-identity-security.test.mjs"]
  R5 --> V5["targeted test run"]
  Evidence --> S6["Test: coverage-script-contract.test.mjs"]
  S6 --> I6["regression suite"]
  I6 --> R6["Review risk: Test: coverage-script-contract.test.mjs"]
  R6 --> V6["targeted test run"]
Loading

@opencode-agent

opencode-agent Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

Coverage evidence did not pass, so approval is blocked. The formal pull-request review is the source-backed diff review, not this status comment.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Review exact current head d3937e7d8f15806bda2d98694d24ebd559c708ad only against protected develop@2c328875e00e86537df3e965170be80532571cad. Fresh exact-head required-workflow evidence shows coverage-evidence is terminal-success and every current inline review thread is resolved. Repository-owned Fuzz, Dependency Review, OSV Scanner, Server Tests, Security Scan, and SAST Semgrep runs are terminal-success on this PR-associated head, while required opencode-review failed solely because no authenticated APPROVED or CHANGES_REQUESTED OpenCode verdict exists for this SHA. Do not transfer the predecessor-head 27e581a7298b9faa309d9c838e1f5f05d3c0f355 COMMENTED review or its earlier coverage failure. Verify current changed source/tests independently and anchor any verdict to d3937e7d8f15806bda2d98694d24ebd559c708ad.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration 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.

Devin Review found 1 new potential issue.

Devin Review

Comment thread tests/api/smoke.mjs
coderabbitai[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Please review exact current contributor head 6afb53e045fe216d837ccb905a1da46d3787f599 against protected develop@2c328875e00e86537df3e965170be80532571cad. Do not reuse the predecessor-head 27e581a7298b9faa309d9c838e1f5f05d3c0f355 OpenCode COMMENTED review or any earlier status-only/model-only evidence.

Fresh current state: every inline review thread is resolved; repository-owned Dependency Review, Fuzz, Security Scan, OSV Scanner, Server Tests, and SAST Semgrep are terminal-success on this exact head. The required OpenCode workflow failed only because no authenticated APPROVED or CHANGES_REQUESTED OpenCode verdict exists for 6afb53e.... Required Strix remains separately non-authoritative because its central workflow materialized the base workspace and then exhausted provider retries; that owner defect is tracked on .github#891 and must not be converted into product approval.

Verify the current source independently, especially canonical invite identity uniqueness, full case-fold equivalence including Cherokee regressions, existing-account invite creation, secret-bearing invite/share path redaction, revoked-token behavior, and no pre-identity membership/audit/delivery/invite-consumption mutation. Anchor any formal verdict to this exact head.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

Review only exact current contributor head 6afb53e045fe216d837ccb905a1da46d3787f599 against protected develop@2c328875e00e86537df3e965170be80532571cad. Treat every predecessor review, PR-body SHA, status, and check as historical. Fresh current-head evidence shows all posted review threads resolved and repository-owned Server Tests, Fuzz, OSV Scanner, Dependency Review, Security Scan, and SAST Semgrep terminal-success on this exact SHA; CodeQL and Semgrep code-scanning checks are also terminal-success. The current opencode-review check 99074778252 failed closed only because no formal current-head OpenCode Reviews API verdict exists. Re-evaluate the current 10-file security diff, including invite identity binding, ambiguous canonical-email fail-closed behavior, request-log bearer redaction, indexed Unicode mailbox canonicalization, existing-account invite creation, Node runtime contract, and the repaired revocation regression, then submit a formal review-only verdict anchored to this SHA. Do not mutate the branch, rebase, force-push, merge, weaken gates, or infer approval from status-only/model-only evidence.

Copy link
Copy Markdown
Contributor Author

Hour-20 exact-head review request.

Current head 6afb53e045fe216d837ccb905a1da46d3787f599. Devin/CodeRabbit/author COMMENTED is not independent APPROVE. OpenCode DISMISSED/REQUEST_CHANGES on predecessor heads does not transfer. Ruleset 18156473 needs two independent APPROVE reviews on this exact SHA.

Invite identity binding. Land only with two independent APPROVE reviews plus exact-head Checks.

Do not self-approve. Do not --admin merge. Checks/reviews are not a reason to weaken fail-closed gates.

Copy link
Copy Markdown
Contributor Author

Hour-21 exact-head review request.

Current head 6afb53e045fe216d837ccb905a1da46d3787f599.
Devin/CodeRabbit/author COMMENTED is not independent APPROVE. Copilot review requests are not APPROVE. Ruleset 18156473 needs two independent approvals. Do not self-approve. Do not merge without two independent APPROVE reviews on this exact head.

@opencode-agent review

Copy link
Copy Markdown
Contributor Author

Hour-22 exact-head review request.

Invite identity bind. Current head 6afb53e045fe216d837ccb905a1da46d3787f599 BLOCKED. Land only with two independent APPROVE reviews plus exact-head Checks. Devin/CodeRabbit/author/OpenCode COMMENTED is not independent APPROVE. Do not self-approve. Do not --admin merge.

@opencode-agent review

Copy link
Copy Markdown
Contributor Author

Hour-23 exact-head review request.

Current head 6afb53e045fe216d837ccb905a1da46d3787f599.
Land only with two independent APPROVE reviews plus exact-head Checks. Bot COMMENTED is not APPROVE.

@opencode-agent review

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.

security: bind invite acceptance to the invited identity and stop roster token disclosure

1 participant