← Back to list

encore-auth
by encoredev
Agent Skills for development with Encore.
⭐ 10🍴 1📅 Jan 23, 2026
SKILL.md
name: encore-auth description: Implement authentication with auth handlers and gateways in Encore.ts.
Encore Authentication
Instructions
Encore.ts provides a built-in authentication system for identifying API callers and protecting endpoints.
1. Create an Auth Handler
// auth.ts
import { Header, Gateway } from "encore.dev/api";
import { authHandler } from "encore.dev/auth";
// Define what the auth handler receives
interface AuthParams {
authorization: Header<"Authorization">;
}
// Define what authenticated requests will have access to
interface AuthData {
userID: string;
email: string;
role: "admin" | "user";
}
export const auth = authHandler<AuthParams, AuthData>(
async (params) => {
// Validate the token (example with JWT)
const token = params.authorization.replace("Bearer ", "");
const payload = await verifyToken(token);
if (!payload) {
throw APIError.unauthenticated("invalid token");
}
return {
userID: payload.sub,
email: payload.email,
role: payload.role,
};
}
);
// Register the auth handler with a Gateway
export const gateway = new Gateway({
authHandler: auth,
});
2. Protect Endpoints
import { api } from "encore.dev/api";
// Protected endpoint - requires authentication
export const getProfile = api(
{ method: "GET", path: "/profile", expose: true, auth: true },
async (): Promise<Profile> => {
// Only authenticated users reach here
}
);
// Public endpoint - no authentication required
export const healthCheck = api(
{ method: "GET", path: "/health", expose: true },
async () => ({ status: "ok" })
);
3. Access Auth Data in Endpoints
import { api } from "encore.dev/api";
import { getAuthData } from "~encore/auth";
export const getProfile = api(
{ method: "GET", path: "/profile", expose: true, auth: true },
async (): Promise<Profile> => {
const auth = getAuthData()!; // Non-null when auth: true
return {
userID: auth.userID,
email: auth.email,
role: auth.role,
};
}
);
Auth Handler Behavior
| Scenario | Handler Returns | Result |
|---|---|---|
| Valid credentials | AuthData object | Request authenticated |
| Invalid credentials | Throws APIError.unauthenticated() | Treated as no auth |
| Other error | Throws other error | Request aborted |
Auth with Endpoints
| Endpoint Config | Request Has Auth | Result |
|---|---|---|
auth: true | Yes | Proceeds with auth data |
auth: true | No | 401 Unauthenticated |
auth: false or omitted | Yes | Proceeds (auth data available) |
auth: false or omitted | No | Proceeds (no auth data) |
Service-to-Service Auth Propagation
Auth data automatically propagates to internal service calls:
import { user } from "~encore/clients";
import { getAuthData } from "~encore/auth";
export const getOrderWithUser = api(
{ method: "GET", path: "/orders/:id", expose: true, auth: true },
async ({ id }): Promise<OrderWithUser> => {
const auth = getAuthData()!;
// Auth is automatically propagated to this call
const orderUser = await user.getProfile();
return { order: await getOrder(id), user: orderUser };
}
);
Common Auth Patterns
JWT Token Validation
import { jwtVerify } from "jose";
import { secret } from "encore.dev/config";
const jwtSecret = secret("JWTSecret");
async function verifyToken(token: string): Promise<JWTPayload | null> {
try {
const { payload } = await jwtVerify(
token,
new TextEncoder().encode(jwtSecret())
);
return payload;
} catch {
return null;
}
}
API Key Authentication
export const auth = authHandler<AuthParams, AuthData>(
async (params) => {
const apiKey = params.authorization;
const user = await db.queryRow<User>`
SELECT id, email, role FROM users WHERE api_key = ${apiKey}
`;
if (!user) {
throw APIError.unauthenticated("invalid API key");
}
return {
userID: user.id,
email: user.email,
role: user.role,
};
}
);
Cookie-Based Auth
interface AuthParams {
cookie: Header<"Cookie">;
}
export const auth = authHandler<AuthParams, AuthData>(
async (params) => {
const sessionId = parseCookie(params.cookie, "session");
if (!sessionId) {
throw APIError.unauthenticated("no session");
}
const session = await getSession(sessionId);
if (!session || session.expiresAt < new Date()) {
throw APIError.unauthenticated("session expired");
}
return {
userID: session.userID,
email: session.email,
role: session.role,
};
}
);
Guidelines
- Auth handlers must be registered with a Gateway
- Use
getAuthData()from~encore/authto access auth data getAuthData()returnsnullin unauthenticated requests- Auth data propagates automatically in service-to-service calls
- Throw
APIError.unauthenticated()for invalid credentials - Keep auth handlers fast - they run on every authenticated request
Score
Total Score
60/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
○言語
プログラミング言語が設定されている
0/5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon
