[FEATURE REQUEST] Private or restricted-access branches within a public repository #202434
Replies: 6 comments
|
💬 Your Product Feedback Has Been Submitted 🎉 Thank you for taking the time to share your insights with us! Your feedback is invaluable as we build a better GitHub experience for all our users. Here's what you can expect moving forward ⏩
Where to look to see what's shipping 👀
What you can do in the meantime 💻
As a member of the GitHub community, your participation is essential. While we can't promise that every suggestion will be implemented, we want to emphasize that your feedback is instrumental in guiding our decisions and priorities. Thank you once again for your contribution to making GitHub even better! We're grateful for your ongoing support and collaboration in shaping the future of our platform. ⭐ |
|
Absolutely looking forward to this! |
|
yes please! |
|
yesss! |
|
yes plz!! |
|
Yes please! 🙌 Looking forward to this! |
Uh oh!
There was an error while loading. Please reload this page.
🏷️ Discussion Type
Product Feedback
Body
Summary
I would like GitHub to support private (or more accurately, restricted-access) branches inside an otherwise public repository.
Today, repository visibility is configured at repository level. Public repositories are readable by everyone, while private repositories are limited to explicitly authorized users. Branch protection can restrict who pushes to a branch, but it does not provide branch-level read permissions.
The proposed feature would add a visibility and access-control layer to individual branches without requiring maintainers to split one project across separate public and private repositories.
GitHub already implements a narrower version of private collaboration for public repositories through temporary private forks used by security advisories. That mechanism is limited to vulnerability remediation, but it demonstrates that private development associated with a public repository is a valid workflow.
What the feature would do
A repository administrator could mark an individual branch, or branches matching a ruleset pattern, as restricted.
A restricted branch would :
Repository administrators would always retain access. Organization and enterprise administrators could configure policies controlling :
internal/**orembargoed/**The feature should be disabled by default and explicitly enabled in repository settings.
Suggested access model
A restricted branch could have three permission levels :
Only repository administrators should be able to grant the Manage permission.
The branch creator could automatically receive View and Contribute access, but could never remove repository administrators or an organization-defined break-glass role.
GitHub Apps should require an explicit branch grant. Repository-wide
contents:readaccess should not automatically expose restricted branches unless an administrator has opted into that behavior.Quick UI mockup
Branch selector
Users without access would only see :
They should not see placeholders, branch counts, names, or any indication that additional restricted branches exist.
Creating or editing a branch
Repository settings
Use cases
Public core with private extensions
A company may maintain an open-source core while developing enterprise-only modules or integrations that closely follow the public codebase.
Maintaining both in one repository would reduce duplicated configuration, synchronization scripts, and cross-repository cherry-picking.
Embargoed feature development
Maintainers could collaborate privately on an unreleased product, partnership, hardware integration, or coordinated announcement before publishing the implementation.
This would be useful when the work is not a security vulnerability and therefore does not fit the security-advisory workflow.
Client-specific development
A public project could contain restricted branches for customer-specific integrations without exposing client names, requirements, credentials, or proprietary changes.
Internal experiments
Maintainers could test architectural changes with a limited group before deciding whether the work should be made public.
Coordinated upstreaming
Organizations that maintain internal modifications to an open-source project could prepare and review changes privately, then intentionally publish individual changes upstream without maintaining a permanently separate mirror.
Credentials/secrets lockaway
Let's face it, many companies create private repos on GitHub and keep secrets in them as an easy way to synchronize credentials across teams. As a consequence, even if the repo could be made public by sheer will, it is just not possible due to those secrets.
Private branches would allow the core to be open-sourced as a public project while company-internal secrets would remain locked away in restricted branches. This isn't ideal, but I've seen this situation way too many times.
Copyrighted or licensed content
A public repository could contain restricted branches with copyrighted or licensed content that cannot be redistributed.
For ex, a project allowing to mod an existing software from its original files could be public, but only the modding-related code would be, with the actual decompiled proprietary code being in a restricted branch, and users of the project would have to bring in their own.
While one could argue that you should just gitignore those files, it's mostly useful to still have them tracked by git, either for the sake of diffs, to be able to easily update them when a new version of the original software is released, to keep track of the code's history or even nowadays to have a rollback state ready when AI Agents mess up.
Proposed visibility semantics
A commit's visibility should depend on reachable references
GitHub should authorize access to a commit based on whether it is reachable from at least one branch or tag the requesting user may view, not merely on whether the user knows its SHA.
Examples :
The underlying Git object may be physically deduplicated, but its storage location must not determine its authorization.
Unauthorized requests should return 404
For an unauthorized user, requests for restricted resources should normally return
404 Not Found, rather than confirming that the branch, commit, pull request, tag, or comparison exists.This should apply consistently to :
Changing a public branch to restricted
Changing an existing public branch to restricted cannot undo previous disclosure.
Anyone may already have :
GitHub's existing documentation similarly warns that rewriting or deleting public history may leave commits accessible in clones, forks, pull-request references, cached views, or through their SHA hashes.
The conversion dialog should therefore display a strong warning :
For especially sensitive incidents, existing sensitive-data-removal and credential-rotation procedures would still be required.
Making a restricted branch public
Publishing a restricted branch should be treated as an explicit declassification event.
Before publication, GitHub should show :
The operation should require repository-admin confirmation and create an audit-log entry. Maybe 2FA too if required by the org ?
Organizations should be able to require approval from a second administrator or designated security team before a restricted branch becomes public.
What happens when merging into a public branch?
A pull request from a restricted branch into a public branch should itself remain restricted until the merge is completed.
Otherwise, the pull request title, description, diff, comments, review activity, check output, and branch name could disclose the supposedly private work.
The merge dialog should clearly explain what will become public.
Merge commit
When a merge commit makes the restricted commits reachable from the public branch, those commits and their contents become public.
GitHub should require an explicit confirmation such as :
Squash merge
The resulting squashed commit and its complete resulting content become public.
The original restricted commit SHAs could remain restricted if they are not reachable from any public reference, but users should be warned that their code and combined change will be public.
Rebase and merge
The newly created public commits and their content become public.
Original restricted commit objects may remain restricted if no public reference reaches them, but the equivalent changes and commit metadata selected for the rebase are published.
Closing without merging
Closing a private pull request should not publish anything. Its branch, discussion, checks, and commits should remain restricted until deleted or explicitly published.
Tags and releases
For an initial version, I suggest not introducing private tags or private releases, although this would be the logical next step.
GitHub releases are based on Git tags, and people with read access to a repository can currently view and compare releases. Adding separate tag and release visibility would substantially increase the scope and number of possible disclosure paths.
A simpler initial rule would be :
A future extension could add restricted tags and releases, but these should use an explicit access model rather than inheriting ambiguous permissions from whichever branch contains the commit.
That later design would need to define :
Forking and cloning
Public clones and forks must receive only public references and objects reachable from public references.
Restricted branch names and tips must not appear in Git reference advertisements.
A public user should not be able to retrieve a restricted-only object by running an exact-SHA fetch.
Existing forks must not automatically receive restricted branches. If restricted forks are supported later, they should require explicit authorization and should not silently widen access through the repository network.
Archive downloads must also be generated from an authorized reference. A repository archive must never include restricted-only Git objects or files.
GitHub Actions and other integrations
Restricted branches introduce significant CI/CD risks.
The safest default would be :
GITHUB_TOKENrestricted_branchespermission ?Workflows running on public branches must not be able to enumerate, fetch, compare against, or inspect restricted branches unless the workflow has been explicitly granted access.
Similarly, an untrusted workflow on a restricted branch must not gain access to unrelated restricted branches merely because they are stored in the same repository.
Derived data that must inherit restrictions
Access controls must cover more than the Git branch itself.
Any data derived exclusively from a restricted branch should inherit its restrictions, including :
For objects associated with several branches, GitHub should avoid lowering their visibility until the relevant content is intentionally published.
Commit URL and SHA security
A commit hash must be treated as an identifier, not as an access token.
For example :
For a user without access, this URL must not reveal :
The same restriction must apply to
.patch,.diff, raw-content, API, comparison, and abbreviated-SHA endpoints.GitHub should re-evaluate authorization whenever a commit is requested. A URL copied while a user had access should stop working after access is revoked, unless the commit has since become reachable from a public reference.
Avoiding indirect information leaks
Unauthorized users should not be able to infer restricted activity from :
A private branch named
client/acme-acquisition, for example, is already sensitive even before any code is viewed.Audit and administration
The audit log should record :
Administrators should also have a view showing every restricted branch, its effective access list, relevant rulesets, active tokens or Apps, and whether any of its commits have become publicly reachable.
Important limitation
A restricted branch should be presented primarily as an access-control and collaboration feature.
Once content has been public, fetched by a user, sent to an integration, included in a build artifact, or copied into another repository, changing branch visibility cannot reliably retract it.
Secret scanning, push protection, least-privilege tokens, credential rotation, and established incident-response procedures would remain necessary.
Alternatives available today
The current alternatives are :
These approaches can work, but separate repositories often introduce duplicated settings, CI workflows, synchronization logic, cherry-picking, and more complicated comparisons and pull requests.
Suggested initial scope
To make the feature practical to introduce incrementally, a first version could support :
A later version could explore restricted tags, releases, forks, packages, and more advanced organization policies.
Closing
Branch-level read permissions would help open-source maintainers and organizations combine public collaboration with controlled pre-publication development, without forcing them to maintain parallel repositories.
The most important requirement is that the feature provide real confidentiality rather than merely hiding a branch in the interface. Every access path, including direct commit URLs, Git fetches, APIs, Actions, caches, forks, archives, pull requests, tags, and derived metadata, would need to enforce the same reachability-based authorization model.
All reactions