Skip to content

chore: update baton-github to v0.4.0 - #26

Merged
Bencheng21 merged 1 commit into
mainfrom
ben.su/update-baton-github-latest
Aug 12, 2026
Merged

chore: update baton-github to v0.4.0#26
Bencheng21 merged 1 commit into
mainfrom
ben.su/update-baton-github-latest

Conversation

@Bencheng21

Copy link
Copy Markdown
Contributor

Summary

  • Bumps github.com/conductorone/baton-github from v0.3.10 to v0.4.0 and re-vendors.
  • Picks up two behavioral fixes from upstream:
    • Repository Grant (AddCollaborator) now detects an existing collaborator role and returns a GrantReplaced annotation instead of silently overwriting the prior permission grant.
    • getOrgBasePermission now treats a missing/empty default_repository_permission as "none" (fail closed) instead of assuming GitHub's create-time default of "read", which previously could invent pull grants for every org member when the credential lacked org-owner visibility.

Test plan

  • go build ./...
  • go test ./...
  • go vet ./...
  • Reviewed the vendored diff (vendor/github.com/conductorone/baton-github/pkg/connector/repository.go) — only file with content changes besides go.mod/go.sum/vendor/modules.txt

Picks up repository grant-replacement handling for AddCollaborator
(reports the previous role as replaced instead of silently overwriting
it) and a fail-closed fix for org default_repository_permission when
the field is empty/unreadable (previously assumed "read", now "none").

Co-authored-by: c1-squire-dev[bot] <c1-squire-dev[bot]@users.noreply.github.com>
Comment on lines +412 to +432
collaborator, resp, err := o.client.Repositories.IsCollaborator(ctx, repo.GetOwner().GetLogin(), repo.GetName(), user.GetLogin())
if err != nil {
return nil, wrapGitHubError(err, resp, "github-connector: failed to check if user is a collaborator")
}

