Skip to main content

Identity Platform Setup Guide

Overview

This guide provides step-by-step instructions for configuring Google Cloud Identity Platform (Firebase Authentication) for the CODITECT License Server.

Required Configuration:

  • Multi-tenancy support
  • OAuth providers: Google, GitHub
  • Email/Password authentication
  • Custom JWT claims (tenant_id, role, features)
  • JWT expiration: 1 hour (refresh token: 30 days)

Prerequisites:

  • GCP Project: coditect-cloud-infra (374018874256)
  • Identity Platform API enabled ✅
  • Project Owner or Firebase Admin role

Step 1: Initialize Firebase Project

1.1 Access Firebase Console

  1. Navigate to Firebase Console
  2. Click "Add project"
  3. Select existing GCP project: coditect-cloud-infra
  4. Important: Select "Pay as you go (Blaze)" plan (required for Identity Platform)
  5. Confirm Firebase billing and click "Continue"

1.2 Verify Firebase Project Created

gcloud firebase projects list | grep coditect-cloud-infra

Expected output:

coditect-cloud-infra  coditect-cloud-infra  374018874256

Step 2: Enable Authentication

2.1 Navigate to Authentication

  1. In Firebase Console, select coditect-cloud-infra project
  2. Click "Authentication" in left sidebar
  3. Click "Get started"

2.2 Configure Sign-in Methods

Email/Password Provider

  1. Click "Sign-in method" tab
  2. Click "Email/Password"
  3. Toggle "Enable"
  4. Do NOT enable "Email link (passwordless sign-in)" (not needed for License API)
  5. Click "Save"

Google OAuth Provider

  1. Click "Add new provider"
  2. Select "Google"
  3. Toggle "Enable"
  4. Web SDK configuration:
    • Project public-facing name: CODITECT License Server
    • Project support email: support@az1.ai
  5. Click "Save"
  6. Copy OAuth Client ID - needed for Django settings

GitHub OAuth Provider

  1. Click "Add new provider"
  2. Select "GitHub"
  3. Toggle "Enable"
  4. Create GitHub OAuth App first:
    • Go to https://github.com/settings/developers
    • Click "New OAuth App"
    • Application name: CODITECT License Server
    • Homepage URL: https://auth.coditect.ai
    • Authorization callback URL: https://coditect-cloud-infra.firebaseapp.com/__/auth/handler
    • Click "Register application"
    • Copy Client ID and Client Secret
  5. Back in Firebase Console:
    • Paste GitHub Client ID
    • Paste GitHub Client Secret
  6. Click "Save"

Step 3: Configure Multi-Tenancy

3.1 Enable Multi-Tenant Support

Note: Multi-tenancy in Identity Platform allows isolating users by tenant (organization).

# Enable multi-tenancy via REST API (no UI option)
curl -X PATCH \
"https://identitytoolkit.googleapis.com/admin/v2/projects/coditect-cloud-infra/config" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"multiTenant": {
"allowTenants": true,
"defaultTenantLocation": "us-central1"
}
}'

3.2 Create Default Tenant

# Create default tenant for initial users
curl -X POST \
"https://identitytoolkit.googleapis.com/v2/projects/coditect-cloud-infra/tenants" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{
"displayName": "Default Tenant",
"allowPasswordSignup": true,
"enableEmailLinkSignin": false,
"enableAnonymousUser": false,
"mfaConfig": {
"state": "DISABLED"
}
}'

Save tenant ID from response - needed for Django settings.


Step 4: Configure JWT Settings

4.1 Update Token Expiration

  1. In Firebase Console → Authentication → Settings
  2. Scroll to "Session management"
  3. Set ID token expiration: 3600 seconds (1 hour)
  4. Set Refresh token expiration: 2592000 seconds (30 days)
  5. Click "Save"

4.2 Configure Custom Claims

Custom claims are set programmatically in Django backend during user creation:

from firebase_admin import auth

# Set custom claims on user creation
auth.set_custom_user_claims(
uid=user.firebase_uid,
custom_claims={
"tenant_id": str(user.tenant_id),
"role": user.role, # ADMIN, MEMBER
"features": license.features # ["marketplace", "analytics"]
}
)

Step 5: Configure Workload Identity (GKE Authentication)

The Django backend running on GKE will use Workload Identity to authenticate with Firebase Admin SDK without needing service account keys.

