← All posts

Bring your own credentials: why your ad account should never live in ours

nordenagent team··3 min read

When we started shopping for marketing automation tools, almost every one of them asked us to connect an account through an OAuth flow they controlled. The tokens landed in their database, under their service account, often with scopes far wider than what the product actually needed. If that vendor ever got breached, every customer's Meta and Google accounts would be exposed in one shot.

We did not want to build another version of that, so nordenagent is built around a bring-your-own-credentials model from day one.

One vault per workspace

Every integration credential you connect is encrypted and written to Supabase Vault under your workspace id. The application code never sees the plaintext. When a job needs a Meta token, a SECURITY DEFINER stored procedure reads the secret, the Row Level Security check confirms the caller is a member of that workspace, and the token is passed directly to the outbound fetch. A second workspace trying to read your credentials is rejected at the database layer, not the application layer.

No service-role clients in the request path

The one way to bypass Row Level Security in Supabase is to use a service-role key. We treat that key like a nuclear option: it only exists in the Stripe webhook handler (which authenticates via signed request bodies) and in a handful of cron scripts that never touch a user request. Every page, server action, and API route uses the cookie-scoped Supabase client. If we accidentally shipped a bug that tried to read another workspace's data, RLS would stop it.

Disconnecting is really disconnecting

When you remove an integration from Settings, the delete flow calls a dedicated procedure that removes the Vault secret row and the integration row in a single transaction. Nothing is soft-deleted, nothing is kept around for analytics, and nothing lingers in application caches. The same procedure runs automatically when you delete your account, so there is no way to end up with an orphan credential tied to a user that no longer exists.

Ready to try it?

Start free