Skip to content

IDP Broker

Pre-release
Pre-release

Choose a tag to compare

@anandlingaraj anandlingaraj released this 12 Jan 13:06
50c2864

Full Changelog: https://github.com/adroitts/identix/commits/v1.0.7-beta

Identity Broker v1.0.7 Beta - Release Notes

License
Version

Breaking Through Microsoft Entra ID Limitations

The Problem Microsoft Can't Solve

Microsoft Entra External ID currently does not support configuring other Microsoft Entra tenants as external identity providers:

"Configuring other Microsoft Entra tenants as an external identity provider is currently not supported. So, the microsoftonline.com domain in the issuer URI isn't accepted."

Microsoft Learn: Custom OIDC Federation

Identity Broker solves this. Deploy a lightweight, enterprise-ready OIDC broker that enables seamless federation across:

  • Multiple Microsoft Entra ID tenants
  • Google Workspace
  • Okta
  • Auth0
  • Azure AD B2C
  • Any OIDC-compliant identity provider

What's New in v1.0.7 Beta

New Features

1. Advanced Branding Customization

  • Custom Login Experience: Fully customizable Home Realm Discovery (HRD) page
  • Logo Upload: Support for custom logos with size presets (small, medium, large)
  • Background Options:
    • Solid colors with color picker
    • Linear gradients with direction control
    • Custom background images
  • Button & Card Styling: Customize colors to match your brand identity
  • Live Preview: See changes in real-time before applying

2. Comprehensive Audit Logging

  • Dual Logging Strategy: Database + file-based logging
  • Sign-In Event Tracking:
    • User email and selected identity provider
    • Success/failure status with error details
    • IP address detection (proxy-aware for X-Forwarded-For)
    • User agent tracking
    • Session correlation
  • Admin Dashboard:
    • Real-time statistics (24h, 7d, total, unique users)
    • Filter by email and status
    • Download log files for SIEM integration
  • Configurable Log Directory: Supports both local development and production paths

3. Enhanced Security Configuration

  • Static Resource Protection: Improved Spring Security configuration for uploaded assets
  • Dynamic Icon System: Context-aware UI icons based on current admin page

Improvements

  • Better error handling in OAuth2 callback flows
  • Optimized database queries for sign-in log retrieval
  • Enhanced IP address extraction for load-balanced environments
  • Improved file upload validation (2MB limit, image type checking)

Bug Fixes

  • Fixed Thymeleaf SpEL parsing errors in HRD template
  • Resolved 404 errors for uploaded branding assets
  • Fixed JPA enum comparison in audit log queries
  • Corrected Alpine.js data binding for dynamic header icons

Core Features

1. OpenID Connect (OIDC) Broker

Identity Broker acts as a standards-compliant OIDC Provider that federates authentication to upstream identity providers:

  • Dynamic Provider Selection: Automatically routes users to their organization's IdP
  • Token Translation: Converts upstream tokens to your application's token format
  • Claims Mapping: Flexible attribute mapping from any IdP to your applications

2. Home Realm Discovery (HRD)

Intelligent user routing based on email domain:

  • Email-Based Routing: Enter email once, automatically redirect to correct IdP
  • Multi-Domain Support: Single IdP can handle multiple email domains
  • Domain Hints: Optional domain_hint parameter for direct IdP selection
  • Custom Branding: Fully white-labeled login experience

3. Multi-Tenant Microsoft Entra ID Federation

The feature Microsoft doesn't support:

  • Federate users from multiple Microsoft Entra ID tenants (Tenant A, B, C, etc.)
  • Each tenant configured as a separate OIDC connection
  • Domain-based routing (e.g., user@companya.com → Tenant A, user@companyb.com → Tenant B)
  • Seamless user experience with automatic tenant detection

4. Universal Identity Provider Support