Status: ✅ Service account created: license-api-firebase@coditect-cloud-infra.iam.gserviceaccount.com Status: ✅ IAM roles granted: firebase.admin, identitytoolkit.admin

5.1 Enable Workload Identity on GKE Cluster

# Verify Workload Identity is enabled (should already be from Phase 0)
gcloud container clusters describe coditect-cluster \
--region=us-central1 \
--format="value(workloadIdentityConfig.workloadPool)"

Expected output: coditect-cloud-infra.svc.id.goog

5.2 Create Kubernetes Service Account

# Create Kubernetes service account for License API
kubectl create serviceaccount license-api-sa \
--namespace=default

5.3 Bind GCP Service Account to Kubernetes Service Account

# Allow Kubernetes service account to impersonate GCP service account
gcloud iam service-accounts add-iam-policy-binding \
license-api-firebase@coditect-cloud-infra.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:coditect-cloud-infra.svc.id.goog[default/license-api-sa]"

5.4 Annotate Kubernetes Service Account

# Link Kubernetes SA to GCP SA
kubectl annotate serviceaccount license-api-sa \
--namespace=default \
iam.gke.io/gcp-service-account=license-api-firebase@coditect-cloud-infra.iam.gserviceaccount.com

5.5 Verify Workload Identity Binding

# Test authentication from a pod
kubectl run -it --rm test-wi \
--image=google/cloud-sdk:slim \
--serviceaccount=license-api-sa \
--namespace=default \
-- gcloud auth list

Expected output: Should show license-api-firebase@coditect-cloud-infra.iam.gserviceaccount.com as active account.


Step 6: Configure Authorized Domains

6.1 Add Production Domain

  1. In Firebase Console → Authentication → Settings
  2. Scroll to "Authorized domains"
  3. Click "Add domain"
  4. Add: auth.coditect.ai
  5. Add: coditect.ai (for OAuth redirects)
  6. Click "Add"

6.2 Configure OAuth Redirect URIs

For Google OAuth:

  • Redirect URI: https://auth.coditect.ai/__/auth/handler
  • Authorized JavaScript origins: https://auth.coditect.ai

For GitHub OAuth:

  • Authorization callback URL: https://auth.coditect.ai/__/auth/handler

Step 7: Test Authentication Flow

7.1 Create Test User

# Create test user via Firebase CLI
firebase auth:import test-users.csv --project coditect-cloud-infra

test-users.csv:

uid,email,passwordHash,displayName
test-user-1,test@coditect.ai,password123,Test User

7.2 Test JWT Token Generation

# Get ID token for test user
curl -X POST \
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=YOUR_WEB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "test@coditect.ai",
"password": "password123",
"returnSecureToken": true
}'

Expected response:

{
"idToken": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
"email": "test@coditect.ai",
"refreshToken": "...",
"expiresIn": "3600",
"localId": "test-user-1"
}

7.3 Verify JWT Token

# Python verification (Django backend pattern)
from firebase_admin import auth, credentials, initialize_app

# Initialize Firebase Admin SDK
cred = credentials.Certificate('firebase-admin-key.json')
initialize_app(cred)

# Verify token
try:
decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']
email = decoded_token['email']
tenant_id = decoded_token.get('tenant_id') # Custom claim
role = decoded_token.get('role') # Custom claim
print(f"✅ Token valid: {email} (tenant: {tenant_id}, role: {role})")
except Exception as e:
print(f"❌ Token invalid: {e}")

Step 8: Django Backend Integration

8.1 Install Firebase Admin SDK

pip install firebase-admin

8.2 Configure Django Settings

settings.py:

# Firebase Authentication
FIREBASE_ADMIN_CREDENTIALS = os.getenv('FIREBASE_ADMIN_KEY_PATH') # From Secret Manager

# Initialize Firebase Admin SDK on startup
import firebase_admin
from firebase_admin import credentials

if not firebase_admin._apps:
cred = credentials.Certificate(FIREBASE_ADMIN_CREDENTIALS)
firebase_admin.initialize_app(cred)

8.3 Create Custom Authentication Backend

backends/firebase.py:

from django.contrib.auth.backends import BaseBackend
from firebase_admin import auth
from apps.users.models import User

class FirebaseAuthentication(BaseBackend):
def authenticate(self, request, firebase_token=None):
if not firebase_token:
return None

try:
# Verify Firebase JWT
decoded_token = auth.verify_id_token(firebase_token)

