Skip to content

fix(plugins): reject unknown keys in nested config objects - #247

Open
ndreno wants to merge 1 commit into
mainfrom
fix/plugin-schemas-closed-objects
Open

ndreno wants to merge 1 commit into
mainfrom
fix/plugin-schemas-closed-objects

Conversation

@ndreno

@ndreno ndreno commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Plugin config is checked against config-schema.json at compile time (E1023). An object schema that leaves additionalProperties unset accepts any key, though. The schema roots were closed, but several nested objects weren't, so a key in the wrong place compiled and was then ignored at runtime. #146's reporter hit this: skip_if_empty placed under headers was accepted and had no effect.

Changes

Closed (additionalProperties: false), each listing exactly the keys its config struct reads:

  • request-transformer: headers, querystring, path, path.replace, body
  • response-transformer: headers, body
  • kafka and nats: ack_response

Explicitly open (true): jwt-auth's public_key_jwk, since a JWK may carry members beyond those listed (RFC 7517: use, x5t, …).

Guard: crates/barbacane-compiler/tests/plugin_schemas.rs.

  • Every object schema with properties, in every plugin's config-schema.json, must state additionalProperties (false, or true or a schema where the shape is open by design). A new plugin can't reintroduce the gap without the test failing.
  • Misplaced request-transformer keys are rejected: skip_if_empty under headers, querystring or body, an unknown path key, and an extra path.replace key.
  • A JWK with extra members is still accepted.

Behavior change: a spec with an unknown key in one of these objects now fails to compile with E1023, instead of compiling and silently ignoring the key. The CHANGELOG records it under Changed.

Testing

  • The test suite (4 tests) fails without the schema changes. On main's schemas the guard lists exactly the 10 open objects. The misplaced-key test fails on main's request-transformer schema, and the JWK test fails if public_key_jwk is closed.
  • No existing config breaks. All 61 configs for these plugins in tests/fixtures, docs/rulesets/tests and the YAML blocks of docs/ validate against the new schemas. The only exception is invalid-middleware.yaml, which is invalid on purpose.
  • docs/rulesets/generate.mjs produces no change: the lint validators check only top-level keys. docs/rulesets/tests/run-tests.sh passes.

Found while checking, not in this PR

Nine jwt-auth examples in the docs use top-level keys the schema has never allowed, so they fail E1023 today:

  • required and scopes: spec-configuration.md, dispatchers.md, extensions.md.
  • header and scheme: extensions.md.
  • secret and public_key: secrets.md.

The schema's top level was already closed, so this PR doesn't cause it. It needs its own docs fix.

Summary by CodeRabbit

  • Changed
    • Selected nested plugin configuration objects now reject unrecognized keys, producing a compilation error instead of silently ignoring them.
    • Unlisted properties remain allowed in JWT public-key JWK configuration.

A plugin config is checked against its config-schema.json at compile time
(E1023), but an object schema without `additionalProperties` accepts any
key. The roots were closed and several nested objects were not, so a key
in the wrong place compiled and was ignored at runtime: `skip_if_empty`
under request-transformer's `headers` had no effect and no error.

Closed: request-transformer `headers`, `querystring`, `path`,
`path.replace`, `body`; response-transformer `headers`, `body`; kafka and
nats `ack_response`. Each lists exactly the keys its config struct reads.
jwt-auth's `public_key_jwk` is marked open (`true`), since a JWK may carry
members beyond those listed (RFC 7517).

crates/barbacane-compiler/tests/plugin_schemas.rs requires every object
schema with `properties` in every plugin to state `additionalProperties`,
checks that misplaced request-transformer keys are rejected and that a
JWK with extra members is accepted. Each fails without the schema change.
Every config in the fixtures and docs still validates.

Signed-off-by: Nicolas Dreno <nicolas.dreno@barbacane.dev>
@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (1)
CLAUDE.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: barbacane-dev/barbacane/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 169e5459-b922-41cb-932b-c21f835dd674

📥 Commits

Reviewing files that changed from the base of the PR and between ba339c7 and 7b7961a.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • crates/barbacane-compiler/tests/plugin_schemas.rs
  • plugins/jwt-auth/config-schema.json
  • plugins/kafka/config-schema.json
  • plugins/nats/config-schema.json
  • plugins/request-transformer/config-schema.json
  • plugins/response-transformer/config-schema.json

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Selected plugin configuration objects now reject undeclared keys during compilation. The JWT-auth public_key_jwk object permits additional keys. Compiler tests check plugin schema declarations and validate selected request-transformer and JWT-auth configurations.

Changes

Plugin configuration validation

Layer / File(s) Summary
Set additional-property rules
plugins/*/config-schema.json
Selected request-transformer, response-transformer, Kafka, and NATS objects reject undeclared properties. The JWT-auth public_key_jwk schema permits additional properties.
Check schema declarations and configuration values
crates/barbacane-compiler/tests/plugin_schemas.rs, CHANGELOG.md
Compiler tests recursively check plugin schemas for object declarations that omit additionalProperties. They also check selected request-transformer keys and JWT JWK members. The changelog records the schema changes and tests.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Low

Merge Risk: ⚪ Minimal · up to 7b796

Selected plugin configs now reject unknown nested keys, so misplaced keys fail at compile time. No merge-blocking risk was identified.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 7b796

Plugin configuration becomes stricter without an identified expansion of access or weakening of authentication. Existing specifications containing previously ignored keys may need correction before recompilation.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated exposure is configuration acceptance for affected middleware and dispatch plugins. The change narrows accepted configuration shapes; it does not establish additional tenant, service, data-store, credential, or network authority.

Trust Boundaries and Controls

  • observed — Making public_key_jwk explicitly open preserves its previous JSON Schema acceptance behavior; it does not newly admit additional members. Existing declared member constraints remain, and a regression test asserts acceptance of an unlisted x5t member. This is schema-level counterevidence to an authentication-boundary relaxation, not verification of the complete JWT runtime.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 1 files. (6 skipped: 6… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: rejecting unknown keys in nested plugin configuration objects.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 1 files. (6 skipped: 6 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ndreno ndreno added the deep-review Ask CodeRabbit for a full review label Oct 1, 2026

This branch has not been deployed

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

Labels

deep-review Ask CodeRabbit for a full review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant