Skip to content

feat(oauth): drop Cloud Console setup; ship embedded verified client#332

Open
cpcloud wants to merge 10 commits into
kenn-io:mainfrom
cpcloud:worktree-drifting-doodling-pine
Open

feat(oauth): drop Cloud Console setup; ship embedded verified client#332
cpcloud wants to merge 10 commits into
kenn-io:mainfrom
cpcloud:worktree-drifting-doodling-pine

Conversation

@cpcloud
Copy link
Copy Markdown
Contributor

@cpcloud cpcloud commented May 21, 2026

Closes #89.
Closes #259.

What changed

  • msgvault ships with an embedded, centrally-verified Google OAuth client. First-time setup no longer requires creating a Google Cloud project.
  • BYO ([oauth] client_secrets) and named-app routing (--oauth-app NAME) remain as advanced fallbacks for Workspace orgs that block third-party apps, custom-quota needs, or fallback during the verification window.
  • Service-account paths (Workspace domain-wide delegation) are unchanged.

Why

Forcing every user to create a Google Cloud project, enable the Gmail API, and configure an OAuth consent screen before they could sync any mail was the biggest onboarding wall — #89 documented users walking away at this step. Eliminating it makes msgvault usable by people who want to archive Gmail without learning Google's developer console.

Note on embedding OAuth credentials

The "client secret" for a desktop OAuth app isn't actually secret once the binary ships — anyone with the binary can extract it. Google says so directly in their OAuth 2.0 docs under "Installed applications": "The process results in a client ID and, in some cases, a client secret, which you embed in the source code of your application. (In this context, the client secret is obviously not treated as a secret.)"

This PR uses the same hybrid pattern the GitHub CLI uses, where gh bakes its production oauthClientSecret directly into source under the comment // This value is safe to be embedded in version control. Source defaults live in internal/oauth/embedded.go; release builds override them via -X ldflags sourced from GitHub Actions Secrets.

How to use

msgvault init-db
msgvault add-account you@gmail.com   # opens browser; no other setup
msgvault sync-full you@gmail.com
msgvault tui

See README's "Advanced: bring your own OAuth client" for the BYO path. Full design in docs/superpowers/specs/2026-05-20-centralized-oauth-design.md.

Pre-merge checklist

Merge-blocking:

  • Resolve internal/oauth/embedded.go TBD-* placeholder defaults: either bake in production credentials at source, or change to empty strings so source builds without ldflags fall back to BYO
  • Create production Google Cloud project, configure OAuth consent screen (app name, privacy policy URL, logo, support email), and create a Desktop OAuth 2.0 client
  • Add MSGVAULT_OAUTH_CLIENT_ID and MSGVAULT_OAUTH_CLIENT_SECRET to wesm/msgvault GitHub Actions Secrets (release builds now fail-fast if either is empty)
  • Cut one release tag and smoke-test the artifact end-to-end on a fresh MSGVAULT_HOME: add-account → consent → sync-full --limit 5

Operational follow-ups (out of band, not merge-blocking but track separately):

  • Submit the production OAuth client for Google verification (restricted scopes: gmail.readonly, gmail.modify, mail.google.com/)
  • Plan a CASA Tier 2 assessment — required by Google for restricted scopes; the 100-grant lifetime cap on unverified restricted-scope clients applies from the first grant

@cpcloud cpcloud requested a review from wesm as a code owner May 21, 2026 16:03
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented May 21, 2026

roborev: Combined Review (b2c83ff)

Medium: the PR has one blocking correctness issue around placeholder embedded OAuth credentials.

Medium

  • internal/oauth/embedded.go:20 - The embedded OAuth defaults are non-empty "TBD-..." placeholders, so HasEmbeddedCredentials() treats them as valid. Source builds or local make build runs without injected env vars will fall through to embedded OAuth and attempt authentication with an invalid client, despite the quick start saying no OAuth setup is required.

    Fix: Replace the placeholders with real dev OAuth credentials before merging, or make HasEmbeddedCredentials() reject placeholder values and return an actionable BYO/configuration error.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented May 21, 2026

roborev: Combined Review (5a7e134)

Verdict: No medium, high, or critical findings were reported.

