- 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
1. **Email/Password** -- traditional signup and login
2. **Magic Link** -- passwordless email-based login
3. **Social Login (OAuth)** -- Google, GitHub
4. **API Key** -- server-to-server (tenant-level, not user-level)
### Required Headers
All auth endpoints require these headers:
```http
X-Project-Id: <your-project-id>
X-Environment: <dev|staging|prod>
Content-Type: application/json
```
Authenticated endpoints additionally require:
```http
Authorization: Bearer <access-token>
```
### Auth Response Structure
All successful auth responses follow this pattern:
```json
{
"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:**
```json
{
"email": "user@example.com",
"password": "SecureP@ss123",
"name": "Alice Kim"
}
```
**Response (201 Created):**
```json
{
"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:**
```typescript
const result = await bkendFetch("/auth/email/signup", {
method: "POST",
body: JSON.stringify({
email: "user@example.com",
password: "SecureP@ss123",
name: "Alice Kim",
}),
});
// Store tokens
const { accessToken, refreshToken } = result.data.tokens;
```
### 2.2 Login
**Endpoint:** `POST /auth/email/signin`
**Request:**
```json
{
"email": "user@example.com",
"password": "SecureP@ss123"
}
```
**Response (200 OK):**
```json
{
"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
```
```json
{
"email": "user@example.com"
}
```
**Verify email with token:**
```
POST /auth/email/verify
```
```json
{
"token": "ev_abc123def456..."
}
```
**Response (200 OK):**
```json
{
"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:**
```json
{
"email": "user@example.com",
"redirectUri": "https://myapp.com/auth/callback"
}
```
**Response (200 OK):**
```json
{
"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:**
```typescript
// app/auth/callback/page.tsx
"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) {
// Store tokens securely
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:**
1. Go to **Console > Project > Settings > Auth > Social Login**
2. Enable Google provider
3. Enter your Google Client ID and Client Secret
4. 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):**
```typescript
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:**
1. Go to **Console > Project > Settings > Auth > Social Login**
2. Enable GitHub provider
3. Enter your GitHub Client ID and Client Secret
4. 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:**
```json
{
GitHub에서 보기