fix(channel/telegram): authorize the account that taps an approval button - #22
Open
JordanTheJet wants to merge 314 commits into
Open
fix(channel/telegram): authorize the account that taps an approval button#22JordanTheJet wants to merge 314 commits into
JordanTheJet wants to merge 314 commits into
Conversation
…eroclaw-labs#9014) - e530dd4 ci(release): notarize + staple the macOS .dmg for offline validation - da1be7e fix(ci): publish the notarized macOS DMG deterministically - 649a013 test(ci): keep desktop release guards mergeable - 40bca67 fix(ci): keep zero-DMG failure portable - be2fd5c Merge branch 'master' into ci-staple-macos-dmg
…zeroclaw-labs#9133) - b3d021f docs(architecture): record channel plugin and gateway process targets - c8c7fd6 Merge branch 'master' into codex/adr-006-007-targets
…law-labs#9130) - cec0fb1 fix(config): restore generated descriptions and code contracts - e0e0a7e fix(gateway): restore pending reload contract description - 13ebdba Merge origin/master into codex/restore-8901-contracts - a39f4ad Merge branch 'master' into codex/restore-8901-contracts
…claw-labs#9026) - b0a7138 feat(gateway/acp): select session agent via ?agent= query param - d163820 fix(gateway/acp): reject disabled agents at shared alias boundary - 28aba77 docs(acp): replace prose em-dashes in ?agent= section - 306178a fix(gateway/acp): keep ?agent= out of session restore rebind - bfcde2f Merge branch 'master' into feat/acp-agent-query-param
…9146) The hardware peripherals design doc linked to a non-existent GitHub repository. Replace it with the canonical kevinmehall/nusb repository verified through crates.io.
…8s (zeroclaw-labs#9147) Replace the nonexistent zeroclaw-templates repository link with the in-repo deploy-k8s sample manifests and correct the Helm wording.
…labs#9148) Remove optional angle brackets from two CommonMark link destinations to match the surrounding documentation style.
…9150) Remove the trailing space inside the Mattermost voice-message code span so markdownlint MD038 passes.
…rt (zeroclaw-labs#9151) Escape the line-leading zeroclaw-labs#6960 reference so markdownlint does not parse it as an ATX heading.
…zeroclaw-labs#8622) - 595c61b feat(channels): emit structured login lifecycle events for QR pairing - 5032f0e fix(log): keep QR pairing credentials off the persisted JSONL trace - 480dbd7 fix(log): flush writer before reading persisted trace in ephemeral-attrs test - 2f355cd fix(log,gateway): keep QR pairing credentials off verbose stderr and unauthenticated SSE - a6a0792 Merge upstream/master into feat/channel-login-events - 13a6205 fix(gateway,log,runtime): hold the pairing-credential boundary across every broadcast consumer - 497a22c Merge upstream/master into feat/channel-login-events - 0a2f53b style(gateway,log,runtime): rustfmt the credential-boundary test helpers - 9b9fe0d Merge upstream/master into feat/channel-login-events
…9122) - ee12041 refactor(plugins): establish canonical instance scope - 1f22dc3 fix(plugins): require adapter opt-in for HTTP - 150c82a fix(plugins): preserve callable tool attribution - caed50f docs(plugins): require grant and adapter opt-in - 03e7153 Merge branch 'master' into feat/plugin-instance-context
…zeroclaw-labs#9094) - 18b4c32 fix(zerocode): separate the literal Ctrl label from the key on darwin - 576fbc6 Merge branch 'master' into fix/darwin-ctrl-chord-display-assertion
…oclaw-labs#9165) The 'Determine version tag' step in docs-deploy.yml expanded ${{ github.event.inputs.tag }} directly into the run: script, one line before the regex that validates it. GitHub performs template interpolation before the shell executes, so a crafted workflow_dispatch tag input (e.g. '"; <cmd>; "') would run arbitrary commands before the validation could reject it — an Actions script-injection (CWE-94) in a job that holds contents: write. Pass github.event_name / event.inputs.tag / github.ref / github.ref_name through env vars and reference them as shell variables, so template values reach the shell as data and can never be interpreted as code. The validation regex and all downstream behavior are unchanged. Exploitability is low (workflow_dispatch requires repo write access and the regex bounds valid values), but this is the canonical Actions injection anti-pattern and the fix is free.
…eroclaw-labs#9152) resolve_sops_dir() only handled the None/empty case relative to the workspace; an explicit relative sops_dir (the shape shown in the documented <workspace>/sops layout) fell through to PathBuf::from(), which resolves against whatever directory the process happens to be running in rather than the workspace. Path::join already replaces the base when the joined path is absolute, so workspace_dir.join(expanded) is a strict superset: absolute and ~-prefixed values behave exactly as before, relative values now resolve against the workspace as documented.
…claw-labs#9043) - 33e3a05 docs(install): align first-run guidance with installer behavior - 41e27d4 docs(install): qualify supported prebuilt targets - 60b366 docs(install): qualify Cargo bin destination
Owner
Author
|
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.
Summary
masteridanddatabut neverfrom. Every message path in this channel authorizes the sender against the channel allowlist first; the callback path did not. An inline keyboard is visible to every member of the chat it was posted in, so the tap that answers an approval prompt now runs the sameis_any_user_allowedcheck.listen()intoresolve_approval_callback, returning a typedApprovalCallbackOutcome(NotApproval/Unauthorized/UnknownAction/Resolved). That puts the decision at a real, testable boundary instead of inline in the long-poll loop.fromaccount fails closed, including under a wildcard allowlist — a new external surface defaults closed.type:fix,risk:low,size:STesting (required)
How you can test
channel=telegramallowed_usersnaming one account, and a second account in the same group chat that is not on that list. Trigger any tool call that requests approval so the inline keyboard is posted.Approveon the prompt.master(before): The same tap resolves the approval and the tool call proceeds.How I tested
Seven new tests at the decision boundary, written before the implementation (all failed with "method not found" first):
callback_actor_identities_carry_username_and_numeric_idcallback_actor_denied_when_from_is_absent— fail-closed under a wildcard allowlistcallback_actor_denied_when_not_on_allowlistcallback_actor_allowed_by_username_or_numeric_idunauthorized_tap_does_not_resolve_a_pending_approval— asserts the oneshot is unresolved and the approval is still pendingauthorized_tap_resolves_the_pending_approvalunknown_action_from_an_allowed_actor_is_reported_not_resolvednon_approval_callback_data_is_ignored_before_any_authzlisten()loop itself is not exercised end-to-end against a live Bot API; the extractedresolve_approval_callbackis what the tests drive, andlisten()is a thin dispatch over its outcome.usernamenormalized vianormalize_identity, plus the numeric sender id). I did NOT run against a live Telegram bot.Security & Privacy Impact (required)
alice/eveand synthetic numeric idsYes, describe the risk and mitigation: N/A. This PR tightens an approval gate; the residual gap it does not close is that the check is allowlist-wide rather than bound to the specific operator who triggered the turn.