Agent SaaS Starter
Guides

Authentication validation

Review findings, executable checks, and live client evidence.

Live client tests

Tested on September 14, 2026, using a Jio Large VM (4 vCPU, 8 GiB RAM), Ubuntu, PostgreSQL, release Rust binaries, and production Next.js builds behind public HTTPS. The initial OAuth integration was reviewed at 0200318, based on bd7483181ca781141d92da8bc50b86d2d8481442.

PathObserved result
Browser registration and password sign-inApplication session and dashboard worked
ChatGPT web OAuthPublished CIMD identity, sign-in and project consent succeeded
ChatGPT tool callget_random_number called the protected API and returned 84
Claude web OAuthPublished CIMD identity, sign-in and project consent succeeded
Claude tool callAfter “Allow once”, the protected tool returned 21
Claude connector cleanupThe obsolete Livy connector was removed

These are actual browser/client calls, not simulated provider responses. Numbers change on each call. Both clients used CIMD; dynamic registration was exercised separately by the HTTP check.

In the final recording walkthrough, application sign-out/sign-in succeeded, ChatGPT returned {"number":13}, and Claude returned {"number":57} after one-time approval. Claude's expanded tool panel displayed the raw API response. OAuth enrollment had already been completed before this walkthrough; the recording exercises those existing connections.

Executable checks

bun run check
API_PUBLIC_URL=https://your-public-origin \
  MCP_RESOURCE=https://your-public-origin/mcp \
  bun run test:auth

scripts/check-auth.ts creates disposable accounts and exercises HTTP checks for login/logout, tenant isolation, workspace/project management, API-key creation/use/revocation, discovery, dynamic registration, consent, PKCE, authorization-code replay, UserInfo, random-number authorization, MCP initialization/tool listing/calling, refresh rotation/replay/narrowing, and revocation.

With TEST_DATABASE_URL pointing to the same test deployment, three additional checks seed one-time records and test browser-bound OIDC handoffs. Do not point this option at an unrelated database. The script leaves its uniquely named test accounts in place for inspection. The removed email/recovery API routes are checked to return 404, and password registration must not report a verified email.

The Rust suite includes real database migration/constraint checks when TEST_DATABASE_URL is set. scripts/redirect.test.ts exercises the shared browser return-URL guard. The full check also runs formatting, clippy, lint, TypeScript, and all three production web builds.

After removing outbound email, 27 Rust tests, one Bun redirect test, and 64 local HTTP checks passed. Formatting, clippy, all three apps' lint/type checks, and all three production builds passed. Database-seeded handoff checks ran against the isolated local PostgreSQL instance.

Fixes found during review

  • Quote environment values containing spaces so Rust and Bun load the same configuration.
  • Allow the explicitly configured private API host through the production host guard.
  • Bind social-login handoffs to a browser-held verifier before issuing a session.
  • Reject unsafe return URLs and malformed PKCE values.
  • Refuse automatic social linking to an existing unverified password account.
  • Preserve narrowed refresh scopes and validate client/resource before replay revocation.
  • Accept Claude's compatible code flow without enabling its other advertised grant types.
  • Track migration files as Cargo build inputs so incremental binaries embed new migrations.

Limits of the evidence

No real upstream Google or other social-provider credentials were configured. Browser binding and handoff consumption were tested, but a complete upstream social login was not.

Existing access JWTs remain valid until expiry (normally 15 minutes, with 30 seconds of validation tolerance), including after logout, refresh revocation. Refresh credentials and application sessions are revoked immediately. Project membership is checked again by the random-number API. Immediate access-token revocation would require an additional authoritative check.

This is a functional deployment review, not a penetration-test certification or availability guarantee. Distributed rate limiting, backups, monitoring, and signing-key rotation remain deployment responsibilities. The repository has no billing implementation. The test VM must remain allocated for its connector URLs to work.

On this page