Skip to content

Internal Repositories and Enterprise Visibility

Lesson 3 of 10Intermediate13 min readGit at Scale & Enterprise Engineering · Enterprise GovernanceVerified: GitHub Enterprise Cloud documentation, September 2026

Internal is the visibility level people set without reading what it does.

It sounds like “private, but for the company”, which is roughly right and misleading in exactly the way that matters: internal repositories are readable by every organisation member across the entire enterprise, including people in organisations you have never heard of.

Internal is a third visibility level, between private and public, available in enterprise accounts.

GitHub documents the access model plainly: “Organization members have read permissions to all internal repositories in an enterprise, including those in organizations they are not a member of.”

And the boundary: “Internal repositories are not visible to people outside of the enterprise, including outside collaborators on organization repositories.”

So: everybody inside, nobody outside. Organisation membership does not narrow it; enterprise membership defines it.

Outside collaborators are explicitly excluded, which is the property that makes internal usable in an enterprise with contractors added as collaborators rather than as members.

Worth stating as a list, because the mental model people arrive with is wrong.

Can read:

  • Every member of every organisation in the enterprise
  • Including members of organisations that do not own the repository
  • Including people who have never heard of the repository or the team that owns it

Cannot read:

  • Anybody outside the enterprise
  • Outside collaborators — even those with access to other repositories in the same organisation
  • Anonymous or unauthenticated users

The purpose is stated by GitHub directly: internal repositories exist so an enterprise can practise innersource.

Innersource is applying open-source collaboration patterns inside a company. Anybody can read the code, anybody can open an issue, anybody can propose a change. See innersource for the operating model.

The barrier innersource removes is discovery and access friction. In an enterprise where everything is private, using another team’s library means finding out it exists, finding out who owns it, asking for access, waiting, and then reading it. Internal visibility removes four of those five steps.

The result is measurable in reduced duplication. The most common expensive outcome of private-by-default is three teams independently writing the same client library, because none of them could see the others’ work.

Enterprise members may fork internal repositories into any organisation where they have permission to create repositories.

Organisation owners can also permit forks owned by a user account, and can manage forking policy for the organisation.

A fork of an internal repository is itself internal — visibility is inherited, and the fork cannot be made public while its parent is internal.

Forking is the standard innersource contribution path. Someone in another team forks, changes, and opens a pull request back. It requires no permission grant from the owning team, which is the point.

The forking policy is a real decision. An enterprise can disallow forking of private and internal repositories entirely, which makes the innersource path unavailable and pushes contributions toward branch access — a stronger permission grant. See visibility and forking policies.

Push rulesets are worth knowing about here: GitHub documents that push rulesets apply to “the entire fork network for a repository”. A rule blocking a file pattern applies to forks as well as the parent, which matters when the fork population is the whole enterprise.

Visibility is about reading, but making a repository internal changes several other things people do not anticipate.

Discovery. The repository appears in enterprise-wide code search. Anybody searching for a function name, a configuration key or a hostname will find it. This is the intended benefit, and it is also the reason a repository containing an internal hostname list is now trivially discoverable by everyone.

Issues and discussions. Every enterprise member can open an issue. For a widely-used internal library that is the point; for a small team’s repository it can mean unexpected inbound traffic with no process behind it.

Notifications and watching. People can watch the repository, which is good for a shared library and noise for everything else.

Cloning. Read access means clone access. Every enterprise member can take a full copy of the repository to their machine, and that copy persists after their access is revoked. This is true of any repository they can read, but internal makes the population much larger.

Which means the question is not just “is this code sensitive” — it is “is anything in the history sensitive”. A repository that once contained a credential, later removed, still contains it in history, and making it internal exposes that history to the entire enterprise.

PrivateInternalPublic
Readable byExplicitly granted onlyEvery enterprise memberEveryone
Outside collaboratorsIf grantedNeverYes
Discoverable internallyNoYesYes
Innersource contributionsNoYesYes
Right forRestricted materialMost internal codeDeliberate publishing

Default to internal for ordinary code, if your enterprise has decided that internal transparency is the norm. It costs nothing and enables reuse.

Use private when there is a reason — a restricted population, sensitive material, a legal constraint, work with an external party. Being able to state the reason is the test.

Use public only deliberately, with a publishing process behind it. Making a repository public is an irreversible disclosure in practice, because clones and forks persist.

Contractors, collaborators and the boundary

