Conversation
66Ton99
force-pushed
the
codex/non-fatal-secret-access-log
branch
from
August 12, 2026 13:55
b6350c3 to
c761f49
Compare
_logSecretAccesses() turned any failure of the secret_accesses insert into a 500, taking the whole index response down with it. That was tolerable while contain[secret] was rare, but both the browser extension and the mobile client now ask for it on this endpoint - the latter on every full refresh, to keep a usable local replica - so it serves whole pages of secrets on a routine background path. One failing insert would deny listing and synchronisation to every client, repeatedly, until someone fixed the cause by hand. Count the failures and report them once per request instead. Logging per secret would trade a 500 for a drowned error log: a broken audit table on a page of a few thousand resources would write one line per secret, on every synchronisation. The deliberate single secret reads in SecretsViewController and ResourcesViewController keep throwing, so the "log or deny" posture is unchanged where a human actually asked to see one secret. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
66Ton99
force-pushed
the
codex/non-fatal-secret-access-log
branch
from
August 12, 2026 19:44
c761f49 to
845f7d8
Compare
66Ton99
marked this pull request as draft
August 12, 2026 19:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
ResourcesIndexController::_logSecretAccesses()turned any failure of thesecret_accessesinsert into anInternalErrorException(500), taking the whole index response down with it.That was tolerable while
contain[secret]was a rare, deliberate request. It no longer is — both existing clients ask for it on this endpoint:findAllByIdsForShareandfindAllForDecrypt;So this endpoint serves whole pages of secrets on a routine background path, and a single failing audit insert would deny listing and synchronisation to every client — repeatedly, on every retry, until someone fixed the underlying cause by hand. An auxiliary audit table should not be able to take down the primary read path.
What
Count the failures and report them once per request via
Cake\Log\Log::error(), with the count, the user id and the first error message.Logging per secret would only trade a 500 for a drowned error log: with a broken audit table, a page of a few thousand resources would write one line per secret, on every synchronisation.
Deliberately not changed:
SecretsViewControllerandResourcesViewControllerstill throw. Those are single-secret reads a human explicitly asked for, where "log or deny" is the right audit posture. The comment in the code says so, to stop this being made uniform later without thinking.Compatibility
No client-visible change on the success path — the response is byte-identical. The request contract (
contain/filterwhitelist), serialization and response DTO are untouched; the diff is confined to thecatchbranch. The only behavioural difference is that a failed audit write now yields200with the normal body instead of500with none, which no client consumes as a feature.Trade-off worth recording
A secret can now be delivered without a matching
secret_accessesrow. That is a deliberate choice of availability over "log or deny" on the bulk path, and it belongs in the administrator documentation alongside the offline-replica caveats.Testing
vendor/bin/phpcs --standard=phpcs.xml src/Controller/Resources/ResourcesIndexController.php— clean.vendor/bin/phpstan analyse(project config, level 6) on the changed file — no errors.tests/TestCase/Controller/Resources/ResourcesIndexControllerTest.phperrors out insetUpwithPROCEDURE test.TruncateDirtyTables does not exist, insidecakephp-test-suite-light's table sniffer, before any application code runs. I confirmed this reproduces identically on a clean checkout ofmain, so it is an environment issue and not a regression from this change. Cause: the sniffer creates that procedure with a two-statementexecute(), which MySQL 8.4 does not run; CI uses MySQL 8.0, and nixpkgs has dropped 8.0 as EOL. CI on this PR runs the real suite against MySQL 8.0, MariaDB 11.5 and PostgreSQL 13.No test is added: there is no existing coverage asserting the 500, and provoking an audit-insert failure would mean mocking the association purely to observe a log line.
🤖 Generated with Claude Code