| name | bkend-auth |
| classification | C |
| description | bkend.ai authentication and security expert skill.
Covers email signup/login, social login (Google, GitHub), magic link,
JWT tokens (Access 1h, Refresh 30d), session management, RBAC (admin/user/self/guest),
RLS policies, password management, and account lifecycle.
Triggers: signup, login, JWT, session, social login, RBAC, RLS, password, token,
회원가입, 로그인, 토큰, 세션, 권한, 보안정책, 비밀번호,
ログイン, 認証, セッション, 権限, パスワード,
登录, 认证, 会话, 权限, 密码,
registro, inicio de sesion, permisos, contrasena,
inscription, connexion, permissions, mot de passe,
Registrierung, Anmeldung, Berechtigungen, Passwort,
registrazione, accesso, permessi, password
Do NOT use for: file storage (use bkend-storage), database queries (use bkend-data),
MCP tool setup (use bkend-mcp)
|
| user-invocable | true |
| argument-hint | |
| allowed-tools | ["read_file","write_file","replace","glob","grep_search","run_shell_command","web_fetch"] |
| imports | [] |
| agents | {"backend":"bkend-expert"} |
| context | session |
| memory | project |
| pdca-phase | all |
bkend-auth
bkend.ai authentication and security expert skill
1. Auth Overview
bkend.ai uses JWT-based authentication with a dual-token strategy:
| Token | Type | Lifetime | Purpose |
|---|
| Access Token | JWT | 1 hour | API request authorization |
| Refresh Token | Opaque | 30 days | Obtain new access tokens |
Supported Authentication Methods
- Email/Password -- traditional signup and login
- Magic Link -- passwordless email-based login
- Social Login (OAuth) -- Google, GitHub
- API Key -- server-to-server (tenant-level, not user-level)
Required Headers
All auth endpoints require these headers:
X-Project-Id: <your-project-id>
X-Environment: <dev|staging|prod>
Content-Type: application/json
Authenticated endpoints additionally require:
Authorization: Bearer <access-token>
Auth Response Structure
All successful auth responses follow this pattern:
{
"success": true,
"data": {
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"name": "Alice",
"role": "user",
"emailVerified": true,
"createdAt": "2025-01-15T09:00:00.000Z",
"updatedAt": "2025-01-15T09:00:00.000Z"
},
"tokens": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "rt_a1b2c3d4e5f6...",
"expiresIn": 3600
}
}
}
2. Email Authentication
2.1 Signup
Endpoint: POST /auth/email/signup
Request:
{
"email": "user@example.com",
"password": "SecureP@ss123",
"name": "Alice Kim"
}
Response (201 Created):
{
"success": true,
"data": {
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"name": "Alice Kim",
"role": "user",
"emailVerified": false,
"createdAt": "2025-01-15T09:00:00.000Z"
},
"tokens": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "rt_a1b2c3d4e5f6...",
"expiresIn": 3600
}
}
}
Password Requirements:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
Error Responses:
| HTTP Status | Error Code | Description |
|---|
| 400 | INVALID_EMAIL | Email format is invalid |
| 400 | WEAK_PASSWORD | Password does not meet requirements |
| 409 | EMAIL_ALREADY_EXISTS | Account with this email already exists |
| 400 | MISSING_REQUIRED_FIELD | Required field (email, password) is missing |
bkendFetch Example:
const result = await bkendFetch("/auth/email/signup", {
method: "POST",
body: JSON.stringify({
email: "user@example.com",
password: "SecureP@ss123",
name: "Alice Kim",
}),
});
const { accessToken, refreshToken } = result.data.tokens;
2.2 Login
Endpoint: POST /auth/email/signin
Request:
{
"email": "user@example.com",
"password": "SecureP@ss123"
}
Response (200 OK):
{
"success": true,
"data": {
"user": {
"id": "usr_abc123",
"email": "user@example.com",
"name": "Alice Kim",
"role": "user",
"emailVerified": true,
"lastLoginAt": "2025-01-20T14:30:00.000Z"
},
"tokens": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "rt_x9y8z7w6v5u4...",
"expiresIn": 3600
}
}
}
Error Responses:
| HTTP Status | Error Code | Description |
|---|
| 401 | INVALID_CREDENTIALS | Email or password is incorrect |
| 403 | ACCOUNT_DISABLED | Account has been disabled |
| 403 | ACCOUNT_LOCKED | Too many failed attempts (locked 30 min) |
| 429 | TOO_MANY_ATTEMPTS | Rate limit exceeded |
2.3 Email Verification
Send verification email:
POST /auth/email/verify/resend
{
"email": "user@example.com"
}
Verify email with token:
POST /auth/email/verify
{
"token": "ev_abc123def456..."
}
Response (200 OK):
{
"success": true,
"data": {
"message": "Email verified successfully",
"emailVerified": true
}
}
3. Magic Link Authentication
Magic link provides passwordless authentication via email.
3.1 Send Magic Link
Endpoint: POST /auth/magiclink/send
Request:
{
"email": "user@example.com",
"redirectUri": "https://myapp.com/auth/callback"
}
Response (200 OK):
{
"success": true,
"data": {
"message": "Magic link sent to user@example.com",
"expiresIn": 600
}
}
The user receives an email with a link like:
https://api-client.bkend.ai/auth/magiclink/verify?token=ml_abc123...&redirectUri=https://myapp.com/auth/callback
3.2 Verify Magic Link
Endpoint: GET /auth/magiclink/verify?token=<token>&redirectUri=<uri>
The server verifies the token and redirects to redirectUri with tokens as query parameters:
https://myapp.com/auth/callback?accessToken=eyJ...&refreshToken=rt_...&expiresIn=3600
Client-side handling:
"use client";
import { useSearchParams, useRouter } from "next/navigation";
import { useEffect } from "react";
export default function AuthCallback() {
const searchParams = useSearchParams();
const router = useRouter();
useEffect(() => {
const accessToken = searchParams.get("accessToken");
const refreshToken = searchParams.get("refreshToken");
if (accessToken && refreshToken) {
document.cookie = `bkend_access_token=${accessToken}; path=/; secure; samesite=lax; max-age=3600`;
document.cookie = `bkend_refresh_token=${refreshToken}; path=/; secure; samesite=lax; max-age=2592000`;
router.push("/dashboard");
} else {
router.push("/login?error=invalid_magic_link");
}
}, [searchParams, router]);
return <div>Authenticating...</div>;
}
Error Responses:
| HTTP Status | Error Code | Description |
|---|
| 400 | INVALID_MAGIC_LINK | Token is invalid or malformed |
| 410 | MAGIC_LINK_EXPIRED | Token has expired (10 min lifetime) |
| 400 | MAGIC_LINK_USED | Token has already been used |
4. Social Login (OAuth)
4.1 Google OAuth
Console Configuration:
- Go to Console > Project > Settings > Auth > Social Login
- Enable Google provider
- Enter your Google Client ID and Client Secret
- Set authorized redirect URI:
https://api-client.bkend.ai/auth/social/google/callback
Initiate Google Login:
GET /auth/social/google?redirectUri=https://myapp.com/auth/callback
The server redirects the user to Google's OAuth consent screen. After authorization, the user is redirected back to your redirectUri with tokens:
https://myapp.com/auth/callback?accessToken=eyJ...&refreshToken=rt_...&expiresIn=3600
bkendFetch Example (redirect):
function handleGoogleLogin() {
const projectId = process.env.NEXT_PUBLIC_BKEND_PROJECT_ID;
const env = process.env.NEXT_PUBLIC_BKEND_ENVIRONMENT;
const redirectUri = encodeURIComponent(`${window.location.origin}/auth/callback`);
window.location.href =
`${process.env.NEXT_PUBLIC_BKEND_API_URL}/auth/social/google` +
`?redirectUri=${redirectUri}` +
`&projectId=${projectId}` +
`&environment=${env}`;
}
4.2 GitHub OAuth
Console Configuration:
- Go to Console > Project > Settings > Auth > Social Login
- Enable GitHub provider
- Enter your GitHub Client ID and Client Secret
- Set authorization callback URL:
https://api-client.bkend.ai/auth/social/github/callback
Initiate GitHub Login:
GET /auth/social/github?redirectUri=https://myapp.com/auth/callback
The flow is identical to Google. The user is redirected to GitHub for authorization, then back to your app with tokens.
Error Responses (Social Login):
| HTTP Status | Error Code | Description |
|---|
| 400 | SOCIAL_AUTH_FAILED | OAuth provider returned an error |
| 400 | SOCIAL_EMAIL_NOT_FOUND | Provider did not return an email |
| 409 | EMAIL_ALREADY_EXISTS | Email is linked to another auth method |
| 400 | SOCIAL_PROVIDER_DISABLED | Provider not enabled in project settings |
5. Token Management
5.1 Refresh Token
Endpoint: POST /auth/token/refresh
Request:
{