Section titled “Contractors, collaborators and the boundary”

The distinction that determines whether internal works for your enterprise.

An outside collaborator has access to specific repositories without being an organisation member. They are granted access repository by repository.

They cannot read internal repositories. GitHub is explicit that internal repositories “are not visible to people outside of the enterprise, including outside collaborators on organization repositories.”

Which is a feature when the contractor should not see everything — the usual case. Internal visibility gives employees broad read access while keeping contractors scoped to what they were granted.

And a problem when contractors are effectively staff. A long-term contractor working alongside a team, who needs to read the shared libraries the team depends on, cannot read them if those libraries are internal. They must be granted access repository by repository, forever, as an ongoing administrative cost.

Two ways out, both with consequences:

  • Make them organisation members. They gain read access to every internal repository in the enterprise, which is a large grant and probably not what a contract intends.
  • Keep the libraries private with explicit team grants. Administrative overhead, and the innersource benefit is lost for those repositories.

The honest framing: internal visibility assumes the enterprise membership is the trust boundary. If a substantial fraction of the people doing the work are not enterprise members, that assumption does not hold, and the visibility model will fight the working model continuously.

Under Enterprise Managed Users this is sharper still, because managed accounts cannot collaborate outside the enterprise at all, and the contractor question becomes an identity architecture question rather than a repository one. See enterprise IAM.

The choice that has the largest effect and is made once.

Private by default means every reuse requires a permission request. It is the right default for an enterprise with genuinely sensitive material spread throughout the estate, and it is the wrong default for most.

Internal by default means code is readable unless somebody chose otherwise. It requires that the enterprise membership genuinely is the trust boundary — which it is, in most companies, since those people are employees with access to far more sensitive things than source code.

The enterprise policy controlling repository creation can specify which visibilities members may create. That is the enforcement point.

And the template is where the default is actually set. A repository created from a template with the right visibility gets it without anybody deciding.

Whichever you choose, make it explicit and write down why. “Private by default because nobody ever changed it” is not a policy, and it is what most enterprises have.

Secrets or credentials in the repository. Internal means the whole enterprise reads them. This should never be true of any repository, but it is more consequential here.

Personal data. A repository containing data subject to a data-protection regime should not be readable by every employee by default.

Material under a restrictive agreement. Code covered by an NDA, a joint venture agreement, or a customer contract that limits who may see it.

Anything an insider-risk model treats as restricted. Security tooling, fraud detection logic, key management. The reason to restrict is not that colleagues are untrustworthy; it is that the population is large enough that “everybody” is not a meaningful control.

Repositories with a contractor population working in them. Outside collaborators cannot read internal repositories, which means an internal repository is invisible to the contractors who need it. Private with explicit grants is correct there.

Internal repositories and security controls

Section titled “Internal repositories and security controls”

A repository that everybody can read is one where several security controls need thinking about differently.

Secret scanning matters more, not less. A credential in an internal repository is exposed to the whole enterprise. Push protection is the control that prevents it arriving in the first place, and it is worth mandating on internal repositories specifically.

Code scanning results are more visible. Depending on configuration, security alerts may be visible to people with read access, which for an internal repository is everybody. That is usually acceptable and occasionally not — a repository whose open vulnerabilities are sensitive in themselves needs consideration.

Dependency data becomes enterprise-visible, which is generally a benefit: it lets a security team see what the estate depends on without a permission campaign.

Branch protection is unchanged by visibility. Read access is not write access, and internal visibility grants only read. Everybody can see the code; the same people as before can change it.

The insider consideration is real but often overstated. The people who gain read access are employees who already have access to the systems the code runs on. The genuine risk is not malice — it is that a control which assumed a small audience no longer has one. Review controls that depend on obscurity; obscurity was never the control, but some were quietly relying on it.

Data classification is the practical framework. If the enterprise has one, map its levels to repository visibility once, publish the mapping, and make it the answer to every future visibility question. Without a mapping, every repository gets a fresh argument.

Inventory by visibility. The API returns visibility per repository, and a fleet-wide sweep produces the list in one query.

Review the ones that surprise you. Every enterprise has repositories that are internal and should not be, usually because visibility was set at creation and never revisited.

Watch visibility changes in the audit log. A private repository becoming internal is a widening of access, and it is worth alerting on rather than discovering.

Restrict who can change visibility. The enterprise policy allows visibility changes to be limited to organisation owners rather than repository admins. Widening access should be a decision somebody makes deliberately.

