Updated 2 October 2026
Choosing a Postgres Schema for Authentication Tables
Why Use a Separate Schema for Authentication
When implementing authentication in PostgreSQL, one of the first architectural decisions is how to organize your tables. PostgreSQL schemas provide named namespaces that help you group related objects together, control access, and avoid naming conflicts with existing application tables. According to the PostgreSQL schemas documentation, schemas provide "named namespaces for tables, indexes, types, functions, and other database objects" which makes them ideal for encapsulating authentication logic away from your core business data.
For Own Auth implementations, placing authentication tables in their own schema creates a clear boundary between authentication concerns and application data. This separation simplifies privilege management, enables targeted security policies, and makes it easier to reason about which parts of your database handle sensitive credential storage.
Recommended Schema Structure for Own Auth
The most common approach is to create a dedicated schema named after your authentication implementation. This keeps all authentication related tables, indexes, and functions grouped together while remaining distinct from your application's main schema (typically named public).
-- Create the authentication schema
CREATE SCHEMA IF NOT EXISTS auth;
-- Set the search path to include auth schema by default
ALTER DATABASE your_database SET search_path TO auth, public;This basic setup places all authentication objects in the auth namespace. When Own Auth initializes, it will create tables like users, sessions, api_keys, and audit_events within this schema. The search_path configuration ensures that queries within your authentication logic can reference these tables without explicit schema prefixes.
Managing Schema Privileges
Security begins with proper privilege management. PostgreSQL GRANT controls privileges on schemas and their contained objects, allowing you to enforce the principle of least privilege. Your application should connect to the database using a role that has only the necessary permissions on the auth schema.
-- Create a dedicated role for your application
CREATE ROLE app_user WITH LOGIN PASSWORD 'secure_password';
-- Grant usage on the auth schema
GRANT USAGE ON SCHEMA auth TO app_user;
-- Grant specific table permissions
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA auth TO app_user;
-- Grant sequence permissions for auto-incrementing IDs
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA auth TO app_user;
-- Ensure future tables also get these permissions
ALTER DEFAULT PRIVILEGES IN SCHEMA auth
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA auth
GRANT USAGE, SELECT ON SEQUENCES TO app_user;This configuration gives your application full access to authentication tables while preventing accidental access to other schemas. If your application only needs to read user data (for example, to display profiles), you can further restrict permissions to SELECT only.
Implementing Row Level Security for Multi Tenant Isolation
When building multi tenant applications with organisations, row level security (RLS) provides an additional layer of protection. Row security policies can restrict which rows a database role can read or modify and default to denying access when enabled without a policy, as documented in the PostgreSQL row security documentation. RLS ensures that even if your application has full table access, users can only see data belonging to their organisation.
-- Enable RLS on the users table
ALTER TABLE auth.users ENABLE ROW LEVEL SECURITY;
-- Create a policy that filters by organisation_id
CREATE POLICY users_organisation_isolation
ON auth.users
FOR ALL
USING (organisation_id = current_setting('app.current_organisation_id')::uuid);
-- Similar policy for sessions
ALTER TABLE auth.sessions ENABLE ROW LEVEL SECURITY;
CREATE POLICY sessions_organisation_isolation
ON auth.sessions
FOR ALL
USING (user_id IN (
SELECT id FROM auth.users
WHERE organisation_id = current_setting('app.current_organisation_id')::uuid
));RLS policies automatically filter query results based on the current session context. Your application sets the organisation context before executing queries, and PostgreSQL enforces the filtering at the database level. This defense in depth approach prevents accidental data leakage even if your application logic contains bugs.
Organising Related Objects Within the Schema
Beyond tables, your auth schema can contain supporting objects that belong logically together. Consider creating these additional components within the auth namespace:
- Indexes for frequently queried columns (user email lookups, session expiry checks)
- Composite types for complex return values
- Functions for common authentication operations (hash verification, token generation)
- Views for reporting that aggregate authentication data
Keeping these objects in the auth schema maintains the namespace boundary and makes it straightforward to grant or revoke access to the entire authentication subsystem at once.
Migration Considerations
When migrating existing authentication data into a new schema structure, plan for downtime or use a blue green deployment approach. Export your current tables, create the new schema structure, import the data, and update your application configuration to point to the schema prefixed table names. Own Auth's database backed sessions and user storage will automatically use the configured schema during initialization.
Conclusion
Choosing a dedicated schema for authentication tables provides clear organizational boundaries, enables granular security controls, and simplifies database management. By combining schema level privileges with row level security policies, you create multiple layers of protection for sensitive authentication data. This approach scales well as your application grows and makes it straightforward to audit access patterns or migrate to different database configurations in the future.
Frequently Asked Questions
Can I use multiple schemas for different authentication components?
Yes, you can create additional schemas for specific purposes, such as separate schemas for audit logs or reporting. However, keeping authentication tables in one schema simplifies privilege management and is the recommended approach for most applications.
Does Own Auth require a specific schema name?
Own Auth does not mandate a specific schema name. The default configuration uses the search_path to locate tables, but you can configure a custom schema by adjusting your database settings and ensuring the search_path includes your chosen namespace.
How do I handle schema migrations with Own Auth?
Own Auth manages its own table creation and migrations. When using a custom schema, ensure your database user has sufficient privileges to create and modify objects within that schema. Run migrations before deploying application updates to avoid runtime errors.