Skip to content

feat(validate): allow declaring ownership of paths that do not exist yet - #12

Open
Elaine-cls wants to merge 1 commit into
masterfrom
fix/validate-private-groups-and-absent-paths
Open

feat(validate): allow declaring ownership of paths that do not exist yet#12
Elaine-cls wants to merge 1 commit into
masterfrom
fix/validate-private-groups-and-absent-paths

Conversation

@Elaine-cls

@Elaine-cls Elaine-cls commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

validate requires every path named in CODEOWNERS to already exist in the
working tree. But declaring an owner ahead of the file is often deliberate and
security-relevant.

Our clearest case is .extension.gitlab-ci.yml: it appears as a rule in 1268 of
our repositories and as a file in almost none. It is executed as a child pipeline
from the default branch, so it must already be owned the moment somebody creates
it. Neither workaround is acceptable — creating the file changes pipeline
behaviour, because its mere existence is what triggers that child pipeline, and
dropping the rule leaves the file unowned.

Fix: --ignore-path / CODEOWNER_IGNORE_PATHS (comma-separated, repeatable)
opts specific paths out of the existence check; they log a warning instead of an
error. Paths that are not listed still fail, so typo detection is preserved —
that matters, because it is exactly what surfaces rules naming directories that
were never created (we have ~1044 repositories in that state).

Compatibility

  • verify is untouched.
  • validate with no new configuration behaves exactly as before.
  • ValidateCodeownerFile gained a parameter; it is library-internal and the one
    call site is updated.

Tests

go test ./... passes. TestValidateCodeownerFileIgnorePaths covers four cases:
an absent path fails when not opted in; passes once opted in; opting in a
different path does not help; and a single comma-separated value is split and
trimmed (the shape an env var arrives in).

Verified end to end in GitLab CI against a real repository and its real file
tree: the previously failing file reports Valid CODEOWNERS file, and an
injected bad path still fails.

Not included

An earlier revision of this branch also tried to fix owner resolution for
private groups. GroupExists only consults the global GET /groups?search
endpoint, which omits private groups the caller is not a member of, so a private
group shared with the project is reported invalid under a CI token.

That attempt fell back to the project's own shared_with_groups. Testing in
real CI proved this does not work
: GitLab filters shared_with_groups by the
caller's visibility too. With a project bot token the endpoint returns only the
groups that token can already see:

Token GET /projects/:idshared_with_groups /groups?search=<private>
A member of the private group ['sre', 'sre-team'] returns it
Project CI bot ['sre'] []

A project-scoped token fundamentally cannot confirm that a private group it
cannot see exists — no endpoint works around that, because that is what private
means. That half was therefore dropped from this PR rather than shipped inert,
and is being addressed separately on the token/permission side.

Ref: CPER-20260817-04

@Elaine-cls
Elaine-cls force-pushed the fix/validate-private-groups-and-absent-paths branch from 4794a4a to 9d00bd9 Compare August 26, 2026 16:26
validate required every path named in CODEOWNERS to already exist in the
working tree. But declaring an owner ahead of the file is often deliberate
and security-relevant: our clearest case is .extension.gitlab-ci.yml, which
appears as a rule in 1268 repositories and as a file in almost none. It is
executed as a child pipeline from the default branch, so it must already be
owned the moment somebody creates it. Neither workaround is acceptable --
creating the file changes pipeline behaviour, since its mere existence
triggers that child pipeline, and dropping the rule leaves it unowned.

Add --ignore-path / CODEOWNER_IGNORE_PATHS, which opts specific paths out of
the existence check; they log a warning instead of an error. Paths that are
not listed still fail, so typos keep being reported -- that matters, because
it is what surfaces rules naming directories that were never created.

verify is untouched, and validate with no new configuration behaves exactly
as before.
@Elaine-cls
Elaine-cls force-pushed the fix/validate-private-groups-and-absent-paths branch from 9d00bd9 to c09f52c Compare August 26, 2026 16:45
@Elaine-cls Elaine-cls changed the title fix(validate): resolve private shared groups and allow declared-but-absent paths feat(validate): allow declaring ownership of paths that do not exist yet Aug 26, 2026
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.

1 participant