Do it periodically. Repository visibility is set once and rarely reviewed, so an annual sweep catches the drift.

If you have decided internal is the right default and the estate is currently private, this is a change worth sequencing rather than scripting in one pass.

  1. Publish the mapping first. Data classification level to repository visibility, agreed with whoever owns data policy. Without it, the change is one person’s judgement applied to thousands of repositories.

  2. Change the default for new repositories. Template and creation flow. This stops the problem growing while you deal with the existing estate, and it is the cheapest step by a wide margin.

  3. Scan history before changing anything existing. Secrets, personal data, third-party code. This is the step that takes real time, and skipping it is how a visibility programme becomes an incident.

  4. Let teams opt in first. Ask owners to flip their own repositories. The teams who do it early find the problems, and their repositories become the examples.

  5. Then flip by category, using custom properties to select. Start with the categories where the classification mapping is unambiguous.

  6. Leave a documented exception path. Some repositories should stay private, and a team that cannot say so will either fight the change or quietly revert it.

  7. Audit afterwards. Confirm what changed, and confirm nothing changed that should not have.

Never bulk-change visibility with a script and no history scan. The operation is one API call per repository and it is trivially easy to run; the exposure it can create is not trivially easy to undo, because clones made in the meantime persist.

Internal visibility is frequently proposed as the answer to problems it does not address.

It does not make code discoverable in a useful way. Everybody can find it; that is not the same as anybody does. Discovery needs a catalogue, decent README files and search that people know to use. Visibility is a precondition, not a solution.

It does not make a repository maintained. An internal repository nobody owns is a trap: colleagues find it, assume it is supported, build on it, and discover otherwise. Ownership metadata matters more once code is visible, not less.

It does not create a contribution culture. People contribute to another team’s repository when the contribution will be reviewed and merged in reasonable time. If it will sit for six weeks, visibility changes nothing. That is the substance of innersource, and it is a process problem.

It does not reduce duplication on its own. It removes one barrier — the access request. The others, principally “I did not know this existed”, need active work.

Being clear about this prevents disappointment. An enterprise that flips everything to internal and expects reuse to follow will conclude, wrongly, that innersource does not work.

Assuming internal means “my organisation”. It means the whole enterprise.

Splitting organisations to restrict internal repositories. It does not work; organisation membership does not narrow internal visibility.

Using internal for anything with a restricted population. Private is the mechanism.

Making a repository internal to enable a single team’s access. Grant that team access to a private repository instead.

Disallowing forking and expecting innersource to work. Forking is the contribution path that needs no permission grant.

Assuming outside collaborators can see internal repositories. They explicitly cannot, which is sometimes a surprise in the other direction.

Never auditing visibility. It is set at creation and drifts.

Leaving visibility changes to repository admins. Widening access should be a deliberate act.

Internal visibility makes the enterprise the audience. It is exactly right when your trust boundary is “employed here” and exactly wrong when it is anything narrower. Organisation structure does not narrow it, and outside collaborators are outside it.

  • Internal repositories are readable by all organisation members across the enterprise, including in organisations they do not belong to
  • Internal repositories are not visible outside the enterprise, including to outside collaborators
  • Organisation boundaries do not restrict internal visibility
  • Internal exists to enable innersource, and it removes the discovery and access friction that causes duplicated work
  • Enterprise members may fork internal repositories into organisations where they can create repositories; forks inherit internal visibility
  • Push rulesets apply to the entire fork network
  • Private is the mechanism for a restricted population; internal is never that mechanism
  • Enterprise Managed Users cannot create public content, so the public option is unavailable under EMU
  • Restricting who can change visibility makes widening access a deliberate act

Use an enterprise you have access to.

  1. List every internal repository across the enterprise. Predict: did you know how many there were?

  2. Pick three at random. For each, ask whether every employee reading it is acceptable. Record any that are not.

  3. Find any repository made internal in order to grant one team access. Predict: what should it be instead?

  4. Check your enterprise’s forking policy for private and internal repositories. Does the innersource path work?

  5. Check who can change repository visibility — repository admins, or organisation owners.

  6. Search the audit log for visibility changes in the last ninety days. Were any of them widenings nobody reviewed?

  7. Write down your enterprise’s default visibility and the reason for it. If there is no reason, that is the finding.

Engineering Team Onboarding SystemA 30-day Git and GitHub programme with standards templates, assessments and governance checklists.