All reported issues were below medium severity, so there are no findings to include under the requested threshold.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@mariusvniekerk mariusvniekerk force-pushed the worktree-drifting-doodling-pine branch from 5a7e134 to 1093c73 Compare May 22, 2026 22:12
@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented May 22, 2026

roborev: Combined Review (1093c73)

High severity issue found: module path mismatch will break the new resolver/build metadata.

High

  • cmd/msgvault/cmd/oauth_resolve.go:6
    The new resolver imports go.kenn.io/msgvault/internal/..., but this repository’s module path is github.com/wesm/msgvault. The same mismatch is also reported in the new tests and Makefile ldflags, so the added code and local build metadata are not consistently targeting this module’s packages.
    Fix: Replace go.kenn.io/msgvault with github.com/wesm/msgvault in the new Go imports and Makefile -X paths.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented May 22, 2026

roborev: Combined Review (1093c73)

High-level verdict: changes need revision due to a module path mismatch that will break builds.

High

  • cmd/msgvault/cmd/oauth_resolve.go:6 - The new resolver imports go.kenn.io/msgvault/internal/..., but this repository’s module path is github.com/wesm/msgvault. The same mismatch is also reported in the new tests and Makefile ldflags, so the added code and local build metadata are not consistently targeting this module’s packages.

    Fix: Replace go.kenn.io/msgvault with github.com/wesm/msgvault in the new Go imports and Makefile -X paths.


Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented May 23, 2026

roborev: Combined Review (670002f)

High-risk issues remain: OAuth build-time injection is inconsistent, one compile issue is reported, and default-token migration has a behavioral gap.

High

  • internal/oauth/oauth.go

    • HasScope uses slices.Contains, but slices is not imported.
    • Fix: Add "slices" to the import block.
  • .github/workflows/release.yml:64; Makefile:10-12,16-17

    • OAuth/version ldflags -X package paths are inconsistent between the release workflow and Makefile (github.com/wesm/msgvault/... vs go.kenn.io/msgvault/...). If the path does not match the actual built package path, release or local binaries may silently miss injected version metadata and embedded OAuth credentials.
    • Fix: Align all ldflags -X entries in both files to the actual module/package path used by the built package.

Medium

  • cmd/msgvault/cmd/addaccount.go:200
    • add-account still skips TokenMatchesClient for the default OAuth binding because needsClientCheck is false when resolvedApp == "". A user with an existing BYO token who removes [oauth] client_secrets may be told the account is already authorized, leaving a token minted for the old client in place; later refresh can fail under the embedded client.
    • Fix: Require the client identity check when resolving through the embedded client, or whenever the active manager’s client ID may differ from the stored token.

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@roborev-ci
Copy link
Copy Markdown

roborev-ci Bot commented May 23, 2026

roborev: Combined Review (41ef2ee)

Summary verdict: Changes are not ready; module path mismatches will break imports and OAuth credential injection.

High

Inconsistent module path references

Locations: cmd/msgvault/cmd/oauth_resolve.go:8, cmd/msgvault/cmd/oauth_resolve_test.go:10, cmd/msgvault/cmd/addaccount_test.go:15, Makefile:14

The new OAuth resolver code, tests, and linker flags reference go.kenn.io/msgvault/..., but this repository’s module path is github.com/wesm/msgvault. This can cause compilation failures and prevents MSGVAULT_OAUTH_CLIENT_ID / MSGVAULT_OAUTH_CLIENT_SECRET from overriding embedded credentials during make build or make build-release.

Fix: Update all new module references to match go.mod:

github.com/wesm/msgvault/internal/config
github.com/wesm/msgvault/internal/oauth

And update the linker targets to:

github.com/wesm/msgvault/internal/oauth.oauthClientID
github.com/wesm/msgvault/internal/oauth.oauthClientSecret

Synthesized from 3 reviews (agents: codex, gemini | types: default, security)

@mariusvniekerk
Copy link
Copy Markdown
Contributor

refine-pr note: the latest roborev PR comment appears stale/incorrect. Current go.mod declares module go.kenn.io/msgvault, and the resolver imports plus Makefile ldflags now use go.kenn.io/msgvault/.... CI confirms this head builds/tests successfully, including nix-build, and the GitHub roborev status for 41ef2ee is passing. roborev wait reports no local job for HEAD to close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When using serve, allow to bypass google account? Material explaining Google

2 participants