Connect any OIDC/OAuth2 provider:

  • Microsoft: Entra ID, Azure AD B2C
  • Google: Google Workspace, Gmail
  • Enterprise: Okta, Auth0, Ping Identity, ForgeRock
  • Social: Facebook, GitHub, GitLab
  • Custom: Any OIDC-compliant provider

5. Advanced Multi-Domain Mapping

  • Single IdP configuration can serve multiple email domains
  • Domain-to-IdP mapping stored in database
  • Dynamic configuration without application restart
  • Admin UI for easy domain management

6. Enterprise Secret Management

Securely store client secrets with multiple backend options:

  • Local: AES-256 encrypted secrets with configurable encryption key
  • HashiCorp Vault: Transit engine for encryption-as-a-service
  • AWS Secrets Manager: Native AWS integration
  • Azure Key Vault: Managed secrets in Azure cloud
  • Rotation Support: Update secrets without downtime

7. Comprehensive Audit & Monitoring

  • Sign-In Logs: Track every authentication attempt with full context
  • Admin Activity Logs: Record all configuration changes
  • Statistics Dashboard: Real-time metrics and insights
  • Export Capabilities: Download logs for external analysis
  • SIEM Integration: File-based logs compatible with log shippers

8. Admin Console

Full-featured administrative interface:

  • IdP Configuration Wizard: Step-by-step setup for new providers
  • Domain Management: Map domains to identity providers
  • Branding Customization: White-label the login experience
  • Audit Log Viewer: Search and filter authentication events
  • RP Client Management: Configure relying party applications
  • Dashboard: System health and usage statistics

9. Production-Ready Architecture

  • SQLite Database: Zero-configuration, file-based persistence
  • Optional Redis: Session storage for horizontal scaling
  • JWT Signing: RSA key pairs with JWKS endpoint
  • Health Checks: Actuator endpoints for monitoring
  • Configurable Issuer: Static or dynamic URL detection
  • Session Management: Configurable timeouts and tracking

Architecture Overview

┌─────────────────┐
│   Application   │
│ (Relying Party) │
└────────┬────────┘
         │ OIDC
         │
    ┌────▼─────────────────────────┐
    │   Identity Broker (v1.0.7)   │
    │  ┌─────────────────────────┐ │
    │  │  Home Realm Discovery   │ │
    │  └─────────────────────────┘ │
    │  ┌─────────────────────────┐ │
    │  │  OIDC Provider Engine   │ │
    │  └─────────────────────────┘ │
    │  ┌─────────────────────────┐ │
    │  │   Audit & Logging       │ │
    │  └─────────────────────────┘ │
    └───┬────────┬────────┬────────┘
        │        │        │
   ┌────▼───┐ ┌─▼──────┐ ┌▼────────┐
   │ Entra  │ │ Google │ │  Okta   │
   │Tenant A│ │Workspace│ │Enterprise│
   └────────┘ └────────┘ └─────────┘
   ┌────────┐ ┌────────┐ ┌─────────┐
   │ Entra  │ │ Auth0  │ │  Custom │
   │Tenant B│ │        │ │  OIDC   │
   └────────┘ └────────┘ └─────────┘

Use Cases

1. Multi-Tenant SaaS Applications

Your SaaS serves enterprise customers, each with their own Microsoft Entra ID tenant:

  • Customer A (tenant: contoso.com)
  • Customer B (tenant: fabrikam.com)
  • Customer C (tenant: woodgrove.com)

Without Identity Broker: You can't federate to multiple Entra ID tenants (Microsoft limitation)

With Identity Broker:

  1. Configure each tenant as a separate OIDC connection
  2. Map domains: *@contoso.com → Tenant A, *@fabrikam.com → Tenant B
  3. Users enter email, automatically routed to their corporate IdP
  4. Single OIDC integration in your application

2. Merger & Acquisition Scenarios

Company acquired multiple organizations, each with different identity systems:

  • Legacy employees: Google Workspace
  • Acquired Company A: Microsoft Entra ID
  • Acquired Company B: Okta
  • Contractors: Auth0

