Bearer read-scope API keys bypass ticket visibility entirely — confirm this is an intentional, documented decision #70
Closed
opened 2026-09-01 00:07:09 -04:00 by jared
·
1 comment
No Branch/Tag Specified
main
development
fix/comment-markdown-persist-18
deploy-2026.10.03-279
deploy-2026.10.03-275
deploy-2026.09.26-272
deploy-2026.09.25-268
deploy-2026.09.25-264
deploy-2026.09.24-258
deploy-2026.09.24-254
deploy-2026.09.12-242
deploy-2026.09.12-238
deploy-2026.09.12-234
deploy-2026.09.12-230
deploy-2026.09.12-226
deploy-2026.09.12-222
deploy-2026.09.11-218
deploy-2026.09.11-214
deploy-2026.09.11-210
deploy-2026.09.11-206
deploy-2026.09.11-202
deploy-2026.09.11-198
deploy-2026.09.11-194
deploy-2026.09.11-190
deploy-2026.09.11-186
deploy-2026.09.09-182
deploy-2026.09.09-178
deploy-2026.09.08-172
deploy-2026.09.01-163
deploy-2026.08.08-155
deploy-2026.08.08-151
deploy-2026.08.08-147
deploy-2026.08.08-143
deploy-2026.08.08-139
deploy-2026.07.15-130
deploy-2026.07.15-122
deploy-2026.07.11-107
deploy-2026.06.30-96
deploy-2026.06.30-92
deploy-2026.06.30-88
deploy-2026.06.30-84
deploy-2026.06.30-80
deploy-2026.06.30-76
deploy-2026.06.30-72
deploy-2026.06.30-68
deploy-2026.04.29-49
deploy-2026.04.29-41
deploy-2026.04.18-35
deploy-2026.04.16-31
deploy-2026.04.16-27
deploy-2026.04.16-23
deploy-2026.04.16-11
deploy-2026.04.14-9
Labels
Clear labels
api
bug
concurrency
config
data-integrity
dead-code
documentation
duplicate
enhancement
help wanted
invalid
needs-decision
notifications
performance
priority/docs
priority/high
priority/low
priority/medium
question
rate-limiting
reliability
security
ux
wontfix
workflow
Bearer/internal API surface
Something is not working
Race condition / concurrency bug
Configuration / deployment default
Data correctness / schema / integrity issue
Unused / dead code cleanup
README / docs accuracy
This issue or pull request already exists
New feature
Need some help
Something is wrong
Needs a maintainer decision, not clearly a bug
Matrix / in-app notification bug
Performance or resource-usage concern
Documentation-only gap
High-severity / high-impact issue
Low-severity / cosmetic issue
Medium-severity issue
More information is needed
Rate limiting behavior
Reliability / error-handling gap
Security or access-control impact
User-facing UX/functional bug
This won't be fixed
Ticket status workflow engine
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: LotusGuild/tinker_tickets#70
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: High (design decision requiring explicit confirmation, not necessarily a bug)
api/tickets_api.php— both the single-ticket read path (ticketModel->getTicketById($ticketId), nocanUserAccessTicket()call) and the list/triage path ($userpassed asnull, soTicketModel::getAllTickets()'s visibility filter is skipped entirely per its own logic) bypass the app's entire visibility subsystem. There's an existing code comment explaining this is intentional ("trusted server credential, not an end user").Concern: Per the README and admin UI, a
read-scope API key can be generated for any external tool, not just hwmonDaemon — there's no way to scope a key to public-visibility-only tickets. Anyread-scope key, however it's issued or to whomever, gets blanket read access to Confidential-visibility ticket titles, descriptions, and comments. If a key is ever handed to a less-trusted integration or third party, this is a full confidentiality bypass with no visibility distinction in the API surface itself.Ask: Confirm this is the intended trust model (all API keys are equally trusted regardless of scope, by design) and if so, document it explicitly in the README's API Key Management / Bearer API sections so it's not accidentally assumed to respect visibility. If it's NOT intended, consider adding an optional visibility-scoping flag when generating a key.
Decision: restrict by default. Fixed in commit
6609320(merged to main ind0a7630).Added see_all_visibility to api_keys (migration 006), defaulting to false for both new and existing keys. api/tickets_api.php now restricts both the single-ticket read and list/triage paths to public-visibility tickets unless a key is explicitly marked see_all_visibility (new checkbox in the API Key Management admin UI). Documented in the README's API Key Management / Bearer API sections.
Verified against real MariaDB with public/confidential/internal test tickets: a public-only key's list only returns the public ticket, and per-ticket access checks correctly exclude both confidential (assigned and unassigned) and internal tickets; a see_all_visibility key sees all three, unchanged from prior behavior. Testing also caught and fixed a real edge case: the synthetic 'no access' user needed user_id=-1, not 0, since canUserAccessTicket()'s PHP-level (int) cast makes (int)null === 0 for an unassigned confidential ticket.