News

Enforce GitHub Advanced Security Ownership Before Delegating Administration

GitHub enterprises can now stop both repository and organization owners from changing feature states defined by an enterprise security configuration. Before you delegate either role, run the same harmless mutation with each identity, read the effective state back, and preserve the result as an ownership boundary.

September 16, 2026

A black mechanical lock assembly with a central padlock, orange-lit controls, and blue lights on either side.
The central lock represents the enterprise policy that remains above delegated repository and organization administration.

Define the Boundary You Need

GitHub's September 15 changelog adds a consequential third enforcement choice for enterprise security configurations. An enterprise administrator can choose not to enforce, enforce against repository owners, or enforce against both repository and organization owners. The last option moves control of configured feature enablement above both delegated administration layers.

The scope is narrower than “organization owners cannot change security.” GitHub's enforcement reference says the boundary applies to the enablement status of features that the configuration sets to enabled or disabled. A feature left unset is not covered by that promise. Your test must therefore name one configured feature and one exact desired state.

Separate authority from operation

A locked configuration does not prove the feature is operating. GitHub lists conditions that can break effective code-scanning enforcement, including disabled or unavailable GitHub Actions. Test who can change the state here; verify scanner health, recent runs, and repository coverage in a separate operational control.

Build a Disposable Role Fixture

Use a test enterprise, one test organization, and one disposable repository. Attach an enterprise configuration that explicitly enables one low-impact feature suitable for the tenant. Do not use a production repository or a feature whose temporary change would expose secrets or suppress required scanning. Record the enterprise, organization, repository, configuration ID, feature field, expected state, and enforcement mode.

Create three separately attributable identities: an enterprise administrator who owns the fixture, an organization owner with no enterprise-administrator role, and a repository administrator who is not an organization owner. Confirm the effective role of each identity before the test. Shared administrator accounts make a pass impossible to audit.

{
  "fixture_id": "ghas-boundary-001",
  "configuration_id": 1325,
  "feature": "secret_scanning",
  "enterprise_state": "enabled",
  "attempted_state": "disabled",
  "actors": ["repository_admin", "organization_owner"],
  "restore_owner": "enterprise_admin"
}

The attempted mutation and the acceptance rule now refer to the same field. Avoid a vague instruction such as “try to weaken security” paired with a score for secret scanning. If one actor edits a different feature, the two role results are not comparable.

Run the Baseline Before Enforcement

Start with Don't enforce. As the repository administrator, attempt the selected change through the normal repository surface. Capture the actor, timestamp, requested value, visible response, and an independent read of the effective value. Restore the enterprise-defined state. Repeat the same sequence as the organization owner through the organization surface.

The baseline is not expected to produce one universal outcome. Other policy, licensing, role, or product constraints may already block a mutation. Its job is to show what each delegated identity can do in your tenant before the new boundary is applied. If either actor cannot reach or change the chosen field in the baseline, stop and choose another documented feature or correct the fixture. A negative result without a working positive control proves nothing about enforcement.

PhaseActorAttemptRequired evidence
BaselineRepository adminEnabled to disabledUI/API result plus effective-state readback
BaselineOrganization ownerEnabled to disabledSame field, same evidence
Repository-only enforcementBoth actorsRepeat unchangedRepository role blocked; organization result recorded
Repository-and-organization enforcementBoth actorsRepeat unchangedBoth roles blocked and state unchanged

Probe Both Enforcement Modes

Have the enterprise administrator select Enforce for repository owners. Verify the displayed mode, then repeat both role attempts without changing the repository, feature, requested state, or evidence format. The repository administrator should not be able to change the configured feature. Do not infer what happens to the organization owner; execute and record that second probe.

Next select Enforce for repository and organization owners using the procedure in GitHub's enterprise configuration guide. Repeat the exact pair. The acceptance condition is specific: neither delegated identity changes the feature's effective state, while the enterprise configuration remains attached and still declares the expected value.

This is a least-privilege test, not an excuse to grant broad roles temporarily in production. The broader design principle is developed in the zero-trust architecture guide, while the manual's security chapter explains why permissions and review boundaries belong in the initial system design.

Treat REST Success as Transport Evidence Only

GitHub documents an unusual failure mode for enforced settings: a REST request can appear to succeed while no enablement status changes. Therefore, do not score a 2xx response as an authorization bypass or as a successful mutation. After every request, retrieve the relevant configuration or repository state with an identity authorized to read it and compare the returned feature value with the pre-attempt value.

pass_when =
  request.actor == expected_actor &&
  request.field == fixture.feature &&
  readback.value == fixture.enterprise_state &&
  configuration.id == fixture.configuration_id &&
  configuration.is_attached == true

Preserve the request ID or audit correlation value when available, but keep the score observable: requested state, response status, readback state, and selected enforcement mode. The public REST representation currently uses a broad enforced/unenforced value, so retain a screenshot or exported administrative record of the granular enterprise UI choice alongside behavioral results. Do not manufacture a three-state API field that the endpoint does not document.

Record the Delegation Decision

Create one row per actor and phase. Mark pass only when the positive control worked and the enforced attempt left the effective state unchanged. Mark fail when a delegated actor changed the configured state under a mode intended to block that actor. Use inconclusive for missing readback, ambiguous identity, an unattached configuration, or a failed baseline.

The final delegation record should name the highest role allowed, the enforcement mode selected, the configuration and repositories covered, the feature tested, every result, evidence locations, test date, and the owner of periodic retesting. Include a separate operational check for the feature itself. For code scanning, that may include workflow availability and a recent successful analysis; it must not be folded into the permission result.

Retest after changing the configuration, its enforcement choice, role assignments, organization membership, repository transfer, or the feature used as the control. The conclusion is deliberately narrow: on the recorded date, these two delegated identities either could or could not override this configured state in this tenant. That is enough to turn delegation from an assumption into an auditable decision.

Sources checked September 16, 2026