Back to guides

Postgres authentication: keep users and sessions in your database


Postgres authentication keeps users, credential records, one-time token hashes, and revocable sessions in the application's database while a server-side auth library enforces the security rules. With Own Auth, the backend calls a TypeScript API and Postgres remains the source of truth instead of a hosted identity tenant.

What belongs in Postgres

  • Normalized users and provider accounts
  • Argon2id password hashes, never plaintext passwords
  • Hashed session tokens with absolute and idle expiry
  • Hashed magic-link, verification, reset, and invitation tokens
  • Organisation membership, roles, permissions, and invitations
  • Revocable application API keys and security audit events

The browser should not connect to these tables directly. It sends credentials or an opaque session token to the application backend. The backend validates the request, calls Own Auth, and returns only the user and session data the application needs.

Install without handing over the database

Terminal
npm install own-auth
npx own-auth migrate
npx own-auth status

Own Auth owns only its own prefixed auth tables. Prisma, Drizzle, Knex, or application SQL can continue to own product tables. Keep the migration responsibilities separate instead of recreating auth tables in a second schema definition.

Create one server-only auth instance

auth.ts
import "server-only";
import { createOwnAuth } from "own-auth";

export const auth = createOwnAuth({
  tokenPepper: process.env.OWN_AUTH_TOKEN_PEPPER,
  session: {
    ttlMs: 30 * 24 * 60 * 60 * 1000,
    idleTtlMs: 7 * 24 * 60 * 60 * 1000,
  },
});

Use opaque sessions at the HTTP boundary

After sign-in, put the raw session token in a Secure HttpOnly cookie or a protected mobile credential store. Store only the protected hash in Postgres. Every protected server operation should verify the token and authorize access to application data instead of trusting a client-supplied user ID.

Operate the database like authentication infrastructure

  • Back up auth and application data together and test restoration.
  • Use a connection pool and bounded query timeouts.
  • Run migrations before new application code receives traffic.
  • Restrict database credentials to server runtimes.
  • Monitor failed sign-ins and rate limits without logging passwords or auth URLs.
  • Revoke sessions and keys through Own Auth APIs rather than deleting random rows.

Database ownership gives the application control over retention, backups, queries, and migration. It also makes the application responsible for secure Postgres operations. The useful trade is ownership with a tested auth engine, not hand-written cryptography or ad hoc session tables.