Solution: Identity Broker provides single sign-on experience across all identity systems while you migrate to unified directory.

3. Partner/Customer Portal

B2B application needs to support customer authentication:

  • Internal employees: Your corporate Entra ID
  • Partner A employees: Their Entra ID tenant
  • Partner B employees: Their Google Workspace
  • Individual customers: Social login (Google, Facebook)

Solution: Configure all upstream IdPs in Identity Broker, enable domain-based routing, provide single login URL to all users.

4. Development/Staging/Production Isolation

Separate Entra ID tenants for each environment:

  • dev.yourcompany.com → Dev Tenant
  • staging.yourcompany.com → Staging Tenant
  • yourcompany.com → Production Tenant

Solution: Identity Broker routes developers to appropriate tenant based on email domain.

Deployment Options

Option 1: Virtual Machine (VM) Deployment

System Requirements

  • OS: Linux (Ubuntu 22.04 LTS, RHEL 8+, Amazon Linux 2023) or Windows Server 2019+
  • Java: OpenJDK 21 or higher
  • Memory: Minimum 512MB RAM, Recommended 1GB+
  • Storage: 2GB minimum (for application + logs + database)
  • Network: Ports 8080 (HTTP) or 443 (HTTPS with reverse proxy)

Installation Steps

# 1. Install Java 21
sudo apt update
sudo apt install openjdk-21-jre-headless -y

# Verify installation
java -version

# 2. Create application directory
sudo mkdir -p /opt/idp-broker
sudo mkdir -p /opt/idp-broker/data
sudo mkdir -p /opt/idp-broker/logs

# 3. Download the WAR file
cd /opt/idp-broker
sudo wget https://github.com/adroitts/identix/releases/download/v1.0.7-beta/idp-broker-1.0.7-beta.war

# 4. Create application user (security best practice)
sudo useradd -r -s /bin/false idpbroker
sudo chown -R idpbroker:idpbroker /opt/idp-broker

# 5. Create environment configuration
sudo tee /opt/idp-broker/application.env > /dev/null <<EOF
# Broker Configuration
BROKER_ISSUER=https://idp.yourdomain.com
BROKER_ISSUER_DYNAMIC=false

# Database Path
DB_PATH=/opt/idp-broker/data/idp-broker.db

# Logs Directory
APP_LOGS_DIRECTORY=/opt/idp-broker/logs

# Secret Encryption (Generate with: openssl rand -base64 32)
SECRET_ENCRYPTION_KEY=YOUR_BASE64_ENCRYPTION_KEY_HERE

# Optional: Redis for session clustering
REDIS_ENABLED=false
# SPRING_DATA_REDIS_HOST=localhost
# SPRING_DATA_REDIS_PORT=6379
# SPRING_DATA_REDIS_PASSWORD=

# Optional: Azure Key Vault
# SECRET_MANAGER_TYPE=azure
# AZURE_KEYVAULT_URI=https://your-vault.vault.azure.net/
# AZURE_TENANT_ID=your-tenant-id

# Optional: AWS Secrets Manager
# SECRET_MANAGER_TYPE=aws
# AWS_REGION=us-east-1
# AWS_SECRETS_PREFIX=idp-broker/

# Optional: HashiCorp Vault
# SECRET_MANAGER_TYPE=vault
# VAULT_ADDR=http://localhost:8200
# VAULT_TOKEN=your-vault-token
EOF

# 6. Create systemd service
sudo tee /etc/systemd/system/idp-broker.service > /dev/null <<EOF
[Unit]
Description=Identity Broker Service
After=network.target

[Service]
Type=simple
User=idpbroker
WorkingDirectory=/opt/idp-broker
EnvironmentFile=/opt/idp-broker/application.env
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar /opt/idp-broker/idp-broker-1.0.7-beta.war
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

# 7. Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable idp-broker
sudo systemctl start idp-broker

# 8. Check status
sudo systemctl status idp-broker

