Auth Block

Enterprise-grade authentication for modern applications
The Auth Block is a complete authentication and authorization service that provides secure user management, JWT token handling, multi-factor authentication, SSO capabilities, and multi-tenant support. It uses RS256 JWT tokens with company-specific RSA key pairs and follows the JSON:API specification.
Key Features
- RS256 JWT Authentication - Asymmetric encryption with company-level RSA keys
- Multi-tenant Architecture - Complete data isolation per tenant using PostgreSQL schemas
- TOTP Multi-Factor Authentication - Time-based one-time passwords with backup codes
- OIDC Provider - OpenID Connect compliant endpoints for single sign-on
- API Key Management - Service-to-service authentication with AWS Gateway integration
- OAuth 2.0 Refresh Tokens - Optional long-lived session support
- Magic Link Authentication - Passwordless login flows
- Role-Based Access Control - Fine-grained permissions system
API Endpoint
| Service | URL |
|---|---|
| Auth | https://auth.api.us.23blocks.com |
Environment Routing: Use the same URL for all environments. Your API key determines the environment:
pk_test_*/sk_test_*→ Routes to Stagingpk_live_*/sk_live_*→ Routes to Production
Quick Start
Installation
npm install @23blocks/sdk
Basic Authentication
import { create23BlocksClient } from '@23blocks/sdk';
const client = create23BlocksClient({
urls: { authentication: 'https://auth.api.us.23blocks.com' },
apiKey: 'your-api-key', // Use pk_test_* for staging, pk_live_* for production
});
// Register a new user
const user = await client.auth.register({
email: 'user@example.com',
password: 'SecurePassword123',
name: 'John Doe',
confirmSuccessUrl: 'https://yourapp.com/confirmed'
});
// Login
const session = await client.auth.login({
email: 'user@example.com',
password: 'SecurePassword123'
});
// Access token is available
console.log(session.accessToken);
Authentication
Required Headers
All authenticated requests require:
Authorization: Bearer [JWT_TOKEN]
X-API-Key: [COMPANY_API_KEY]
Content-Type: application/json
JWT Token Structure
Tokens are signed using RS256 with company-specific RSA keys. You can verify tokens using the public JWKS endpoint:
GET /:company_url_id/.well-known/jwks.json
API Reference
User Registration
curl -X POST https://auth.api.us.23blocks.com/auth \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"user": {
"email": "newuser@example.com",
"password": "SecurePassword123",
"password_confirmation": "SecurePassword123",
"name": "Jane Smith",
"confirm_success_url": "https://yourapp.com/email-confirmed"
}
}'
Response:
{
"data": {
"id": "usr_def456",
"type": "user",
"attributes": {
"unique_id": "usr_def456",
"email": "newuser@example.com",
"name": "Jane Smith",
"confirmed": false,
"confirmation_sent_at": "2024-01-15T10:30:00Z"
}
},
"meta": {
"message": "A confirmation email has been sent to newuser@example.com"
}
}
Sign In
curl -X POST https://auth.api.us.23blocks.com/auth/sign_in \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"email": "user@example.com",
"password": "SecurePassword123"
}'
Response:
{
"data": {
"id": "usr_abc123",
"type": "user",
"attributes": {
"unique_id": "usr_abc123",
"email": "user@example.com",
"name": "John Doe",
"confirmed": true,
"role_id": 5
}
},
"meta": {
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 86400
}
}
Token Validation
curl -X GET https://auth.api.us.23blocks.com/auth/validate_token \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key"
Password Reset
Request reset:
curl -X POST https://auth.api.us.23blocks.com/auth/password \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"email": "user@example.com",
"redirect_url": "https://app.example.com/reset-password"
}'
Update password:
curl -X PUT https://auth.api.us.23blocks.com/auth/password \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"password": "NewSecurePassword123",
"password_confirmation": "NewSecurePassword123",
"reset_password_token": "abc123resettoken"
}'
Multi-Factor Authentication
Setup MFA
curl -X POST https://auth.api.us.23blocks.com/users/usr_abc123/mfa/setup \
-H "Authorization: Bearer your-jwt-token" \
-H "X-API-Key: your-api-key"
Response:
{
"data": {
"id": "mfa_setup_123",
"type": "mfa_setup",
"attributes": {
"secret": "JBSWY3DPEHPK3PXP",
"qr_code_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
"backup_codes": ["12345678", "87654321", "11111111"]
}
}
}
Enable MFA
After scanning the QR code with an authenticator app:
curl -X POST https://auth.api.us.23blocks.com/users/usr_abc123/mfa/enable \
-H "Authorization: Bearer your-jwt-token" \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{"mfa_code": "123456"}'
Login with MFA
curl -X POST https://auth.api.us.23blocks.com/auth/sign_in \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"email": "user@example.com",
"password": "SecurePassword123",
"mfa_code": "123456"
}'
User Invitations
Invite users to join your application:
curl -X POST https://auth.api.us.23blocks.com/auth/invitation \
-H "Authorization: Bearer your-jwt-token" \
-H "Content-Type: application/json" \
-d '{
"user": {
"email": "newuser@example.com",
"name": "New User",
"role_id": 5,
"appid": "your-api-key",
"accept_invitation_url": "https://app.example.com/accept-invite"
}
}'
Magic Link Authentication
Create passwordless login links:
curl -X POST https://auth.api.us.23blocks.com/companies/your-company/magic_links \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-d '{
"email": "user@example.com",
"redirect_url": "https://app.example.com/dashboard",
"expires_in": 900
}'
OIDC Provider
The Auth Block can act as an OpenID Connect provider for your applications.
Discovery Document
curl https://auth.api.us.23blocks.com/your-company/.well-known/openid-configuration
JWKS Endpoint
curl https://auth.api.us.23blocks.com/your-company/.well-known/jwks.json
Data Types
User
| Field | Type | Description |
|---|---|---|
unique_id | string | Unique identifier |
email | string | User's email address |
name | string | Full name |
confirmed | boolean | Email confirmed status |
role_id | integer | Assigned role ID |
mfa_enabled | boolean | MFA status |
Company
| Field | Type | Description |
|---|---|---|
unique_id | string | Unique identifier |
url_id | string | URL-safe identifier |
name | string | Company name |
api_access_key | string | API key |
oidc_issuer | string | OpenID Connect issuer URL |
Error Handling
The API uses JSON:API error format:
{
"errors": [
{
"status": "422",
"source": "Authentication Service",
"code": "10001",
"title": "Validation Error",
"detail": "Email is required and must be valid"
}
]
}
Common Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | 10001 | Invalid request format |
| 401 | 10002 | Invalid authentication |
| 401 | 103 | Missing or invalid API key |
| 403 | 10003 | Insufficient permissions |
| 404 | 10004 | Resource not found |
| 422 | 10005 | Validation failed |
| 429 | 10006 | Rate limited |
Rate Limiting
| Endpoint Type | Limit |
|---|---|
| Authentication | 10 requests/minute/IP |
| Token validation | 60 requests/minute/token |
| General endpoints | 1000 requests/hour/API key |
Rate limit headers in responses:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1642248000
Security Features
- RS256 JWT - Asymmetric encryption with per-company RSA keys
- JWKS Endpoints - Public key verification for token validation
- Key Rotation - Automated key rotation with graceful transitions
- 24-hour Token Lifetime - Short-lived access tokens
- Tenant Isolation - PostgreSQL schema separation per tenant
- Audit Logging - Complete audit trail for security events
SDK Examples
TypeScript/JavaScript
import { create23BlocksClient } from '@23blocks/sdk';
const client = create23BlocksClient({
urls: { authentication: 'https://auth.api.us.23blocks.com' },
apiKey: process.env.BLOCKS_API_KEY,
});
// Check if token is valid
const isValid = await client.auth.validateToken();
// Get current user
const user = await client.auth.getCurrentUser();
// Update user profile
await client.auth.updateProfile({
name: 'Updated Name',
timezone: 'America/New_York'
});
// Enable MFA
const mfaSetup = await client.auth.setupMfa();
// Show QR code to user
console.log(mfaSetup.qrCodeUrl);
// After user scans QR and enters code
await client.auth.enableMfa('123456');
React Hook Example
import { useAuth } from '@23blocks/react';
function LoginForm() {
const { login, isLoading, error } = useAuth();
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
await login({
email: formData.get('email'),
password: formData.get('password')
});
};
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" required />
<input name="password" type="password" required />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Signing in...' : 'Sign In'}
</button>
{error && <p>{error.message}</p>}
</form>
);
}
Related Resources
- API Reference - Interactive API documentation
- Frontend SDK - Client-side integration
- Platform Status - Service uptime monitoring