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.
- Last reviewed commit: 04fa951a02592b513fb6916a5d8c4c8e0d2841fc
- Latest commit, not reviewed: 09ac75c3cf9810a361a1dd1542c8194334778db4
Use the following commands to manage reviews:
@coderabbitai resumeto resume automatic reviews.@coderabbitai reviewto trigger a single review.
Use the checkboxes below for quick actions:
- โถ๏ธ Resume reviews
- ๐ Trigger review
๐ Summary
Summary by CodeRabbit
- New Features
- Connect GitHub accounts to an organization from Settings โ GitHub, reuse existing installations, and choose which accounts to connect when multiple are available.
- View connected accounts, repository counts, who connected each account, and when.
- Disconnect an account for one organization without affecting its connections to other organizations. Members can view connections; owners and admins can manage them.
- The CLI can list organization GitHub accounts, provide a connection link, wait for a connection to complete, and disconnect accounts by login.
- Documentation
- Updated GitHub setup, connection, permissions, and CLI guidance.
The pull request adds organization-scoped GitHub account connections through the dashboard and CLI. It adds authorization and callback flows, account listing and disconnection, and updates repository displays, configuration, tests, and documentation.
Changes: Organization GitHub Connections
Layer / File(s) Summary GitHub authorization foundation
dashboard/src/modules/github/github-observation.api.ts,dashboard/src/server/config.server.ts,dashboard/.env*,dashboard/self-host/.env.example,dashboard/scripts/verify/*,dashboard/src/test/*,docs/user/self-hosting.mdThe GitHub API exchanges authorization codes and reads authorized user data. Configuration, test environments, and self-hosting instructions include GitHub App client credentials and authorization details. Organization connection lifecycle
dashboard/src/modules/github/github-connect.*,dashboard/src/modules/github/github-connect.postgres.test.ts,dashboard/src/routes/api/github/*,dashboard/src/routeTree.gen.tsAuthenticated operations start and complete connections, list and accept installation offers, and list organization accounts. Signed state and offer tokens are checked against the actor and organization. Settings and connection entry points
dashboard/src/routes/_protected/cloud/$organizationSlug/_org/*,dashboard/src/components/dashboard-navigation-model*,dashboard/src/components/service-source-selector*,dashboard/DESIGN.md,docs/user/deploy/github.mdThe dashboard adds organization GitHub settings and manager controls. Connection prompts use the organization-scoped route, and repository results are grouped by account. Account listing and CLI behavior
dashboard/src/modules/github/github-cli.server.ts,dashboard/src/modules/github/github.repository.ts,dashboard/src/modules/agent/call-cloud.server.ts,dashboard/src/routes/api/cli/*,core/crates/ployz/src/handlers/github.rs,core/crates/ployz/tests/config_cli.rs,docs/user/cli/overview.mdConnection data includes the organization connect URL and connection attribution. Disconnect operations use an account login instead of an installation ID. The CLI waits for connection changes and displays account and connector details. Priority: โ Normal
Estimated code review effort: 4 (Complex) | ~60 minutes
Change: Feature
Sequence Diagram(s)
mermaid1 sequenceDiagram 2 actor User 3 participant ConnectRoute 4 participant GithubConnect 5 participant GitHub 6 participant CallbackRoute 7 User->>ConnectRoute: Request organization connection 8 ConnectRoute->>GithubConnect: Start connection for signed-in user 9 GithubConnect->>GitHub: Redirect for installation or authorization 10 GitHub->>CallbackRoute: Return authorization callback 11 CallbackRoute->>GithubConnect: Complete connection for signed-in user 12 GithubConnect->>GitHub: Exchange code and list authorized installations - New Features
Merge Risk: ๐ก Moderate ยท up to 04fa9
A connection offer can still be accepted after the user loses GitHub administrator access. Recheck authorization before linking; the remaining CLI and dashboard issues are narrower but should also be addressed.
Security architecture risk: ๐ก Moderate ยท up to 04fa9
The connection flow has meaningful identity and organization checks. However, account-selection offers can outlive GitHub administrator access, and a concurrent connection can overwrite a recorded installation suspension. These lifecycle issues warrant attention because connections grant ongoing repository access.
Retained concerns
- Medium ยท security ยท inferred: The new signed offer retains linking authority for up to 15 minutes after issuance. Acceptance rechecks Ployz organization management access but not GitHub administrator authority, and does not consume or invalidate the offer. A former GitHub administrator who remains a Ployz organization manager can therefore link an offered installation after GitHub revocation, or replay an accepted offer after disconnect. The resulting organization link can persist beyond offer expiry while the installation remains usable.
- Medium ยท security ยท inferred: The callback filters installations using an earlier GitHub response, then upserts their metadata through a helper that unconditionally clears suspendedAt. If a suspension webhook is processed between that response and the upsert, the callback can erase the newer suspension for the shared installation. This affects the local credential guard for every organization linked to that installation, not only the connecting organization. The helper predates this PR, but the OAuth callback introduces this additional stale-snapshot writer. Actual access while GitHub itself remains suspended is not established.
Security review details
Security Blast Radius
- inferred โ Offer abuse requires the original actor, current management access to the signed organization, and an unexpired legitimate offer. It cannot select arbitrary installations or another organization. Once linked, access follows the App installation's repository scope rather than the connector's continuing GitHub membership. Shared suspension-state drift can affect every organization linked to that installation.
Security Findings and Attack Paths
- inferred โ A user can obtain a multi-account offer while authorized, lose GitHub administration, and accept it before expiry while retaining Ployz management access. Acceptance inserts a persistent link without renewed GitHub authorization. Separately, an in-flight callback can overwrite a webhook-recorded suspension using its earlier installation snapshot. These are source-supported lifecycle concerns, not demonstrated production exploits.
Trust Boundaries and Controls
- observed โ The strongest controls are authenticated callback identity, signed actor/organization-bound state, current organization management checks, GitHub-side administration checks at callback time, and signed selection restrictions. Repository-cache queries join through the target organization's link, and credential acquisition checks that link and local suspension before returning even a cached installation token. Neither credential acquisition nor offer acceptance rechecks the connector's GitHub membership.
Resilience and Maintainability Implications
- observed โ Disconnect's organization-scoped deletion and the per-call credential guard provide failure containment. Suspension retains links but clears repository cache; deletion removes the installation and associated state. These protections depend on preserving authoritative lifecycle state across concurrent callback and webhook writes.
Hardening Proposals
- proposed โ Make authorization freshness and offer invalidation explicit: renew GitHub authority at acceptance, and use consumption or a revocation generation where disconnect must invalidate outstanding offers. Separate metadata updates from suspension transitions so callback snapshots cannot clear a later lifecycle event.
Pre-merge checks: Passed 4 ยท Failed 1
Failed Failed checks: 1 warning
Check name Status Explanation Resolution Docstring Coverage Warning Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 34 functions across 39 files. (4 skipped:โฆ Write docstrings for the functions missing them to satisfy the coverage threshold. Passed Passed checks: 4 passed
Check name Status Explanation 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 The description directly covers the organization-scoped GitHub connection and disconnection changes, including UI behavior, CLI behavior, security checks, self-hosting configuration, tests, and verifiโฆ Title check Passed The title clearly and concisely summarizes the primary change: connecting and disconnecting GitHub accounts per organization.
Full details: Docstring Coverage
Explanation
Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 34 functions across 39 files. (4 skipped: 4 unsupported.)
โจ Finishing Touches: ๐ก 1
-
๐ Generate docstrings: ๐ก
- Commit to this branch
- Create a new PR
๐งช Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix ยท Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.