Skip to content

feat(config): implement endpoint anchors (D1-D5)#74

Merged
OliverWolffGIP merged 9 commits into
mainfrom
feature/plan-03-endpoint-anchors
Jul 18, 2026
Merged

feat(config): implement endpoint anchors (D1-D5)#74
OliverWolffGIP merged 9 commits into
mainfrom
feature/plan-03-endpoint-anchors

Conversation

@OliverWolffGIP

@OliverWolffGIP OliverWolffGIP commented Jul 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements doc/plan/03-endpoint-anchors.adoc in full — all five design decisions (D1-D5) — governed by ADR-0007 (endpoint anchors) and ADR-0009 (single-reporter disjointness move).

  • D1: gateway.schema.json / endpoint.schema.json gain an optional anchors map (name → path_prefix + policy blocks) and optional anchor refs on endpoint/route, with shared $defs; endpoint auth becomes optional.
  • D2: New AnchorConfig record; GatewayConfig/EndpointConfig/RouteConfig gain anchor fields; RouteTableBuilder resolves gateway -> anchor -> endpoint -> route (wholesale replacement) into ResolvedRoute (effective auth/methods/security_filter/security_headers), preserving weakening WARNs and adding a per-route effective-posture INFO LogRecord.
  • D3: All seven ConfigValidator rules (prefix disjointness, anchor exists, route-inside-prefix, undeclared squatter, non-weakenable auth floor, endpoint-auth conditional mandatoriness, effective-auth completeness) in the existing all-violations convention, each with a negative test.
  • D4: A single ${VAR} / ${VAR:-default} pre-schema substitution pass across gateway.yaml, endpoints/*.yaml, and topology.properties, with loud failure on a non-matching ${ and secrets classified pre-substitution; the convention-named TOPOLOGY_<ALIAS> (TopologyResolver) and ENDPOINT_<ID>_ENABLED (EndpointEnablementResolver) machinery is deleted outright (dead code per PR fix(config): close Plan-02/01 landing gaps from post-merge review #64 landing-gap note).
  • D5: Seven hardening fixes — trusted_proxies CIDR parsing with an address-space-coverage trust-all guard, http/https-only upstream scheme allowlist in TopologyResolver, prefix normalization ahead of disjointness/containment checks (with the same-prefix route-disjointness check moved into the all-violations ConfigValidator pass per ADR-0009), stray *.yml boot failure under endpoints/, sanitized binding-error messages (no resolved scalar, including secrets, is ever logged), explicit YAML StreamReadConstraints / alias-expansion limits, and a doc-only fix reconciling the header-matcher disjointness description in configuration.adoc.

Changes

  • api-sheriff/src/main/resources/schema/gateway.schema.json, endpoint.schema.jsonanchors map and anchor refs (D1)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/model/AnchorConfig.java (new), GatewayConfig.java, EndpointConfig.java, RouteConfig.java, ResolvedRoute.java — anchor-aware config model (D2)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/RouteTableBuilder.java — anchor resolution chain and effective-posture logging (D2)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/validation/ConfigValidator.java — seven anchor validation rules (D3)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/load/ConfigLoader.java, EnvSecretResolver.java (new) — ${VAR} substitution pass and pre-substitution secrets classification (D4)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/topology/TopologyResolver.java, EndpointEnablementResolver.java — env-override machinery deleted; scheme allowlist and CIDR trust-all guard added (D4, D5)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/ConfigLogMessages.java — new effective-posture LogRecord
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/quarkus/ConfigModelReflection.java, ConfigProducer.java — native-reflection and CDI wiring for the new model
  • api-sheriff/src/test/** — unit tests for the above, including ConfigFailFastTest.java (squatter-route boot refusal)
  • api-sheriff/src/test/resources/config/anchor-squatter/**, anchored/** — new anchor-violation and anchored fixtures
  • integration-tests/src/main/docker/sheriff-config/**, integration-tests/src/test/java/.../ConfigLoadedIntegrationIT.java, integration-tests/scripts/verify-invalid-config-fails.sh — anchor-block sample configs and anchor-violation IT variant
  • doc/adr/0007-anchor-scoped-policy.adoc — flipped to Accepted
  • doc/configuration.adoc, doc/LogMessages.adoc — Anchors/validation-rules documentation and the new LogRecord entry

Test Plan

  • Verification command passed (verify -Ppre-commit)
  • Manual testing completed (if applicable)

Related Issues

None.


Generated by plan-finalize skill

Summary by CodeRabbit

  • New Features
    • Added named policy anchors for shared routing, authentication, security filters, headers, and allowed methods, with inheritance and route-level overrides.
    • Added ${VAR} / ${VAR:-default} placeholder support and tightened placeholder validation across config and topology.
    • Added effective route posture reporting plus WARNs for weak policy overrides and overly broad trusted-proxy CIDRs.
  • Bug Fixes
    • Improved YAML hardening, schema/config validation, and error reporting without exposing secret values; endpoints now reject .yml files.
    • Strengthened anchor, route, and CIDR/forwarded-trust consistency checks.
  • Documentation
    • Updated placeholder grammar, anchor behavior, route disjointness rules, and structured log message catalog.

OliverWolffGIP and others added 3 commits July 18, 2026 17:22
…-time hardening (D1-D5)

Implements Plan 03 D1-D5: anchor-scoped policy inheritance (ADR-0007, flipped to Accepted), the single ${VAR}/${VAR:-default} substitution engine replacing convention-named env overrides (EndpointEnablementResolver removed; TopologyResolver TOPOLOGY_ lookup dropped), and seven config-subsystem boot-time fixes (real-CIDR trusted_proxies with full-space rejection and broad-prefix WARN, same-prefix route-disjointness moved to ConfigValidator, http/https topology scheme allowlist, stray .yml rejection, secret-safe binding errors, YAML expansion limits). Integration configs gain api+bff anchors and an anchor-violation negative check; docs reconciled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-102

Collapse the byte-identical normalizePrefix duplicate in ConfigValidator
onto the shared RouteTableBuilder implementation, and add the missing
ApiSheriff-102 (broad trusted_proxies prefix) row to doc/LogMessages.adoc.

Co-Authored-By: Claude <noreply@anthropic.com>
TopologyResolver.decompose() echoed the fully substituted topology URL
into TopologyResolutionException messages (malformed URI, missing
scheme/host, disallowed scheme), which ConfigProducer logs at ERROR.
Keep only the alias name / offending scheme, mirroring the redaction
contract EnvSecretResolver and ConfigLoader already enforce (CWE-209).

Co-Authored-By: Claude <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @OliverWolffGIP, your pull request is larger than the review limit of 150000 diff characters

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@OliverWolffGIP, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository: cuioss/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 85f41589-59cc-49dd-bbf9-6d21c379f3d5

📥 Commits

Reviewing files that changed from the base of the PR and between 689aed5 and bd81dc3.

📒 Files selected for processing (5)
  • .plan/project-architecture/api-sheriff/enriched.json
  • .plan/project-architecture/integration-tests/enriched.json
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/validation/ConfigValidator.java
  • doc/adr/0010-YAML_expansion_limits_enforced_in_a_compose-only_pre-pass_before_bind.adoc
  • integration-tests/scripts/verify-invalid-config-fails.sh
📝 Walkthrough

Walkthrough

The configuration pipeline adds namespace-scoped policy anchors, richer placeholder substitution, anchor-aware validation, effective route posture materialization, structured logging, and expanded unit, integration, and fail-fast coverage.

Changes

Anchor policy and configuration pipeline

Layer / File(s) Summary
Anchor model and schema contracts
api-sheriff/src/main/java/de/cuioss/sheriff/api/config/model/*, api-sheriff/src/main/resources/schema/*
Adds anchor configuration, optional endpoint authentication, route anchor overrides, effective route policy fields, and reusable schema definitions.
Placeholder substitution and boot loading
api-sheriff/src/main/java/de/cuioss/sheriff/api/config/load/*, api-sheriff/src/main/java/de/cuioss/sheriff/api/config/topology/*
Adds defaulted placeholders, malformed-placeholder handling, pre-schema substitution, YAML hardening, topology placeholder resolution, and shared resolver wiring.
Anchor validation and effective route assembly
api-sheriff/src/main/java/de/cuioss/sheriff/api/config/validation/ConfigValidator.java, api-sheriff/src/main/java/de/cuioss/sheriff/api/config/RouteTableBuilder.java
Validates anchor namespaces, effective authentication, route disjointness, and trusted-proxy CIDR coverage while materializing inherited route posture and logging overrides.
Tests and integration fixtures
api-sheriff/src/test/*, integration-tests/*
Expands model, loader, resolver, validator, route assembly, fail-fast, and anchored integration coverage.
Documentation and log catalog
doc/*, api-sheriff/src/main/java/de/cuioss/sheriff/api/config/ConfigLogMessages.java
Documents accepted anchor policy, placeholder grammar, disjointness rules, and new structured route and validation log records.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • cuioss/API-Sheriff#60: Earlier configuration, route-table, placeholder, topology, validation, and logging changes in the same subsystem.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: implementing endpoint anchors.

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements policy anchors (ADR-0007) and visible in-file placeholder substitution (D4) across the configuration boot pipeline, while moving route disjointness checks to the validator (ADR-0009) and hardening YAML loading. The review feedback highlights two important issues: first, the global scalar coercion in ConfigLoader may incorrectly convert string-typed fields (like secrets or IDs) to booleans or integers if their resolved values resemble those types, causing strict schema validation to fail; second, the public static normalizePrefix method in RouteTableBuilder lacks a defensive null check, which could lead to unexpected NullPointerExceptions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Nitpick comments (2)
api-sheriff/src/test/java/de/cuioss/sheriff/api/config/validation/ConfigValidatorTest.java (1)

427-440: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert that tightly scoped CIDRs emit no broad-range WARN.

The test name promises “without warning,” but the assertions only prove that validation succeeds. Add a negative WARN assertion so a threshold regression that warns for 10.0.0.0/8 or 2001:db8::/32 is detected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@api-sheriff/src/test/java/de/cuioss/sheriff/api/config/validation/ConfigValidatorTest.java`
around lines 427 - 440, Update shouldAcceptTightlyScopedCidrs in
ConfigValidatorTest to assert that validation produces no broad-range WARN for
either 10.0.0.0/8 or 2001:db8::/32. Keep the existing trusted_proxies validation
assertion and use the returned ConfigError details to specifically reject the
relevant warning.
api-sheriff/src/test/java/de/cuioss/sheriff/api/quarkus/ConfigFailFastTest.java (1)

88-94: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin this failure to the squatter validation rule.

assertThrows(IllegalStateException.class) also passes if the fixture later fails for an unrelated loading, topology, or schema problem. Assert the ERROR log contains the namespace diagnostic, such as does not declare it.

Proposed assertion
 assertThrows(IllegalStateException.class, producer::gatewayConfig,
         "an undeclared squatter route inside an anchor namespace must refuse boot");
+LogAsserts.assertLogMessagePresentContaining(TestLogLevel.ERROR, "does not declare it");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@api-sheriff/src/test/java/de/cuioss/sheriff/api/quarkus/ConfigFailFastTest.java`
around lines 88 - 94, Strengthen shouldRefuseBootOnAnAnchorSquatterConfig by
capturing the ERROR log produced during producer.gatewayConfig and asserting it
contains the namespace diagnostic “does not declare it”. Keep the existing
IllegalStateException assertion, but ensure the test specifically verifies the
squatter validation rule rather than any unrelated boot failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@api-sheriff/src/main/java/de/cuioss/sheriff/api/config/load/ConfigLoader.java`:
- Around line 310-329: Update ConfigLoader.coerce and its callers to be
destination-type aware: preserve whole-value placeholders as TextNode by
default, and only convert values such as “true” or numeric strings when the
target schema expects boolean or integer. Pass the expected schema type through
the placeholder-resolution path, while retaining existing integer range handling
for integer destinations.

In
`@api-sheriff/src/main/java/de/cuioss/sheriff/api/config/load/EnvSecretResolver.java`:
- Around line 56-58: Update EnvSecretResolver’s placeholder parsing and
assertNoMalformedPlaceholder validation to reject any nested “${” sequence
within a placeholder default, including `${A:-${B}}`, instead of treating the
inner expression as resolved text. Add a malformed-placeholder test covering
this nested-default case.

In
`@api-sheriff/src/main/java/de/cuioss/sheriff/api/config/validation/ConfigValidator.java`:
- Around line 95-106: Update validateEffectiveAuth and its related
auth-validation flow to resolve an Optional<AuthConfig> for every route,
including route-specific anchors and auth overrides, rather than checking only
the endpoint anchor. Report routes with missing auth configuration at
/endpoint/routes, then derive bearer and session requirements only from present
route values so both route-provided auth and auth-less overrides are validated
correctly.
- Around line 621-625: Update prefixContains so a normalized root container "/"
is treated as containing every normalized candidate path; preserve exact-match
and owner-prefix behavior for non-root containers, while avoiding the owner +
"/" double-slash check.
- Around line 215-217: Update hostsOverlap to compare present route hosts
case-insensitively, such as by normalizing both host values before equality
comparison, while preserving the existing behavior that empty hosts overlap with
any host.

In `@api-sheriff/src/main/resources/schema/gateway.schema.json`:
- Around line 138-152: The CORS validation in ConfigValidator.validateCors
currently checks only gateway.securityHeaders(); update it to also validate
security_headers from every configured anchor under anchors. Apply the same
allow_credentials with wildcard-origin rule to each anchor policy, while
preserving the existing gateway validation behavior.

In
`@api-sheriff/src/test/java/de/cuioss/sheriff/api/config/load/ConfigLoaderTest.java`:
- Around line 404-413: Update rejectsYamlExceedingAliasExpansionLimit to use a
schema-valid YAML document while retaining alias expansion beyond the configured
limit, then assert the thrown ConfigLoadException contains the parser’s
alias-expansion-limit diagnostic. Ensure the test cannot pass solely because
schema validation rejects unknown properties.

In `@doc/configuration.adoc`:
- Around line 408-412: Update the validation summary around the existing
differing-exact-header-values text to also state that opposite presence
assertions, present: true versus present: false for the same header at the same
prefix, are disjoint. Keep the clarification that a lone present: true does not
establish a conflict.
- Around line 89-101: Update the topology override passages around the earlier
descriptions to remove any implication of automatic environment-over-file
lookup. State that topology and enablement values can be overridden only through
explicit in-file `${VAR}` or `${VAR:-default}` placeholders, consistent with the
placeholder resolution rules already documented.

In `@integration-tests/scripts/verify-invalid-config-fails.sh`:
- Around line 72-79: Update verify-invalid-config-fails.sh so each test
explicitly asserts that the container logs contain the expected ${marker},
rather than merely printing matching lines. Preserve the existing non-zero exit
check, but fail with a clear error when ${marker} is absent, ensuring unrelated
startup failures cannot satisfy the validation test.

---

Nitpick comments:
In
`@api-sheriff/src/test/java/de/cuioss/sheriff/api/config/validation/ConfigValidatorTest.java`:
- Around line 427-440: Update shouldAcceptTightlyScopedCidrs in
ConfigValidatorTest to assert that validation produces no broad-range WARN for
either 10.0.0.0/8 or 2001:db8::/32. Keep the existing trusted_proxies validation
assertion and use the returned ConfigError details to specifically reject the
relevant warning.

In
`@api-sheriff/src/test/java/de/cuioss/sheriff/api/quarkus/ConfigFailFastTest.java`:
- Around line 88-94: Strengthen shouldRefuseBootOnAnAnchorSquatterConfig by
capturing the ERROR log produced during producer.gatewayConfig and asserting it
contains the namespace diagnostic “does not declare it”. Keep the existing
IllegalStateException assertion, but ensure the test specifically verifies the
squatter validation rule rather than any unrelated boot failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: cuioss/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 73976a11-6005-4ba9-8360-da2682b4d250

📥 Commits

Reviewing files that changed from the base of the PR and between ef766c9 and 077a517.

📒 Files selected for processing (39)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/ConfigLogMessages.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/RouteTableBuilder.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/load/ConfigLoader.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/load/EnvSecretResolver.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/model/AnchorConfig.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/model/EndpointConfig.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/model/GatewayConfig.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/model/ResolvedRoute.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/model/RouteConfig.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/topology/EndpointEnablementResolver.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/topology/TopologyResolver.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/topology/package-info.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/validation/ConfigValidator.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/quarkus/ConfigModelReflection.java
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/quarkus/ConfigProducer.java
  • api-sheriff/src/main/resources/schema/endpoint.schema.json
  • api-sheriff/src/main/resources/schema/gateway.schema.json
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/RouteTableBuilderTest.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/load/ConfigLoaderTest.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/load/EnvSecretResolverTest.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/model/ConfigModelContractTest.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/topology/EndpointEnablementResolverTest.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/topology/TopologyResolverTest.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/validation/ConfigValidatorTest.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/quarkus/ConfigFailFastTest.java
  • api-sheriff/src/test/resources/config/anchor-squatter/endpoints/squatter.yaml
  • api-sheriff/src/test/resources/config/anchor-squatter/gateway.yaml
  • api-sheriff/src/test/resources/config/anchor-squatter/topology.properties
  • api-sheriff/src/test/resources/config/anchored/endpoints/api.yaml
  • api-sheriff/src/test/resources/config/anchored/endpoints/bff.yaml
  • api-sheriff/src/test/resources/config/anchored/gateway.yaml
  • api-sheriff/src/test/resources/config/anchored/topology.properties
  • doc/LogMessages.adoc
  • doc/adr/0007-anchor-scoped-policy.adoc
  • doc/configuration.adoc
  • integration-tests/scripts/verify-invalid-config-fails.sh
  • integration-tests/src/main/docker/sheriff-config/endpoints/httpbin.yaml
  • integration-tests/src/main/docker/sheriff-config/gateway.yaml
  • integration-tests/src/test/java/de/cuioss/sheriff/api/integration/ConfigLoadedIntegrationIT.java
💤 Files with no reviewable changes (2)
  • api-sheriff/src/main/java/de/cuioss/sheriff/api/config/topology/EndpointEnablementResolver.java
  • api-sheriff/src/test/java/de/cuioss/sheriff/api/config/topology/EndpointEnablementResolverTest.java

Comment thread api-sheriff/src/main/resources/schema/gateway.schema.json
Comment thread doc/configuration.adoc
Comment thread doc/configuration.adoc
Comment thread integration-tests/scripts/verify-invalid-config-fails.sh Outdated
OliverWolffGIP and others added 6 commits July 18, 2026 18:31
Sonar java:S3655 flagged anchor.get() in validateAnchorAuthFloor as an
unguarded Optional access (unprovable-though-safe via the derived
anchorRequire). Restructure with an explicit isEmpty() continue so the
access is guarded; behavior unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
… and YAML alias-bomb guard

TASK-012: rewrite the ConfigValidator auth-mandatoriness rule to check per-route via the route->endpoint->anchor resolution chain (the same chain RouteTableBuilder uses). A config where every route self-declares auth is no longer falsely rejected, and a route overriding to an auth-less anchor is now caught in the ADR-0009 all-violations pass instead of escaping to a RouteTableException at boot.

TASK-013: add a SnakeYAML-native compose-only pre-pass to ConfigLoader that actually enforces setMaxAliasesForCollections. Jackson's YAMLParser consumes SnakeYAML's event stream directly and never runs the Composer, so the alias-expansion cap was inert on the readTree path; the alias-bomb test now asserts the alias-specific diagnostic so it fails loudly if the guard regresses.

Also folds in the unified-triage review fixes: RouteTableBuilder null-check, EnvSecretResolver nested-placeholder rejection, ConfigValidator host/prefix/anchor-CORS validation, ConfigValidatorTest/ConfigFailFastTest/EnvSecretResolverTest nitpicks, doc/configuration.adoc wording, and the verify-invalid-config-fails.sh marker assertion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Yaml.composeAll()'s iterator never yields null (verified against
snakeyaml 2.6), so Objects.requireNonNull in withinExpansionLimits was
dead code implying a false hazard. Drive the composer with a plain
iterator loop instead; the alias/nesting caps still fire.

Co-Authored-By: Claude <noreply@anthropic.com>
- hostsOverlap: hoist both host() Optionals into locals so the isEmpty
  guard provably covers the get() accesses (Sonar java:S3655 flagged the
  repeated accessor calls).
- verify-invalid-config-fails.sh: assert on the unknown property KEY
  (unknown_key, carried in the ApiSheriff-200 pointer) instead of the
  rejected raw value, which the D5 binding-error redaction deliberately
  keeps out of the logs.

Co-Authored-By: Claude <noreply@anthropic.com>
mktemp -d yields a 700-permission directory; the distroless image runs
non-root, so the mounted gateway.yaml was unreadable and the container
failed on "configuration file not found" instead of the validation under
test (the old script passed for the wrong reason — any non-zero exit
counted). chmod the temp dirs/files so the schema-invalid and
anchor-violation configs are actually parsed and the asserted markers
appear.

Co-Authored-By: Claude <noreply@anthropic.com>
ADR-0010 (Proposed): YAML anchor/alias expansion limits are enforced in
a SnakeYAML compose-only pre-pass before the Jackson bind — Jackson's
event-stream path never runs the Composer, the only layer that counts
collection aliases, so bind-side LoaderOptions caps are inert.

Also persists the lessons-capture architecture hints (IT profile not
covered by local pre-commit; package-info in deletion sweeps) into the
per-module enriched.json descriptors.

Co-Authored-By: Claude <noreply@anthropic.com>
@OliverWolffGIP
OliverWolffGIP enabled auto-merge July 18, 2026 20:52
@OliverWolffGIP
OliverWolffGIP added this pull request to the merge queue Jul 18, 2026
Merged via the queue into main with commit a9fd717 Jul 18, 2026
24 checks passed
@OliverWolffGIP
OliverWolffGIP deleted the feature/plan-03-endpoint-anchors branch July 18, 2026 21:00
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