Ploy
Ploy
Features

Authentication

Add managed user authentication to your applications with Ploy Auth.

Authentication

Ploy Auth provides managed user authentication for your deployed applications. Add email/password authentication with a single configuration option.

Configuration

Add an auth binding in your ploy.yaml:

ploy.yaml
kind: dynamic
build: pnpm build
out: dist
auth:
  binding: AUTH_DB

The binding specifies which database to use for storing users. Ploy automatically creates the necessary tables when you deploy.

How It Works

When you enable auth, Ploy:

  1. Creates or uses an existing database based on the binding name
  2. Initializes ploy_users and ploy_sessions tables
  3. Exposes auth endpoints at /_ploy/auth/* for browser clients
  4. Provides an internal http://auth/ URL for server-side access
  5. Generates a per-project JWT secret for signing tokens

Auth Endpoints

All endpoints are available at /_ploy/auth/*:

EndpointMethodDescription
/signupPOSTCreate a new user account
/signinPOSTSign in with email and password
/signoutPOSTRevoke the current session
/meGETGet the current user

Sign Up

const response = await fetch("/_ploy/auth/signup", {
	method: "POST",
	credentials: "include",
	headers: { "Content-Type": "application/json" },
	body: JSON.stringify({
		email: "user@example.com",
		password: "securepassword123",
		metadata: { name: "John Doe" }, // optional
	}),
});

const { user } = await response.json();
// Session cookie is automatically set

Sign In

const response = await fetch("/_ploy/auth/signin", {
	method: "POST",
	credentials: "include",
	headers: { "Content-Type": "application/json" },
	body: JSON.stringify({
		email: "user@example.com",
		password: "securepassword123",
	}),
});

const { user } = await response.json();
// Session cookie is automatically set

Get Current User

const response = await fetch("/_ploy/auth/me", {
	credentials: "include",
});

const { user } = await response.json();

Sign Out

await fetch("/_ploy/auth/signout", {
	method: "POST",
	credentials: "include",
});
// Session cookie is cleared

Server-Side Authentication

In your server code, use the PLOY_AUTH binding to verify tokens and get user information:

app/api/protected/route.ts
export async function GET(request: Request) {
	const authHeader = request.headers.get("Authorization");
	const token = authHeader?.replace("Bearer ", "");

	if (!token) {
		return Response.json({ error: "Unauthorized" }, { status: 401 });
	}

	// Use the auth binding to verify and get user
	const user = await env.PLOY_AUTH.getUser(token);

	if (!user) {
		return Response.json({ error: "Invalid token" }, { status: 401 });
	}

	return Response.json({ user });
}

Server-Side Auth Methods

The PLOY_AUTH binding provides:

interface PloyAuth {
	// Get user from session token
	getUser(token: string): Promise<PloyUser | null>;

	// Verify token signature without fetching user
	verifyToken(token: string): Promise<boolean>;
}

interface PloyUser {
	id: string;
	email: string;
	emailVerified: boolean;
	createdAt: string;
	metadata: Record<string, unknown> | null;
}

Session Management

Sessions are managed via secure httpOnly cookies:

  • Session tokens: Valid for 7 days
  • Cookie name: ploy_session
  • Cookie flags: httpOnly, SameSite=Lax, Secure (in production)

Session tokens are stored in httpOnly cookies, preventing XSS attacks. The cookie is automatically sent with every request when using credentials: "include".

Security Features

Ploy Auth includes built-in security measures:

  • Password hashing: PBKDF2 with 100,000 iterations and SHA-512
  • JWT signing: HMAC-SHA256 with per-project secrets
  • Session expiration: 7-day session tokens with revocation support
  • Email validation: Server-side email format validation
  • Password requirements: Minimum 8 characters
  • Secure cookies: httpOnly cookies prevent XSS attacks

User Metadata

Store additional user data in the metadata field during signup:

const response = await fetch("/_ploy/auth/signup", {
	method: "POST",
	credentials: "include",
	headers: { "Content-Type": "application/json" },
	body: JSON.stringify({
		email: "user@example.com",
		password: "securepassword123",
		metadata: {
			name: "John Doe",
			company: "Acme Inc",
			plan: "pro",
		},
	}),
});

Metadata is returned with the user object on signin and when calling /me.

React Components

For Next.js applications, use the @meetploy/auth-react package for pre-built components:

pnpm add @meetploy/auth-react

See the Next.js Auth Guide for detailed integration instructions.

Next Steps

How is this guide?

Last updated on