Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5b0e8ea9-7fd3-4e74-87d7-c3b7e69d8a7b
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5b0e8ea9-7fd3-4e74-87d7-c3b7e69d8a7b
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Membership snapshots, incomplete permission sources, and pending invitations currently undermine fail-closed reconciliation.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
Open (3)
What changed in this PR
Adds a backend for managing direct, role-aware GitHub repository access.
Changes:
- Loads validated repository role files.
- Reconciles direct grants through GraphQL and REST.
- Adds comprehensive tests and rollout documentation.
| File | Description |
|---|---|
README.md |
Documents configuration and rollout. |
lib/entitlements/backend/github_repository.rb |
Defines and loads the backend. |
lib/entitlements/backend/github_repository/configuration.rb |
Validates and loads role files. |
lib/entitlements/backend/github_repository/controller.rb |
Coordinates reconciliation. |
lib/entitlements/backend/github_repository/models/repository_access.rb |
Models role-aware access. |
lib/entitlements/backend/github_repository/provider.rb |
Calculates repository changes. |
lib/entitlements/backend/github_repository/service.rb |
Implements GitHub reads and mutations. |
spec/unit/entitlements/backend/github_repository_spec.rb |
Tests backend behavior. |
spec/unit/spec_helper.rb |
Loads the backend in tests. |
spec/unit/fixtures/repositories/other.repo/maintain.txt |
Adds group-rule fixture. |
spec/unit/fixtures/repositories/other.repo/admin.yaml |
Adds expired-rule fixture. |
spec/unit/fixtures/repositories/entitlements-app/write.rb |
Adds Ruby-rule fixture. |
spec/unit/fixtures/repositories/entitlements-app/triage.yaml |
Adds YAML-rule fixture. |
spec/unit/fixtures/repositories/entitlements-app/read.txt |
Adds text-rule fixture. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| def apply(repository, instructions) | ||
| Configuration.validate_repository!(repository) | ||
| instructions.sort_by { |instruction| [instruction.fetch(:action) == :upsert ? 0 : 1, instruction.fetch(:login).downcase] }.each do |instruction| |
| if status == 201 | ||
| unless result.is_a?(Sawyer::Resource) && result[:id].is_a?(Integer) && result[:id] > 0 | ||
| GitHubRepository.fail!("Malformed repository invitation response") | ||
| end | ||
| Entitlements.logger.warn("#{repository}: invitation created for #{instruction.fetch(:login)}; access is not yet active") | ||
| end |
| unless edge.is_a?(Hash) && edge["node"].is_a?(Hash) && edge["permissionSources"].is_a?(Array) | ||
| GitHubRepository.fail!("Missing or malformed repository permission sources") | ||
| end |
|
The vendored-gem demo is available in github/entitlements#142229 (draft, DO NOT MERGE). It pins preview version |
The live entitlements-default demo proved edge.permission adds a public_repo scope requirement to an admin:org token. Read only the source-specific roles consumed by reconciliation, without broadening credentials or falling back to effective permissions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5b0e8ea9-7fd3-4e74-87d7-c3b7e69d8a7b
|
The real github/entitlements#142229 no-op calculation exposed an unnecessary credential requirement in the initial query: effective edge.permission requires public_repo, while CI has admin:org. Commit d12e39a removes that unused field, retaining exact direct permissionSources.roleName and strict error handling. No token scopes were broadened. A regression test guards the requested fields; all 285 plugin examples pass with 100% line coverage. The demo now vendors the refreshed source-commit-derived gem and is rerunning the actual entitlements-default calculation. No live mutations or merge are involved. |
Remove all repository team associations and undeclared direct grants, including outside collaborators. Preserve team hierarchy and membership, order user upserts before cleanup, and verify snapshots before and after application. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8107bce-2500-45f8-b046-3f50092d9fbd
|
Published individual-only repository reconciliation in The live read-only App no-op run succeeded and now proposes removal of Production gate discovered: the declared user currently has organization-owner JIT access and the backend rejects desired owners. The demo uses the existing warn-and-skip setting to verify team cleanup, not as a production fix. Owner declarations/direct-grant persistence during JIT elevation need an explicit policy and API validation before rollout. This live run does not verify owner grant creation or applied convergence. |
Discover base permissions and every organization role and assignment. Accept owners as desired users, defer ambiguous owner grants and roles below inherited access, and preserve organization/enterprise team sources using access_source. Refresh organization access for stale-plan and convergence checks, fail closed on incomplete metadata, and document required read permissions and policy exceptions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a8107bce-2500-45f8-b046-3f50092d9fbd


Summary
Validation
Required read permissions / live gate
Organization Administration: read and Custom organization roles: read are now required, alongside Members: read and repository permissions. The App must expose organization base settings, the full role catalog/assignments, collaborator permissionSources, and repository-team access_source. Missing permissions or unsupported APIs fail closed.
The prior successful read-only demo in github/entitlements#142229 used preview 1.2.6.pre.repository.g224de61218a0 and confirmed three direct team-removal calculations. It does not validate the generalized organization-role reader added in c522a17. The refreshed preview
1.2.6.pre.repository.gc522a17097b2is now pushed to github/entitlements#142229 at commit285d75533ecc7bce9754f3c01e4fe41a87cd177b. Its CI job installed the preview but failed preflight because the App installation lacksorganization_administrationandorganization_custom_org_rolesread permissions. App/installation approval and a successful rerun are required before this live gate is satisfied. No live mutations or production convergence tests have been performed.Deferrals are visible exceptions, not full convergence to role files. Existing higher direct grants can remain while deferred. JIT expiry is handled on a later calculation, not atomically with privilege changes.
Tracking: github/sae-iam-team#3141.
This PR does not include the unrelated team GraphQL batching changes in #301.