# View logs
sudo journalctl -u idp-broker -f

Nginx Reverse Proxy (HTTPS)

# Install Nginx
sudo apt install nginx certbot python3-certbot-nginx -y

# Create Nginx configuration
sudo tee /etc/nginx/sites-available/idp-broker > /dev/null <<EOF
server {
    listen 80;
    server_name idp.yourdomain.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_set_header X-Forwarded-Host \$host;
        proxy_set_header X-Forwarded-Port \$server_port;
    }

    client_max_body_size 10M;
}
EOF

# Enable site
sudo ln -s /etc/nginx/sites-available/idp-broker /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

# Obtain SSL certificate
sudo certbot --nginx -d idp.yourdomain.com

Option 2: Docker Container

Dockerfile

Create Dockerfile in your project:

FROM eclipse-temurin:21-jre-jammy

# Create app user
RUN groupadd -r idpbroker && useradd -r -g idpbroker idpbroker

# Set working directory
WORKDIR /app

# Copy WAR file
COPY idp-broker-1.0.7-beta.war /app/app.war

# Create necessary directories
RUN mkdir -p /app/data /app/logs && \
    chown -R idpbroker:idpbroker /app

# Switch to non-root user
USER idpbroker

# Expose port
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

# Run application
ENTRYPOINT ["java", "-Xms512m", "-Xmx1024m", "-jar", "/app/app.war"]

Docker Compose

version: '3.8'

services:
  idp-broker:
    build: ..
    container_name: idp-broker
    ports:
      - "8080:8080"
    environment:
      - BROKER_ISSUER=https://idp.yourdomain.com
      - BROKER_ISSUER_DYNAMIC=false
      - DB_PATH=/app/data/idp-broker.db
      - APP_LOGS_DIRECTORY=/app/logs
      - SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
      - REDIS_ENABLED=false
    volumes:
      - ./data:/app/data
      - ./logs:/app/logs
    restart: unless-stopped
    networks:
      - idp-network

  # Optional: Redis for session clustering
  redis:
    image: redis:7-alpine
    container_name: idp-redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    restart: unless-stopped
    networks:
      - idp-network

  # Optional: Nginx reverse proxy
  nginx:
    image: nginx:alpine
    container_name: idp-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - idp-broker
    restart: unless-stopped
    networks:
      - idp-network

volumes:
  redis-data:

networks:
  idp-network:
    driver: bridge

Run with Docker

# Build image
docker build -t idp-broker:1.0.7-beta .

# Run container
docker run -d \
  --name idp-broker \
  -p 8080:8080 \
  -v $(pwd)/data:/app/data \
  -v $(pwd)/logs:/app/logs \
  -e BROKER_ISSUER=https://idp.yourdomain.com \
  -e SECRET_ENCRYPTION_KEY=$(openssl rand -base64 32) \
  idp-broker:1.0.7-beta

# Or use docker-compose
docker-compose up -d

# View logs
docker logs -f idp-broker

Option 3: Kubernetes Deployment

Kubernetes Manifests

namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: idp-broker

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: idp-broker-secrets
  namespace: idp-broker
type: Opaque
stringData:
  SECRET_ENCRYPTION_KEY: "YOUR_BASE64_KEY_HERE"
  # For Redis
  SPRING_DATA_REDIS_PASSWORD: "your-redis-password"
  # For Azure Key Vault (if using managed identity, omit these)
  AZURE_KEYVAULT_URI: "https://your-vault.vault.azure.net/"
  AZURE_TENANT_ID: "your-tenant-id"

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: idp-broker-config
  namespace: idp-broker
