oscerd commented on PR #26974:
URL: https://github.com/apache/camel/pull/26974#issuecomment-5868438075

   Thanks — this was a genuinely useful review, and point 2 was a real bypass. 
All seven are addressed, plus the JIRA. I verified each one against the live 
SDK and a real OpenFGA 1.21.0 before changing anything, so here is the evidence 
alongside the fix.
   
   **1. Duplicate dependency — fixed.** My bug, and worse than a stray 
copy-paste: the script I used to insert the registration entries had a regex 
whose `(?:[^\n]*\n)*?` spanned many blocks, so it matched the *first* 
`<dependency>` in `dependencyManagement` (the camel core block) as well as the 
correct alphabetical slot. Removed the stray one. I also checked the other 
three registration poms in case the same helper had misfired there — 
`bom/camel-bom` and `catalog/camel-allcomponents` are correctly placed, and the 
two entries in `test-infra/camel-test-infra-all` are intentional (a 
`<dependency>` and a `<fileSet>`, as `camel-test-infra-opa` has).
   
   **2. `failOpen` too broad — fixed, and you were right that it was 
exploitable.** Confirmed against OpenFGA 1.21.0:
   
   | object (passes `OpenFgaIdentifiers`) | server |
   |---|---|
   | `document:a:b` | HTTP 400 `invalid 'object' field format` |
   | `document:x#y` | HTTP 400 `invalid 'object' field format` |
   | `nosuchtype:x` | HTTP 400 `type 'nosuchtype' not found` |
   
   `#` is legitimate in a userset *subject*, so the guards let it through as an 
object, and with `failOpen=true` and `object=document:${header.documentId}` a 
caller sending `x#y` was allowed.
   
   `failOpen` now applies only when OpenFGA could not answer. The classifier 
walks the cause chain for an `FgaError` and uses the SDK's own predicates — 
`!isClientError() || isRateLimitError()` (I checked the bytecode: 
`isClientError()` is status ∈ [400,500), `isRateLimitError()` is 429 or 
`rate_limit_exceeded`). So 4xx fails closed, 429 and 5xx and transport failures 
and timeouts still fail open, and when `failOpen` is set but does not apply the 
component logs *why* rather than denying silently.
   
   Tests: parameterized over 400/401/403/404 (deny) and 500/502/503 plus 429 
(allow), and an IT that first asserts the server really does answer 400 for 
`document:x#y` and then that the route is denied anyway. The doc's failOpen 
section now states the 4xx carve-out explicitly.
   
   **3. Invalid `consistency` — fixed.** You are right, and my code comment 
claimed the opposite of the truth. Measured:
   
   ```
   fromValue("HIGHER_CONSISTENCY") = HIGHER_CONSISTENCY
   fromValue("higher_consistency") = unknown_default_open_api
   fromValue("TYPO")               = unknown_default_open_api
   ```
   
   Now rejected at endpoint start with a message listing the three valid 
values, the comment is corrected to say what `fromValue` actually does, and 
there are tests for both the accepted values and the lowercase typo.
   
   **4. Body replacing the configured tuple — fixed, not just noted.** Agreed 
that for this component it was the wrong default. `writeTuples`/`deleteTuples` 
now use the endpoint's `user`/`relation`/`object` whenever it names any of 
them, and read the body only when it names none. A partly configured triple is 
reported as a mistake rather than completed from the message. There is an 
IMPORTANT block in "Granting and revoking access" and a test asserting that a 
body of 
`{"user":"user:attacker","relation":"owner","object":"document:secret"}` does 
not override a configured triple.
   
   **5. Docs example — fixed.** Correct: `sql:` yields a `List<Map>` whose 
entries stringify to `{ID=budget}`, fail validation, and get skipped, so the 
example returned an empty list. It now transforms the rows to `document:<id>` 
first, with a comment saying why.
   
   **6. Missing `scopes` — added** next to the rest of the client-credentials 
options.
   
   **7. `CamelOpenFgaAllowed` unset when every entry is invalid — fixed** to 
`false`, with a test.
   
   **JIRA** — `fixVersions` set to 4.23.0.
   
   90 unit tests and 12 ITs pass; the branch is rebased on current `main` and a 
full reactor leaves `git status` clean.
   
   One note for the record rather than a disagreement: this review carries a 
`_Claude Code on behalf of davsclaus_` trailer, so by the project's own 
AI-attribution convention it is an AI review under a human login. I have not 
counted it as the human approval the merge rules require, and I am not 
resolving any conversation — please close them off yourself once you have 
checked the changes.
   
   ---
   
   _Claude Code on behalf of @oscerd_
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to