Authentication
DYPAI provides a complete authentication and authorization system with multiple sign-in providers, JWT-based sessions, role-based access control, and deep integration with Row Level Security.
Overview
Every DYPAI project includes a built-in auth system that handles user registration, login, token management, and access control. Key capabilities include:
- Multiple providers β email/password, magic links, SMS/OTP, and OAuth with Google, GitHub, Microsoft, and Apple.
- JWT sessions β stateless tokens that encode the user's identity and role, used to authenticate every API request.
- Role-based access control (RBAC) β assign roles with fine-grained permissions in the format
resource:action. - RLS integration β use
auth.uid()andauth.role()directly inside PostgreSQL Row Level Security policies. - Password recovery β built-in reset flow with customizable email templates.
Authentication Flow
The authentication flow follows a standard JWT pattern:
- The client sends credentials (email + password, OAuth code, or OTP) to the login endpoint.
- DYPAI validates the credentials against the user store.
- On success, a short-lived access token (JWT) and a long-lived refresh token are returned.
- The client includes the access token in the
Authorizationheader of subsequent API requests. - When the access token expires, the client uses the refresh token to obtain a new pair.
Here is an example of the login request and response using the email/password provider:
// Login request
const response = await fetch('https://my-project.dypai.ai/auth/v1/token?grant_type=password', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_ANON_KEY',
},
body: JSON.stringify({
email: 'user@example.com',
password: 'securepassword123',
}),
})
const session = await response.json()
// {
// "access_token": "eyJhbGciOiJIUzI1NiIs...",
// "token_type": "bearer",
// "expires_in": 3600,
// "refresh_token": "v1.MjQ1NjcxMjM...",
// "user": {
// "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
// "email": "user@example.com",
// "role": "authenticated"
// }
// }localStorage for applications that handle sensitive data. Use httpOnly cookies instead to protect tokens from XSS attacks. DYPAI supports cookie-based sessions out of the box.Supported Providers
DYPAI supports the following authentication providers. Enable or disable each provider from the Auth > Providers section in your project dashboard.
| Provider | Type | Status | Notes |
|---|---|---|---|
| Email / Password | Built-in | Enabled by default | Supports email confirmation and password reset |
| Magic Link | Built-in | Enabled by default | Passwordless login via a one-time link sent to email |
| SMS / OTP | Built-in | Requires Twilio config | One-time passcode sent via SMS |
| OAuth 2.0 | Manual setup | Requires Google Cloud OAuth client ID and secret | |
| GitHub | OAuth 2.0 | Manual setup | Requires GitHub OAuth app credentials |
| Microsoft | OAuth 2.0 | Manual setup | Azure AD application registration required |
| Apple | OAuth 2.0 | Manual setup | Requires Apple Developer Program membership |
See the Providers guide for step-by-step setup instructions for each OAuth provider.
User States
Every user in your project is in one of the following states. The state determines whether the user can authenticate and what access they have:
| State | Can Log In | Description |
|---|---|---|
| Confirmed | Yes | The user has verified their email or phone and can authenticate normally. |
| Pending | No | The user has registered but has not yet confirmed their email. A confirmation link was sent automatically. |
| Anonymous | Yes (limited) | A temporary user created without credentials. Useful for guest carts or previews. Anonymous users can later be upgraded to confirmed users. |
| Banned | No | An admin has explicitly blocked this user. All existing tokens are invalidated immediately. |
Role-Based Access Control
DYPAI uses a permission model based on roles. Each role contains a set of permissions in the format resource:action. When a user makes an API request, DYPAI checks whether their role grants the required permission for the requested resource and action.
Default Roles
| Role | Description | Use Case |
|---|---|---|
authenticated | Assigned automatically to every confirmed user after login. | Standard signed-in users |
anon | Applied to requests made with the anon API key and no user token. | Public read access, guest users |
service_role | Full access that bypasses RLS. Used for server-side operations and admin tasks. | Backend services, migrations, admin scripts |
You can create custom roles with specific permissions. Here is an example of a role definition for a content editor:
{
"role": "editor",
"permissions": [
"posts:read",
"posts:write",
"posts:delete",
"comments:read",
"comments:write",
"media:read",
"media:upload"
]
}Assign roles to users through the dashboard or programmatically via the admin API:
// Assign a custom role to a user
await fetch('https://my-project.dypai.ai/auth/v1/admin/users/USER_ID', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer SERVICE_ROLE_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
role: 'editor',
}),
})Row Level Security
DYPAI's auth system integrates directly with PostgreSQL Row Level Security. Inside RLS policies, you can reference the authenticated user's ID and role using built-in helper functions:
-- Only allow users to read their own profiles
CREATE POLICY "Users read own profile"
ON profiles
FOR SELECT
USING (auth.uid() = user_id);
-- Only allow editors to insert posts
CREATE POLICY "Editors can create posts"
ON posts
FOR INSERT
WITH CHECK (auth.role() = 'editor');auth.uid() function returns the sub claim from the JWT, which is the user's UUID. The auth.role() function returns the role claim. Both are available inside any RLS policy expression.Security Best Practices
Follow these recommendations to keep your application secure:
- Use httpOnly cookies for token storage. This prevents JavaScript from accessing tokens and protects against XSS attacks. DYPAI provides cookie-based session management as a built-in option.
- Enable token rotation. When a refresh token is used, the old token is invalidated and a new one is issued. This limits the window of exposure if a refresh token is compromised.
- Keep access tokens short-lived. The default expiration is 1 hour. You can reduce it to as low as 5 minutes for high-security applications in Auth > Settings > Token Lifetime.
- Always enable RLS on tables with user data. Without RLS, any authenticated user can potentially read or modify all rows in a table through the auto-generated API.
- Never expose the
service_rolekey on the client. This key bypasses all RLS policies. It should only be used in server-side code or admin scripts. - Require email confirmation. Enable the Confirm email setting to prevent users from logging in before verifying their email address.
- Set strong password requirements. Configure minimum password length and complexity rules in Auth > Settings > Password Policy.