data:
  BROKER_ISSUER: "https://idp.yourdomain.com"
  BROKER_ISSUER_DYNAMIC: "false"
  DB_PATH: "/app/data/idp-broker.db"
  APP_LOGS_DIRECTORY: "/app/logs"
  REDIS_ENABLED: "true"
  SPRING_DATA_REDIS_HOST: "idp-redis-service"
  SPRING_DATA_REDIS_PORT: "6379"
  SECRET_MANAGER_TYPE: "local"

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: idp-broker-data-pvc
  namespace: idp-broker
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard  # Change to your storage class

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: idp-broker-logs-pvc
  namespace: idp-broker
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  storageClassName: standard

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: idp-broker
  namespace: idp-broker
  labels:
    app: idp-broker
spec:
  replicas: 2
  selector:
    matchLabels:
      app: idp-broker
  template:
    metadata:
      labels:
        app: idp-broker
    spec:
      containers:
      - name: idp-broker
        image: yourdockerhub/idp-broker:1.0.7-beta
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: JAVA_OPTS
          value: "-Xms512m -Xmx1024m"
        envFrom:
        - configMapRef:
            name: idp-broker-config
        - secretRef:
            name: idp-broker-secrets
        volumeMounts:
        - name: data
          mountPath: /app/data
        - name: logs
          mountPath: /app/logs
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: idp-broker-data-pvc
      - name: logs
        persistentVolumeClaim:
          claimName: idp-broker-logs-pvc

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: idp-broker-service
  namespace: idp-broker
spec:
  type: ClusterIP
  selector:
    app: idp-broker
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP
    name: http

ingress.yaml (for Azure AKS with Application Gateway)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: idp-broker-ingress
  namespace: idp-broker
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    cert-manager.io/cluster-issuer: letsencrypt-prod
    appgw.ingress.kubernetes.io/ssl-redirect: "true"
    appgw.ingress.kubernetes.io/connection-draining: "true"
    appgw.ingress.kubernetes.io/connection-draining-timeout: "30"
spec:
  tls:
  - hosts:
    - idp.yourdomain.com
    secretName: idp-broker-tls
  rules:
  - host: idp.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: idp-broker-service
            port:
              number: 8080

hpa.yaml (Horizontal Pod Autoscaler)

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: idp-broker-hpa
  namespace: idp-broker
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: idp-broker
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Deploy to Kubernetes

# Create namespace and resources
kubectl apply -f namespace.yaml
kubectl apply -f secret.yaml
kubectl apply -f configmap.yaml
kubectl apply -f pvc.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
kubectl apply -f hpa.yaml

# Check deployment status
kubectl get pods -n idp-broker
kubectl get svc -n idp-broker
kubectl get ingress -n idp-broker

# View logs
kubectl logs -f deployment/idp-broker -n idp-broker

# Scale manually (if not using HPA)
kubectl scale deployment idp-broker --replicas=3 -n idp-broker

Azure AKS with Azure Key Vault Integration

# Use Azure Workload Identity
apiVersion: v1
kind: ServiceAccount
metadata:
  name: idp-broker-sa
  namespace: idp-broker
  annotations:
    azure.workload.identity/client-id: "YOUR_MANAGED_IDENTITY_CLIENT_ID"

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: idp-broker
  namespace: idp-broker
spec:
  template:
    metadata:
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: idp-broker-sa
      containers:
      - name: idp-broker
        env:
        - name: SECRET_MANAGER_TYPE
          value: "azure"
        - name: AZURE_KEYVAULT_URI
          value: "https://your-vault.vault.azure.net/"
        # Managed identity handles authentication automatically

Configuration Examples

Example 1: Multi-Tenant Microsoft Setup

Configure three different Microsoft Entra ID tenants:

