Skip to main content

Auth Block

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

ServiceURL
Authhttps://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 Staging
  • pk_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"
}
}'

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

FieldTypeDescription
unique_idstringUnique identifier
emailstringUser's email address
namestringFull name
confirmedbooleanEmail confirmed status
role_idintegerAssigned role ID
mfa_enabledbooleanMFA status

Company

FieldTypeDescription
unique_idstringUnique identifier
url_idstringURL-safe identifier
namestringCompany name
api_access_keystringAPI key
oidc_issuerstringOpenID 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

StatusCodeDescription
40010001Invalid request format
40110002Invalid authentication
401103Missing or invalid API key
40310003Insufficient permissions
40410004Resource not found
42210005Validation failed
42910006Rate limited

Rate Limiting

Endpoint TypeLimit
Authentication10 requests/minute/IP
Token validation60 requests/minute/token
General endpoints1000 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>
);
}