feat: add read-only OAuth mode for safe autonomous tool use#205
Merged
scottlovegrove merged 3 commits intomainfrom Mar 31, 2026
Merged
feat: add read-only OAuth mode for safe autonomous tool use#205scottlovegrove merged 3 commits intomainfrom
scottlovegrove merged 3 commits intomainfrom
Conversation
Add support for authenticating with a read-only OAuth token (scope `data:read`) via `td auth login --read-only`. When in read-only mode, all mutating API calls are blocked at the proxy layer before they reach the Todoist API. - Add `--read-only` flag to `td auth login` with `data:read` scope - Store auth metadata (mode, scope) in config file alongside secure token storage from #120 - Create permissions module with default-deny allowlist of safe API methods — unknown/new methods are blocked by default - Integrate permission checks into the API proxy and direct fetch calls (uploads) - Display auth mode in `td auth status` (human + JSON output) - Update README, skill content, and tests Supersedes #110. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
scottlovegrove
commented
Mar 31, 2026
Add step 3 to the add-command developer skill documenting that new read-only SDK methods must be added to KNOWN_SAFE_API_METHODS in src/lib/permissions.ts. The default-deny approach means unmapped methods are automatically blocked in read-only mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
doistbot
reviewed
Mar 31, 2026
Member
doistbot
left a comment
There was a problem hiding this comment.
This PR introduces a read-only OAuth mode to safely restrict autonomous tool use by blocking mutating API calls through a proxy and an allowlist. The implementation is well-structured and thoughtfully integrates with the recent secure store refactor to provide robust safeguards. There are a couple of minor adjustments to consider, specifically exempting standard object prototype methods from being incorrectly flagged as mutating by the proxy, and using the explicit AuthMode type instead of a generic string to improve type safety.
…e type - Exempt standard Object.prototype methods (toString, valueOf, etc.) from being incorrectly treated as mutating API methods in the proxy - Use explicit AuthMode type instead of string in formatAuthMode Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
doist-release-bot bot
added a commit
that referenced
this pull request
Mar 31, 2026
## [1.34.0](v1.33.0...v1.34.0) (2026-03-31) ### Features * add read-only OAuth mode for safe autonomous tool use ([#205](#205)) ([446756b](446756b))
Contributor
|
🎉 This PR is included in version 1.34.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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
td auth login --read-onlyflag that authenticates with OAuth scopedata:read, blocking all mutating API calls at the proxy layertd auth status(both human-readable and--jsonoutput)Supersedes #110, reimplemented against current main to accommodate the secure store refactor (#120) and command directory split (#195).
Changes
src/lib/auth.ts—AuthMode,AuthMetadata,SaveApiTokenOptionstypes;getAuthMetadata(); metadata persistence in save/clearsrc/lib/oauth.ts—readOnlyoption onbuildAuthorizationUrlsrc/lib/permissions.ts(new) —KNOWN_SAFE_API_METHODS,ensureWriteAllowed(),isMutatingApiMethod(),isMutatingSyncPayload()src/lib/api/core.ts— permission checks before mutating callssrc/lib/api/uploads.ts— directensureWriteAllowed()(bypasses proxy)src/commands/auth/{index,login,token,status}.ts—--read-onlyflag, metadata passing, mode displaypermissions.test.ts,oauth.test.ts; updated:auth.test.ts,lib-auth.test.tsREADME.md,src/lib/skills/content.ts,skills/todoist-cli/SKILL.mdTest plan
npm run type-checkpassesnpm run lint:check— 0 warnings, 0 errorsnpm run format:check— all cleantd auth login --read-only→ verify OAuth flow usesdata:readscopetd auth status→ verify mode displayedtd auth login(without--read-only) → verify switches back to read-write🤖 Generated with Claude Code