# Get or create user
user, created = User.objects.get_or_create(
firebase_uid=decoded_token['uid'],
defaults={
'email': decoded_token['email'],
'tenant_id': decoded_token.get('tenant_id'),
'role': decoded_token.get('role', 'MEMBER')
}
)

return user
except Exception as e:
return None

settings.py:

AUTHENTICATION_BACKENDS = [
'backends.firebase.FirebaseAuthentication',
'django.contrib.auth.backends.ModelBackend', # Fallback
]

8.4 Create Authentication Middleware

middleware/jwt_auth.py:

from django.http import JsonResponse
from firebase_admin import auth

class FirebaseJWTMiddleware:
def __init__(self, get_response):
self.get_response = get_response

def __call__(self, request):
# Extract JWT from Authorization header
auth_header = request.META.get('HTTP_AUTHORIZATION', '')

if auth_header.startswith('Bearer '):
token = auth_header.split(' ')[1]

try:
# Verify and decode JWT
decoded_token = auth.verify_id_token(token)

# Attach user info to request
request.firebase_user = decoded_token
request.tenant_id = decoded_token.get('tenant_id')
request.user_role = decoded_token.get('role')

except Exception as e:
return JsonResponse(
{'detail': 'Invalid authentication token'},
status=401
)

response = self.get_response(request)
return response

settings.py:

MIDDLEWARE = [
# ... other middleware
'middleware.jwt_auth.FirebaseJWTMiddleware',
]

Step 9: Security Hardening

9.1 Enable Advanced Security Features

  1. In Firebase Console → Authentication → Settings → Security
  2. Email enumeration protection: Enable (prevents attackers from discovering registered emails)
  3. Suspicious activity detection: Enable
  4. Account takeover protection: Enable

9.2 Configure Rate Limiting

# Django settings for authentication rate limiting
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/minute', # Unauthenticated requests
'user': '100/minute' # Authenticated requests
}
}

9.3 Enable Audit Logging

gcloud logging logs list | grep firebase

Monitor for:

  • Failed authentication attempts
  • Unusual login patterns
  • Token verification failures

Step 10: Production Checklist

Pre-Launch Verification

  • Identity Platform API enabled
  • Email/Password provider configured
  • Google OAuth provider configured with client ID
  • GitHub OAuth provider configured with client ID/secret
  • Multi-tenancy enabled
  • JWT expiration set (1 hour / 30 days)
  • Service account created with Firebase Admin role
  • Service account key stored in Secret Manager
  • Authorized domains added (auth.coditect.ai, coditect.ai)
  • OAuth redirect URIs configured
  • Django backend Firebase Admin SDK integrated
  • Custom authentication backend implemented
  • JWT middleware configured
  • Email enumeration protection enabled
  • Suspicious activity detection enabled
  • Rate limiting configured
  • Audit logging enabled

Post-Launch Monitoring

  • Monitor authentication success/failure rates
  • Track JWT token verification latency
  • Alert on suspicious login patterns
  • Review audit logs weekly

Troubleshooting

Issue: "Invalid token" errors

Cause: Clock skew between Firebase and Django server

Fix:

# Sync server time with NTP
sudo ntpdate -s time.google.com

Issue: "Tenant not found"

Cause: Multi-tenancy not properly configured

Fix:

# Verify tenant exists
curl "https://identitytoolkit.googleapis.com/v2/projects/coditect-cloud-infra/tenants" \
-H "Authorization: Bearer $(gcloud auth print-access-token)"

Issue: OAuth redirect URI mismatch

Cause: Redirect URI not added to authorized domains

Fix:

  1. Firebase Console → Authentication → Settings → Authorized domains
  2. Add: auth.coditect.ai
  3. Update OAuth provider callback URL

Cost Estimate

Identity Platform Pricing (Pay-as-you-go):

  • First 50,000 MAU (Monthly Active Users): Free
  • 50,001 - 100,000 MAU: $0.0055/user
  • 100,001+ MAU: $0.0025/user

Phone authentication: $0.06/verification (not used)

Estimated monthly cost:

  • Development (< 50 users): $0
  • Production (100-500 users): $0
  • Production (1,000 users): $5.50
  • Production (10,000 users): $100

SMS verification (if enabled): Additional $0.06/verification


References


Created: November 30, 2025 Status: Ready for implementation Next Steps: Follow steps 1-10 to complete Identity Platform setup Estimated Time: 2-3 hours (manual console configuration + testing)