Skip to content

fix: add missing adjudicateMisboundNamespace check to admission webhook filter#2978

Open
joonas wants to merge 2 commits intodefenseunicorns:mainfrom
joonas:fix/missing-adjudicate-misbound-namespace-admission
Open

fix: add missing adjudicateMisboundNamespace check to admission webhook filter#2978
joonas wants to merge 2 commits intodefenseunicorns:mainfrom
joonas:fix/missing-adjudicate-misbound-namespace-admission

Conversation

@joonas
Copy link
Copy Markdown
Member

@joonas joonas commented Mar 1, 2026

Description

shouldSkipRequest omitted the adjudicateMisboundNamespace adjudicator that filterNoMatchReason (the watch path) already included. This meant bindings targeting kind: Namespace with a namespace filter (a configuration error since namespaces don't live inside namespaces) were not rejected on the admission side. Instead, the request fell through to
adjudicateMismatchedNamespace, which produced a misleading error:

"Binding defines namespaces ... but Object carries ''"

rather than the correct "Cannot use namespace filter on a namespace object" rejection.

Additionally, misboundNamespace only checked
definesNamespaces (literal namespace list) but not definesNamespaceRegexes. A kind: Namespace binding with regexNamespaces would slip through in both the admission and watch paths with the same misleading mismatch message.

Two fixes:

  1. Add adjudicateMisboundNamespace(binding) to the shouldSkipRequest adjudicator list in filter.ts, placed before the namespace mismatch checks so the configuration error is caught early.

  2. Broaden misboundNamespace in postCollection.ts from allPass([bindsToNamespace, definesNamespaces]) to allPass([bindsToNamespace, anyPass([definesNamespaces, definesNamespaceRegexes])]), covering both filter variants.

Tests added for both admission and watch paths with literal and regex namespace filters, plus unit tests for the broadened predicate.

End to End Test:
(See Pepr Excellent Examples)

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Other (security config, docs update, etc)

Checklist before merging

…hook filter

`shouldSkipRequest` omitted the `adjudicateMisboundNamespace`
adjudicator that `filterNoMatchReason` (the watch path) already
included. This meant bindings targeting `kind: Namespace` with a
namespace filter (a configuration error since namespaces don't
live inside namespaces) were not rejected on the admission side.
Instead, the request fell through to
`adjudicateMismatchedNamespace`, which produced a misleading error:
```
"Binding defines namespaces ... but Object carries ''"
```
rather than the correct "Cannot use namespace filter on a namespace
object" rejection.

Additionally, `misboundNamespace` only checked
`definesNamespaces` (literal namespace list) but not
`definesNamespaceRegexes`. A `kind: Namespace` binding with
`regexNamespaces` would slip through in both the admission and
watch paths with the same misleading mismatch message.

Two fixes:

1. Add `adjudicateMisboundNamespace(binding)` to the
   `shouldSkipRequest` adjudicator list in `filter.ts`, placed
   before the namespace mismatch checks so the configuration
   error is caught early.

2. Broaden `misboundNamespace` in `postCollection.ts` from
   `allPass([bindsToNamespace, definesNamespaces])` to
   `allPass([bindsToNamespace, anyPass([definesNamespaces,
   definesNamespaceRegexes])])`, covering both filter variants.

Tests added for both admission and watch paths with literal and
regex namespace filters, plus unit tests for the broadened
predicate (166 tests pass across the two test files).

Signed-off-by: Joonas Bergius <joonas@defenseunicorns.com>
@joonas joonas requested a review from a team as a code owner March 1, 2026 04:12
@samayer12
Copy link
Copy Markdown
Contributor

@greptileai

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 22, 2026

Greptile Summary

This PR fixes two related bugs in the namespace filter adjudication logic. First, shouldSkipRequest (admission path) was missing adjudicateMisboundNamespace, causing bindings targeting kind: Namespace with a namespace filter to fall through to a misleading mismatch error. Second, misboundNamespace only checked definesNamespaces (literal list) but not definesNamespaceRegexes, so regex-based namespace filters on Namespace kinds were silently ignored on both admission and watch paths. Both fixes are minimal, well-placed, and accompanied by targeted tests covering literal and regex filter variants.

Confidence Score: 5/5

Safe to merge — targeted bug fix with no regressions expected.

Both changes are minimal and correct: the missing adjudicator is inserted at the right position in the chain, and the broadened predicate covers the previously-unhandled regex case. All new code paths are covered by new tests. No existing behaviour is altered for non-Namespace bindings.

No files require special attention.

Important Files Changed

Filename Overview
src/lib/filter/filter.ts Adds adjudicateMisboundNamespace to the shouldSkipRequest adjudicator chain, correctly positioned after kind-matching checks and before namespace mismatch checks.
src/lib/filter/adjudicators/postCollection.ts Broadens misboundNamespace predicate to catch both literal (definesNamespaces) and regex (definesNamespaceRegexes) namespace filters on Namespace-kind bindings.
src/lib/filter/filter.test.ts Adds admission-path tests for Namespace-kind bindings with literal and regex namespace filters, and a watch-path test for the regex case.
src/lib/filter/adjudicators/postCollection.test.ts Extends misboundNamespace unit tests to cover both regex-only and combined literal+regex namespace filter cases.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Incoming Admission Request] --> B[adjudicateMismatchedKind]
    B -->|kind mismatch| SKIP[Skip / Ignore]
    B -->|kind matches| C[adjudicateMisboundNamespace ✨ NEW]
    C -->|binding is Namespace kind\nwith namespace/regexNamespace filter| SKIP
    C -->|no misbound namespace| D[adjudicateUnbindableNamespaces]
    D --> E[adjudicateUncarryableNamespace]
    E --> F[adjudicateMismatchedNamespace]
    F --> G[adjudicateMismatchedLabels / Annotations]
    G --> H[adjudicateMismatchedNamespaceRegex]
    H --> PASS[Allow Request]

    subgraph misboundNamespace predicate
        P1[bindsToNamespace] --> P3[allPass]
        P2[anyPass\ndefinesNamespaces\ndefinesNamespaceRegexes ✨ NEW] --> P3
    end
Loading

Reviews (1): Last reviewed commit: "Merge branch 'main' into fix/missing-adj..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants