mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 19:56:53 +00:00
allows() is called once per /v1/chat/completions and nowhere else, so the 60s cache saved two Keycloak admin GETs on a request that then runs an LLM inference. On an authorization decision that is not a trade worth making.
It produced the CI failure directly. The spec walks hermes then openclaw: it grants biber only hermes, the hermes completion re-reads and stores {hermes}, then it swaps the grant to openclaw. Open WebUI sees the new group on the fresh sign-in, which is why the models assertion passes, but about eight seconds later the openclaw completion hits a fresh cache entry, reads {hermes} and refuses. A hit returned the value without re-stamping the timestamp, so all three attempts - 13.9s, 15.2s, 15.2s - stayed inside one 60s window and failed identically.
The same cache was a security defect in the other direction: a revoked caller stayed entitled for up to a minute, contradicting requirement 037's own sentence that the broker refuses the request and stops the agent once a caller has lost the group. Step 3 of that document now says the groups are resolved on every completion, which is what the code does. The admin-token cache is untouched - that is a credential lifetime bounded by expires_in, not an entitlement answer.
Verified with a negative control: the CI scenario run against the real access.py through a transport fake, alongside a transcription of the pre-fix groups_of over the same transport. Pre-fix, the swapped-group check returns False, which is the CI failure; post-fix it returns True, and a revocation between two checks is seen by the second.
The repository had already worked around this twice: files/test/test.sh slept 65 seconds after granting a membership and membership.py constructed the client with the cache disabled. Both are removed.
The group-to-agent mapping was not at fault - broker and spec derive the path from the identical rbac_group_path expression, and the sibling spec that holds both groups passed.
Each completion now costs two Keycloak admin round trips, unmeasured on an onion deployment where KEYCLOAK_URL is a .onion against a 15s per-call timeout. The unit test that asserted the cached answer is replaced by two that encode the CI failure. Requirement 037 still has 47 translated catalogs carrying the removed access_cache_seconds row; the i18n tests pass, so it is obsolete rather than broken.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>