Logs verify against a set the registry key is not in - #100
Merged
Conversation
komizo-be#180 put the registry key into the one set every route verified against. Correct for commands -- it is what lets any signed-in device work -- and wrong for exactly one route. Logs are the only bytes on a box that never leave it any other way. Reports, history and metrics are PUSHED to the service by the agent, so it holds them already and a signature changes nothing about who can see them. app-only.md §5 said what that makes logs: putting the most sensitive bytes on the machine behind the same single env var, and then calling the protection structural, would be false. So there are two sets now. OperatorKeys carries the registry key; LogKeys is operator keys plus ACCOUNT log keys and does not. BUILT, NOT FILTERED. Deriving the log set by removing the registry key from the command set would be shorter and would fail OPEN the day somebody refactors the derivation -- and failing open here is silent, because a log that can be read looks exactly like a log that should be readable. AND PASSED, NOT DEFAULTED. verifiedRead now takes its key set as an argument, so every route names the one it uses and a new route cannot avoid the decision. A default would mean whoever forgot got the wider set, in the direction that does not announce itself. An account key is portable where a device key is not: its private half comes from a passphrase, so it works on any device the person signs in from. That is the property that makes this possible at all -- it was device keys being per-browser that broke the product flow in the first place, and #180 removed them from the required path for that reason. Planting one is a root action and there is no op that does it. If the service could push a log key it would push its own, and all of the above would be theatre. TestNoSignedCommandCanPlantALogKey holds the op set to it. The central test asserts BOTH halves on one box: the registry key reads the report and cannot read the log, and the account key does the opposite. Asserting only the refusal would pass against a box that refuses everything, which is this codebase's recurring failure -- the passing result indistinguishable from the not-running result. A box that commands and serves no logs is NORMAL, not broken. It is every box between #180 and an account setting a passphrase. Both enrol and serve say so in their own words, because an empty log screen otherwise sends somebody to the machine to fix something that is working as designed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Implements nicodes/komizo-be#187 and nicodes/komizo-be#188 — the box half of the account-log-key epic (komizo-be#186).
The problem
komizo-be#180 put the registry key into the one set every route verified against. That is correct for commands — it is what lets any signed-in device work — and wrong for exactly one route.
Logs are the only bytes on a box that never leave it any other way. Reports, history and metrics are pushed to the service by the agent, so it holds them already and a signature changes nothing about who can see them.
app-only.md§5 said what that makes logs:Two sets
OperatorKeyscarries the registry key.LogKeysis operator keys plus account log keys, and does not.Built, not filtered. Deriving the log set by removing the registry key from the command set would be shorter and would fail open the day somebody refactors the derivation — and failing open here is silent, because a log that can be read looks exactly like a log that should be readable.
Passed, not defaulted.
verifiedReadtakes its key set as an argument, so every route names the one it uses and a new route cannot avoid the decision.Why an account key works where a device key did not
It is portable. The private half comes from a passphrase, so it works on any device the person signs in from. Device keys being per-browser is what broke the product flow and why #180 removed them from the required path.
Planting one is a root action and there is no op that does it. If the service could push a log key it would push its own and read every log, and all of the above would be theatre.
TestNoSignedCommandCanPlantALogKeyholds the op set to that.The central test asserts both halves
One key, one box, two routes, opposite answers:
Asserting only the refusal is this codebases recurring failure: the passing result indistinguishable from the not-running result.
Mutation-tested
OperatorKeysagain (the bug)LogTrustedKeysalso returns the registry keyParseLogKeyaccepts any prefixA box with no log key is normal, not broken
It is every box between #180 and an account setting a passphrase — including the users, the moment this ships. Both
enrolandservesay so in their own words, because an empty log screen otherwise sends somebody to the machine to fix something working as designed.🤖 Generated with Claude Code