Initial Commit
This commit is contained in:
333
mvp-platform-services/tenants/AUTH0-CONFIG.md
Normal file
333
mvp-platform-services/tenants/AUTH0-CONFIG.md
Normal file
@@ -0,0 +1,333 @@
|
||||
# Auth0 Multi-Tenant Configuration Guide
|
||||
|
||||
This document provides step-by-step instructions for configuring Auth0 for the multi-tenant MotoVaultPro platform.
|
||||
|
||||
## Overview
|
||||
|
||||
The multi-tenant architecture requires:
|
||||
- **Landing Page**: `motovaultpro.com` - Entry point with tenant selection
|
||||
- **Admin Tenant**: `admin.motovaultpro.com` - Admin access to all tenants
|
||||
- **Regular Tenants**: `{tenant-id}.motovaultpro.com` - Isolated tenant access
|
||||
- **Signup Workflow**: Tenant-specific signup with admin approval
|
||||
|
||||
## Auth0 Application Configuration
|
||||
|
||||
### 1. Application Settings
|
||||
|
||||
**Application Type**: Single Page Application (SPA)
|
||||
|
||||
**Allowed Callback URLs**:
|
||||
```
|
||||
# Development URLs
|
||||
http://localhost:3002/callback
|
||||
http://admin.motovaultpro.local/callback
|
||||
http://demo-tenant.motovaultpro.local/callback
|
||||
|
||||
# Production URLs
|
||||
https://motovaultpro.com/callback
|
||||
https://admin.motovaultpro.com/callback
|
||||
https://demo-tenant.motovaultpro.com/callback
|
||||
|
||||
# Add additional tenant subdomains as needed:
|
||||
https://{tenant-id}.motovaultpro.com/callback
|
||||
```
|
||||
|
||||
**Allowed Logout URLs**:
|
||||
```
|
||||
# Development
|
||||
http://localhost:3002
|
||||
http://admin.motovaultpro.local
|
||||
http://demo-tenant.motovaultpro.local
|
||||
|
||||
# Production
|
||||
https://motovaultpro.com
|
||||
https://admin.motovaultpro.com
|
||||
https://demo-tenant.motovaultpro.com
|
||||
https://{tenant-id}.motovaultpro.com
|
||||
```
|
||||
|
||||
**Allowed Web Origins**:
|
||||
```
|
||||
# Development
|
||||
http://localhost:3002
|
||||
http://admin.motovaultpro.local:3000
|
||||
http://demo-tenant.motovaultpro.local:3000
|
||||
|
||||
# Production
|
||||
https://motovaultpro.com
|
||||
https://admin.motovaultpro.com
|
||||
https://demo-tenant.motovaultpro.com
|
||||
https://{tenant-id}.motovaultpro.com
|
||||
```
|
||||
|
||||
### 2. JWT Configuration
|
||||
|
||||
**JWT Signature Algorithm**: RS256
|
||||
|
||||
**OIDC Conformant**: Enabled
|
||||
|
||||
### 3. Advanced Settings
|
||||
|
||||
**Grant Types**:
|
||||
- Authorization Code
|
||||
- Refresh Token
|
||||
- Implicit (for development only)
|
||||
|
||||
## Auth0 Rules Configuration
|
||||
|
||||
### Rule 1: Add Tenant Context to JWT
|
||||
|
||||
Create a new Rule in Auth0 Dashboard > Auth Pipeline > Rules:
|
||||
|
||||
```javascript
|
||||
function addTenantContext(user, context, callback) {
|
||||
const namespace = 'https://motovaultpro.com/';
|
||||
|
||||
// Extract tenant_id from user metadata (set during signup)
|
||||
let tenantId = user.user_metadata && user.user_metadata.tenant_id;
|
||||
|
||||
// For existing users without tenant metadata, default to admin
|
||||
if (!tenantId) {
|
||||
tenantId = 'admin';
|
||||
// Optionally update user metadata
|
||||
user.user_metadata = user.user_metadata || {};
|
||||
user.user_metadata.tenant_id = tenantId;
|
||||
}
|
||||
|
||||
// Check signup status for non-admin tenants
|
||||
const signupStatus = user.user_metadata && user.user_metadata.signup_status;
|
||||
|
||||
if (tenantId !== 'admin' && signupStatus !== 'approved') {
|
||||
// Block login for unapproved users
|
||||
return callback(new UnauthorizedError('Account pending approval'));
|
||||
}
|
||||
|
||||
// Add tenant context to tokens
|
||||
context.idToken[namespace + 'tenant_id'] = tenantId;
|
||||
context.accessToken[namespace + 'tenant_id'] = tenantId;
|
||||
context.idToken[namespace + 'signup_status'] = signupStatus || 'approved';
|
||||
|
||||
callback(null, user, context);
|
||||
}
|
||||
```
|
||||
|
||||
### Rule 2: Tenant-Specific User Metadata
|
||||
|
||||
```javascript
|
||||
function setTenantMetadata(user, context, callback) {
|
||||
const namespace = 'https://motovaultpro.com/';
|
||||
|
||||
// If this is a signup and connection is Username-Password-Authentication
|
||||
if (context.stats.loginsCount === 1 && context.connection === 'Username-Password-Authentication') {
|
||||
|
||||
// Extract tenant from redirect_uri or state parameter
|
||||
const redirectUri = context.request.query.redirect_uri || '';
|
||||
const tenantMatch = redirectUri.match(/([a-z0-9-]+)\.motovaultpro\.(com|local)/);
|
||||
|
||||
if (tenantMatch) {
|
||||
const tenantId = tenantMatch[1];
|
||||
|
||||
// Set initial user metadata
|
||||
user.user_metadata = user.user_metadata || {};
|
||||
user.user_metadata.tenant_id = tenantId;
|
||||
|
||||
// Set signup status (pending for regular tenants, approved for admin)
|
||||
user.user_metadata.signup_status = tenantId === 'admin' ? 'approved' : 'pending';
|
||||
|
||||
// Update user metadata in Auth0
|
||||
auth0.users.updateUserMetadata(user.user_id, user.user_metadata);
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, user, context);
|
||||
}
|
||||
```
|
||||
|
||||
## Tenant Signup Flow Configuration
|
||||
|
||||
### 1. Signup URLs
|
||||
|
||||
**Tenant-Specific Signup**:
|
||||
```
|
||||
https://motovaultpro.com/signup/{tenant-id}
|
||||
```
|
||||
|
||||
**Process**:
|
||||
1. User visits tenant-specific signup URL
|
||||
2. Landing page validates tenant exists
|
||||
3. Redirects to Auth0 with tenant context
|
||||
4. Auth0 Rule sets tenant_id in user metadata
|
||||
5. User account created with status="pending"
|
||||
6. Tenant admin receives notification
|
||||
7. Admin approves/rejects via tenant management API
|
||||
|
||||
### 2. Auth0 Hosted Login Customization
|
||||
|
||||
Add custom CSS and JavaScript to Auth0 Universal Login to support tenant context:
|
||||
|
||||
**Custom CSS** (Dashboard > Universal Login > Advanced Options):
|
||||
```css
|
||||
.tenant-signup-info {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
border-left: 4px solid #007bff;
|
||||
}
|
||||
```
|
||||
|
||||
**Custom JavaScript**:
|
||||
```javascript
|
||||
// Extract tenant from URL parameters
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const redirectUri = urlParams.get('redirect_uri') || '';
|
||||
const tenantMatch = redirectUri.match(/([a-z0-9-]+)\.motovaultpro\.(com|local)/);
|
||||
|
||||
if (tenantMatch && tenantMatch[1] !== 'admin') {
|
||||
const tenantName = tenantMatch[1].replace('-', ' ').toUpperCase();
|
||||
|
||||
// Add tenant information to signup form
|
||||
const container = document.querySelector('.auth0-lock-header');
|
||||
if (container) {
|
||||
const info = document.createElement('div');
|
||||
info.className = 'tenant-signup-info';
|
||||
info.innerHTML = `
|
||||
<strong>Signing up for: ${tenantName}</strong><br>
|
||||
<small>Your account will require admin approval before you can access the system.</small>
|
||||
`;
|
||||
container.appendChild(info);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## JWT Token Format
|
||||
|
||||
After successful authentication, JWT tokens will include:
|
||||
|
||||
**ID Token Claims**:
|
||||
```json
|
||||
{
|
||||
"sub": "auth0|user-123",
|
||||
"email": "user@example.com",
|
||||
"https://motovaultpro.com/tenant_id": "demo-tenant",
|
||||
"https://motovaultpro.com/signup_status": "approved",
|
||||
"iat": 1699123456,
|
||||
"exp": 1699127056
|
||||
}
|
||||
```
|
||||
|
||||
**Access Token Claims**:
|
||||
```json
|
||||
{
|
||||
"sub": "auth0|user-123",
|
||||
"https://motovaultpro.com/tenant_id": "demo-tenant",
|
||||
"scope": "openid profile email",
|
||||
"iat": 1699123456,
|
||||
"exp": 1699127056
|
||||
}
|
||||
```
|
||||
|
||||
## Backend JWT Validation
|
||||
|
||||
Services should validate JWT tokens and extract tenant context:
|
||||
|
||||
```typescript
|
||||
// Example JWT validation middleware
|
||||
import jwt from 'jsonwebtoken';
|
||||
import jwksClient from 'jwks-rsa';
|
||||
|
||||
const client = jwksClient({
|
||||
jwksUri: `https://${AUTH0_DOMAIN}/.well-known/jwks.json`
|
||||
});
|
||||
|
||||
function getKey(header: any, callback: any) {
|
||||
client.getSigningKey(header.kid, (err, key) => {
|
||||
if (err) return callback(err);
|
||||
const signingKey = key.getPublicKey();
|
||||
callback(null, signingKey);
|
||||
});
|
||||
}
|
||||
|
||||
export const validateJWT = (token: string): Promise<any> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
jwt.verify(token, getKey, {
|
||||
audience: process.env.AUTH0_AUDIENCE,
|
||||
issuer: `https://${process.env.AUTH0_DOMAIN}/`,
|
||||
algorithms: ['RS256']
|
||||
}, (err, decoded) => {
|
||||
if (err) return reject(err);
|
||||
resolve(decoded);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Extract tenant from validated JWT
|
||||
export const getTenantFromToken = (decodedToken: any): string => {
|
||||
return decodedToken['https://motovaultpro.com/tenant_id'] || 'admin';
|
||||
};
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Configure the following environment variables for each service:
|
||||
|
||||
**Platform Services**:
|
||||
```env
|
||||
AUTH0_DOMAIN=your-domain.auth0.com
|
||||
AUTH0_AUDIENCE=https://api.motovaultpro.com
|
||||
```
|
||||
|
||||
**Landing Page Service**:
|
||||
```env
|
||||
VITE_AUTH0_DOMAIN=your-domain.auth0.com
|
||||
VITE_AUTH0_CLIENT_ID=your-client-id
|
||||
VITE_TENANTS_API_URL=http://mvp-platform-tenants:8000
|
||||
```
|
||||
|
||||
**Admin/Tenant Services**:
|
||||
```env
|
||||
REACT_APP_AUTH0_DOMAIN=your-domain.auth0.com
|
||||
REACT_APP_AUTH0_CLIENT_ID=your-client-id
|
||||
REACT_APP_AUTH0_AUDIENCE=https://api.motovaultpro.com
|
||||
REACT_APP_TENANT_ID=admin # or specific tenant ID
|
||||
```
|
||||
|
||||
## Testing the Configuration
|
||||
|
||||
### 1. Test Admin Login
|
||||
```bash
|
||||
# Visit admin tenant
|
||||
open http://admin.motovaultpro.local
|
||||
|
||||
# Should redirect to Auth0, login, then return to admin app
|
||||
```
|
||||
|
||||
### 2. Test Tenant Signup
|
||||
```bash
|
||||
# Visit tenant signup
|
||||
open http://motovaultpro.local/signup/demo-tenant
|
||||
|
||||
# Complete signup, verify pending status
|
||||
curl -H "Authorization: Bearer admin-token" \
|
||||
http://localhost:8001/api/v1/signups
|
||||
```
|
||||
|
||||
### 3. Test Approval Workflow
|
||||
```bash
|
||||
# Approve signup
|
||||
curl -X PUT -H "Authorization: Bearer admin-token" \
|
||||
http://localhost:8001/api/v1/signups/1/approve
|
||||
|
||||
# User should now be able to login to tenant
|
||||
open http://demo-tenant.motovaultpro.local
|
||||
```
|
||||
|
||||
## Production Deployment Notes
|
||||
|
||||
1. **SSL Certificates**: Ensure wildcard SSL certificate for `*.motovaultpro.com`
|
||||
2. **DNS Configuration**: Set up wildcard DNS or individual A records per tenant
|
||||
3. **Auth0 Environment**: Use production Auth0 tenant with proper security settings
|
||||
4. **Rate Limiting**: Configure Auth0 rate limiting for signup endpoints
|
||||
5. **Monitoring**: Set up Auth0 logs monitoring for failed login attempts
|
||||
|
||||
This configuration provides a secure, scalable multi-tenant authentication system with proper tenant isolation and admin approval workflows.
|
||||
Reference in New Issue
Block a user