Back to blog
EngineeringDate unavailable· min read

Hardening OAuth: Why We Now Validate Before We Store

A small change with big implications: how validating OAuth tokens before persistence makes Sabine more secure and reliable.

OAuth flows are deceptively tricky. You exchange codes, receive tokens, and suddenly you're trusted to access user data across platforms. But what happens when a token arrives malformed, expired, or invalid? Until this week, Sabine would happily store it in the configuration database and only discover the problem later—usually when a user tried to authenticate and faced cryptic errors.

The Problem We Solved

Our OAuth implementation was optimistic. When tokens came back from providers, we'd persist them immediately to the config_store table. This created a window where invalid tokens could enter the system, causing failures downstream when partnerships tried to authenticate API calls. The error surface was broad: malformed JSON, expired timestamps, missing required fields, or tokens that failed provider-specific validation rules.

The real cost wasn't just technical debt. It was user trust. When authentication fails silently or with unclear errors, users assume the platform is unreliable. They don't know (or care) whether the problem originated in token persistence or validation—they just know it doesn't work.

What Changed

We added a validation gate before persistence. Now, when OAuth tokens arrive from a provider, Sabine validates them against a schema and provider-specific rules before writing to config_store. Invalid tokens are rejected immediately with clear error messages, preventing corrupted state from entering the database.

This follows a principle we should have applied from day one: validate at the boundary. By moving validation earlier in the flow, we catch errors when context is richest—during the OAuth callback—rather than minutes or hours later when a user attempts an action and receives a generic authentication failure.

Why It Matters

Security and reliability are intertwined. Invalid tokens in storage create an attack surface—they can be probed, replayed, or exploited if validation happens inconsistently across services. By enforcing validation before persistence, we reduce that surface and create a single source of truth: if a token is in config_store, it's valid.

For users, this means fewer mysterious authentication failures. For engineers debugging OAuth issues, it means clearer error messages at the point of failure. For the platform, it means a healthier data layer and fewer edge cases to handle in downstream services.

What's Next

This change is foundational, but it's not the end. We're extending the validation framework to cover refresh token flows, adding observability around token validation failures to spot provider-specific issues early, and exploring proactive token health checks that validate stored tokens periodically rather than only at use-time.

Authentication should be invisible when it works and obvious when it fails. This fix moves us closer to that ideal.