var replacedGrantID string
if collaborator {
permLevel, resp, err := o.client.Repositories.GetPermissionLevel(ctx, repo.GetOwner().GetLogin(), repo.GetName(), user.GetLogin())
if err != nil {
return nil, wrapGitHubError(err, resp, "github-connector: failed to get user's repository permission")
}

prevPermission := roleNameToRepoPermission(permLevel.GetRoleName())
if prevPermission == "" {
// Custom repository role: fall back to the coarse permission (read/write/admin).
prevPermission = roleNameToRepoPermission(permLevel.GetPermission())
}

switch prevPermission {
case permission:
return annotations.New(&v2.GrantAlreadyExists{}), nil

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.

🟠 Bug: IsCollaborator and GetPermissionLevel report effective access — GitHub counts org members with access via a team or via default_repository_permission as collaborators. So a user whose only push access comes from a team makes prevPermission == permission, and this returns GrantAlreadyExists without ever calling AddCollaborator. C1 records the grant as fulfilled, but no direct collaborator record is created, so removing the user from the team silently drops the access. This is a regression versus v0.3.10, where AddCollaborator always ran; it is most visible with direct-collaborators-only, where the sync (affiliation direct) will keep showing no grant at all. Fix belongs upstream in baton-github: restrict the short-circuit to direct collaborators (e.g. ListCollaborators with Affiliation: "direct", or check permLevel.GetUser().GetRoleName() against the direct-collaborator source) rather than effective permission. (confidence: medium-high)

Comment on lines +440 to +446
// AddCollaborator overwrites the user's existing role, so report the
// old role's grant as replaced. GitHub permissions are cumulative;
// grants for other implied flags are reconciled at the next sync.
replacedGrantID = grant.NewGrantID(principal, &v2.Entitlement{
Id: entitlement.NewEntitlementID(en.Resource, prevPermission),
})
}

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.

🟡 Suggestion: with the default direct-collaborators-only=false, Grants() emits user-principal grants for team- and org-base-derived access too (ListCollaborators with affiliation all, line 233). prevPermission is the effective permission, so this can emit GrantReplaced for a grant that was never replaced — e.g. pull inherited from the org base permission survives AddCollaborator(push), but C1 drops it until the next sync reconciles. Worth scoping the GrantReplaced to the direct-collaborator permission upstream, or at least noting the transient inconsistency in the PR description. (confidence: medium)

Comment on lines 574 to +581
if perm == "" {
perm = "read" // GitHub default
l.Debug(
"baton-github: org default_repository_permission missing or empty; skipping org-member repo expansion (treating as none). "+
"Grant the credential org-owner visibility (admin:org / Organization Administration) to sync base-permission grants accurately.",
zap.String("org", orgName),
zap.String("org_id", orgResourceID.Resource),
)
perm = "none"

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.

🟡 Suggestion: this fail-closed change is default-on and removes grants for existing installs. docs/connector.mdx:77 currently presents read:org as an acceptable alternative to admin:org, but default_repository_permission is only returned to org owners / admin:org, so a read:org install running with direct-collaborators-only will lose every org-member-derived repo grant on the next sync — and the only signal is a Debug log. Update docs/connector.mdx to state that admin:org is required for accurate base-permission grants (BP3/D3), and consider surfacing this at Warn since it reflects a credential-scope gap (L1) rather than a routinely-absent field. (confidence: high on the docs gap, medium on the log level)

@github-actions

Copy link
Copy Markdown
Contributor

Connector PR Review: chore: update baton-github to v0.4.0

Blocking Issues: 1 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base ea40d9500147.
Review mode: full
View review run

Review Summary

Scanned the full PR diff for security and correctness: go.mod/go.sum/vendor/modules.txt bump only github.com/conductorone/baton-github v0.3.10 → v0.4.0 with no unrelated module additions, and the sole vendored content change is pkg/connector/repository.go. Since this repo delegates entirely to baton-github's builders (pkg/connector/connector.go:44-57, including RepositoryBuilder), both upstream behavior changes ship directly to this connector, so the vendored diff was reviewed as release behavior. No security issues found; one correctness regression in the new repository Grant short-circuit, plus a docs/observability gap around the fail-closed org base-permission change.

Security Issues

None found.

Correctness Issues

  • vendor/github.com/conductorone/baton-github/pkg/connector/repository.go:412-432IsCollaborator/GetPermissionLevel return effective access (team- and org-base-derived), so GrantAlreadyExists can short-circuit AddCollaborator and never create a direct collaborator record.

Suggestions

  • vendor/github.com/conductorone/baton-github/pkg/connector/repository.go:440-446GrantReplaced may be emitted for a team/org-base-derived grant that was not actually replaced when direct-collaborators-only is false.
  • vendor/github.com/conductorone/baton-github/pkg/connector/repository.go:574-581 + docs/connector.mdx:77 — the fail-closed "read""none" change is default-on and silently drops org-member repo grants for read:org installs; docs still present read:org as sufficient, and the only signal is a Debug log.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Correctness Issues

In `vendor/github.com/conductorone/baton-github/pkg/connector/repository.go` (fix belongs upstream in github.com/conductorone/baton-github, then re-vendor):
- Around lines 412-432: The repository Grant path calls Repositories.IsCollaborator and
  Repositories.GetPermissionLevel and, when the resulting permission equals the requested
  permission, returns a GrantAlreadyExists annotation without calling AddCollaborator. Both
  GitHub endpoints report effective access, which includes org members who only have access
  through a team or through the org's default_repository_permission. As a result, granting
  "push" to a user who has push only via a team is treated as already-granted, no direct
  collaborator record is created, and the access silently disappears if the user leaves the
  team. In v0.3.10 AddCollaborator always ran, so this is a regression. With
  direct-collaborators-only enabled the sync lists collaborators with affiliation "direct",
  so the grant will also never show up in a later sync. Fix: only short-circuit when the
  user is an existing *direct* collaborator — for example resolve the direct-collaborator
  role via ListCollaborators with Affiliation "direct" (or an equivalent check) instead of
  the effective permission — and otherwise fall through to AddCollaborator.

## Suggestions

In `vendor/github.com/conductorone/baton-github/pkg/connector/repository.go`:
- Around lines 440-446: replacedGrantID is built from prevPermission, which is the effective
  permission. With direct-collaborators-only false, Grants() lists collaborators with
  affiliation "all" and emits user-principal grants for team- and org-base-derived access, so
  this can report GrantReplaced for a grant that still legitimately exists (for example a
  "pull" grant inherited from the org base permission survives AddCollaborator("push")).
  Scope the replaced-grant computation to the user's direct-collaborator permission, or
  document the transient inconsistency until the next sync reconciles.
- Around lines 574-581: getOrgBasePermission now treats an empty default_repository_permission
  as "none" and only logs at Debug. This is a default-on behavior change that removes
  previously synced org-member repo grants. Consider logging at Warn instead, since an absent
  field here indicates a credential-scope gap (org owner / admin:org) rather than a routinely
  missing value, and include the org name so operators can act on it.

In `docs/connector.mdx`:
- Around line 77: The scope list offers "read:org" as an alternative to "admin:org", but with
  baton-github v0.4.0 a read:org credential cannot read default_repository_permission, so
  org-member-derived repository grants are no longer emitted (they are treated as "none").
  Update the docs to state that admin:org is required for base-permission grants to sync
  accurately, and note what changes for existing read:org installs after this upgrade.

@github-actions github-actions 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.

Blocking issues found — see review comments.

@Bencheng21
Bencheng21 merged commit c9dc5d1 into main Aug 12, 2026
11 checks passed
@Bencheng21
Bencheng21 deleted the ben.su/update-baton-github-latest branch August 12, 2026 19:23
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