# Admin UI Configuration
IDP Configurations:

  1. Contoso Corporation
     - Name: Contoso Entra ID
     - Provider Type: microsoft
     - Domain Hint: contoso.com
     - Client ID: 11111111-1111-1111-1111-111111111111
     - Client Secret: <stored in Key Vault>
     - Authorization URL: https://login.microsoftonline.com/contoso.onmicrosoft.com/oauth2/v2.0/authorize
     - Token URL: https://login.microsoftonline.com/contoso.onmicrosoft.com/oauth2/v2.0/token
     - User Info URL: https://graph.microsoft.com/oidc/userinfo
     - JWKS URI: https://login.microsoftonline.com/contoso.onmicrosoft.com/discovery/v2.0/keys
     - Scopes: openid profile email

  2. Fabrikam Industries
     - Name: Fabrikam Entra ID
     - Provider Type: microsoft
     - Domain Hint: fabrikam.com
     - Client ID: 22222222-2222-2222-2222-222222222222
     - Client Secret: <stored in Key Vault>
     - Authorization URL: https://login.microsoftonline.com/fabrikam.onmicrosoft.com/oauth2/v2.0/authorize
     - Token URL: https://login.microsoftonline.com/fabrikam.onmicrosoft.com/oauth2/v2.0/token
     - User Info URL: https://graph.microsoft.com/oidc/userinfo
     - JWKS URI: https://login.microsoftonline.com/fabrikam.onmicrosoft.com/discovery/v2.0/keys
     - Scopes: openid profile email

  3. Woodgrove Bank
     - Name: Woodgrove Entra ID
     - Provider Type: microsoft
     - Domain Hint: woodgrove.com
     - Client ID: 33333333-3333-3333-3333-333333333333
     - Client Secret: <stored in Key Vault>
     - Authorization URL: https://login.microsoftonline.com/woodgrove.onmicrosoft.com/oauth2/v2.0/authorize
     - Token URL: https://login.microsoftonline.com/woodgrove.onmicrosoft.com/oauth2/v2.0/token
     - User Info URL: https://graph.microsoft.com/oidc/userinfo
     - JWKS URI: https://login.microsoftonline.com/woodgrove.onmicrosoft.com/discovery/v2.0/keys
     - Scopes: openid profile email

Domain Mappings:
  - @contoso.com, @contoso.net → Contoso Entra ID
  - @fabrikam.com, @fabrikam.io → Fabrikam Entra ID
  - @woodgrove.com, @woodgrovebank.com → Woodgrove Entra ID

Example 2: Mixed Identity Provider Setup

IDP Configurations:

  1. Corporate Entra ID
     - Domains: @yourcompany.com

  2. Google Workspace (Partners)
     - Domains: @partner1.com, @partner2.com

  3. Okta (Contractors)
     - Domains: @contractor.com

  4. Auth0 (Social Login)
     - Domains: @gmail.com, @outlook.com (catch-all)

First-Time Setup

  1. Access Admin Console: https://idp.yourdomain.com/admin

    • Default credentials: admin / admin123 (change immediately!)
  2. Configure Broker Issuer:

    • Set BROKER_ISSUER environment variable to your public URL
    • Or enable dynamic issuer with BROKER_ISSUER_DYNAMIC=true
  3. Generate Encryption Key:

    openssl rand -base64 32

    Set as SECRET_ENCRYPTION_KEY environment variable

  4. Add First Identity Provider:

    • Navigate to "IDP Configurations"
    • Click "Add New Provider"
    • Follow the wizard to configure OIDC connection
  5. Configure Domain Mapping:

    • In IDP configuration, add email domains
    • Example: @contoso.com, @fabrikam.com
  6. Customize Branding (Optional):

    • Navigate to "Branding"
    • Upload logo, set colors, customize HRD page
  7. Register Your Application:

    • Navigate to "RP Clients"
    • Click "Add Client"
    • Note the Client ID and Secret
    • Set redirect URI to your app's callback URL
  8. Configure Your Application:

    OIDC Configuration:
      Issuer: https://idp.yourdomain.com
      Authorization Endpoint: https://idp.yourdomain.com/oauth2/authorize
      Token Endpoint: https://idp.yourdomain.com/oauth2/token
      UserInfo Endpoint: https://idp.yourdomain.com/oauth2/userinfo
      JWKS URI: https://idp.yourdomain.com/.well-known/jwks.json
      Client ID: <from step 7>
      Client Secret: <from step 7>
      Scopes: openid profile email

Monitoring & Operations

Health Checks

# Application health
curl https://idp.yourdomain.com/actuator/health

# Detailed health (requires authentication)
curl https://idp.yourdomain.com/actuator/health -H "Authorization: Bearer <token>"

Metrics

# View metrics
curl https://idp.yourdomain.com/actuator/metrics

# Specific metric
curl https://idp.yourdomain.com/actuator/metrics/jvm.memory.used

Logs

# VM deployment
sudo journalctl -u idp-broker -f

# Docker
docker logs -f idp-broker

# Kubernetes
kubectl logs -f deployment/idp-broker -n idp-broker

# Sign-in specific logs
tail -f /opt/idp-broker/logs/signin.log

Security Considerations

  1. Change Default Admin Credentials: Immediately after first login
  2. Use HTTPS: Always deploy behind TLS/SSL termination
  3. Secure Encryption Key: Store SECRET_ENCRYPTION_KEY in environment variables, never in code
  4. Key Vault Integration: Use Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault for production
  5. Network Security:
    • Restrict admin console access to corporate network
    • Use Azure Private Link / AWS PrivateLink if in cloud
  6. Regular Updates: Subscribe to security advisories
  7. Audit Logs: Regularly review sign-in logs for suspicious activity
  8. Rate Limiting: Configure reverse proxy rate limiting
  9. Session Timeouts: Adjust server.servlet.session.timeout for your security policy
  10. CORS Configuration: Restrict allowed origins in production

Performance Tuning

JVM Options

# For production workloads
-Xms1024m -Xmx2048m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/app/logs

Redis Session Store (for multiple replicas)

redis.enabled=true
spring.data.redis.host=your-redis-host
spring.data.redis.port=6379
spring.data.redis.password=your-password
spring.data.redis.ssl.enabled=true

Database Optimization

  • SQLite is suitable for up to 100,000 users
  • For larger deployments, consider PostgreSQL migration (roadmap feature)

Troubleshooting

Issue: 404 on uploaded logos

Solution: Ensure /uploads/** path is in Spring Security permitAll list

Issue: Callback URL mismatch

Solution: Check BROKER_ISSUER matches your public URL, or enable dynamic issuer

Issue: Redis connection fails

Solution: Set REDIS_ENABLED=false if not using Redis, or verify connection details

Issue: JWKS keys not rotating

Solution: JWT keys are generated on first startup and persisted. Delete and restart to regenerate.

Migration Guide

From v1.0.6 to v1.0.7-beta

  1. Backup Database:

    cp data/idp-broker.db data/idp-broker.db.backup
  2. Update WAR File: Replace with new version

  3. Add New Configuration (optional):

    # Add to environment file
    APP_LOGS_DIRECTORY=/opt/idp-broker/logs
  4. Database Migration: Automatic via Hibernate ddl-auto=update

    • New tables: signin_logs, branding_settings
  5. Restart Service:

    sudo systemctl restart idp-broker

Roadmap

  • PostgreSQL/MySQL database support
  • SAML 2.0 provider support
  • Multi-factor authentication (MFA)
  • Advanced analytics dashboard
  • User consent management
  • API for programmatic configuration
  • Webhook notifications
  • Custom claim transformations
  • Rate limiting per tenant
  • Geo-restriction policies

Support & Resources

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributors

Special thanks to all contributors who made this release possible!


Download: idp-broker-1.0.7-beta.war

SHA256: <generate after build>

Release Date: January 11, 2026


Quick Start Commands

# Download and run (Linux/Mac)
wget https://github.com/adroitts/identix/releases/download/v1.0.7-beta/idp-broker-1.0.7-beta.war
java -jar idp-broker-1.0.7-beta.war

# Access admin console
open http://localhost:8080/admin

Breaking through Microsoft's limitations, one tenant at a time.