Skip to content

IDP Developer Setup Guide

Introduction

This guide provides step-by-step instructions for setting up a local development environment using the Identity Provider (IDP) system. The setup involves configuring the IDP API Server with organizational structure, generating device credentials, and enabling IDP authentication on Commerce servers.

Prerequisites

Before starting the IDP setup, ensure you have:

  • IDP API Server running locally or accessible remotely
  • Commerce server configured for local development
  • Administrative access to create organizations, environments, and devices
  • Basic understanding of OAuth2 client credentials flow

IDP API Server Setup

1. Organization Structure Creation

The IDP system uses a hierarchical structure that must be established before device authentication can occur.

Create Organization

POST /api/internal/org
Content-Type: application/json

{
    "id": "local-dev",
    "name": "Local Development Organization",
    "description": "Development environment for local testing"
}

Create Environment

POST /api/internal/org/local-dev/env
Content-Type: application/json

{
    "id": "development",
    "name": "Development Environment", 
    "description": "Local development environment"
}

Note: Creating an environment automatically generates a client pool with unique OAuth2 configuration and signing keys.

2. Device Registration

Register Device

POST /api/internal/org/local-dev/env/development/device
Content-Type: application/json

{
    "id": "pos-terminal-001",
    "name": "POS Terminal 001",
    "description": "Development POS terminal",
    "metadata": {
        "location": "checkout-1",
        "terminal_type": "pos"
    },
    "tags": {
        "business_unit_id": "store-001",
        "country": "US",
        "state": "NY",
        "app_id": "pos",
        "device_type": "terminal"
    }
}

Create Device Application Binding

POST /api/internal/org/local-dev/env/development/device/pos-terminal-001/app
Content-Type: application/json

{
    "clientAppId": "client",
    "name": "POS Client Application",
    "description": "Primary client application for POS terminal"
}

3. OTP Generation

Generate a one-time password for device activation:

POST /api/internal/org/local-dev/env/development/device/pos-terminal-001/app/client/otp
Content-Type: application/json

{}

Response Example:

{
    "otp": "123456",
    "expirationTime": "2025-08-14T15:30:00Z",
    "deviceId": "pos-terminal-001",
    "clientAppId": "client"
}

Important: Save the generated OTP as it will be needed for device activation. OTPs typically expire within a short timeframe (e.g., 10 minutes).


Commerce Server Configuration

1. Enable IDP Profile

Configure the Commerce server to use IDP authentication by enabling the idp Spring profile.

Application Configuration (application.yml)

spring:
    profiles:
        active: 
            - idp
            - development

IDP-Specific Configuration (application-idp.yml)

secured:
    idp:
        enabled: true
        baseUrl: https://idp.device.cp.jumpmind.cloud  # IDP API Server URL
        authPoolId: <auth pool ID>  # Generated client pool ID
        organizationId: <organization ID>  # Your organization ID
        env: <environment ID>  # Your environment ID
        apiKey: <api key>  # API key for internal API access
        jwksCacheFile: ./work/jwks.json
        httpTimeoutInMs: 5000
        offlineExpirationLeniencyInMinutes: 4320  # 3 days

    idp-client:
        key-store-type: <file/key_chain/windows_my/windows_root>
        active-client: <client-credentials/jwt-bearer>

    idp-client-principal:
        subject: <device/asset id>
spring:
    security:
        oauth2:
            client:
                registration:
                    client-credentials:
                        client-id: <your-client-id>
                        client-secret: <your-client-secret>
                provider:
                    jmc-idp:
                        token-uri: ${secured.idp.baseUrl}/${secured.idp.authPoolId}/oauth2/token
            resourceserver:
                jwt:
                    jwk-set-uri: ${secured.idp.baseUrl}/${secured.idp.authPoolId}/.well-known/jwks.json

Notes regarding configuration: - baseURL in IDP configuration is set to the production instance of IDP. This can be overriden for local development. - authPoolId, organizationId, and env must match the values created in the IDP API server for the customer implementation that the Commerce server will authenticate against. - apiKey is required for the Commerce server to access internal management APIs if needed. - client-id and client-secret will typically be poplulated during the bootstrapping process but can be generated and set manually for testing.

2. Profile Activation Impact

When the idp profile is enabled, the Commerce server:

  • Disables Default Security: Removes standard username/password authentication
  • Enables JWT Validation: Configures Spring Security to validate JWT tokens from IDP
  • Activates Token Caching: Enables secure token caching using system keychain
  • Configures JWKS Integration: Sets up automatic JWK retrieval and validation
  • Enables Offline Mode: Allows cached JWKs and lenient token expiration for offline scenarios

Client Application Setup

1. Device Activation Process

Version 1 (Service-Based)

The client application will automatically prompt for OTP during startup through the IdpPersonalizationStartupTask:

  1. Startup Prompt: Modal dialog requests 6-digit OTP
  2. Device Activation: OTP submitted to /api/otp/activate endpoint
  3. Credential Storage: Client credentials stored in secure storage
  4. Token Acquisition: OAuth2 client credentials flow obtains access token
  5. Application Configuration: JWT claims populate server URL and device configuration

Version 2 (NGXS State-Based)

Modern implementation uses federated modules and centralized state:

  1. Route Loading: Attempts to load remote IDP module, falls back to local routes
  2. Component Rendering: Device registration component handles OTP input
  3. State Coordination: NGXS actions orchestrate registration and authentication
  4. Cross-Module Integration: IDP state populates provisioning and bootstrap states
  5. Transparent Authentication: HTTP interceptor automatically adds Bearer tokens

2. Expected Client Behavior

After successful device activation:

  • HTTP Requests: Automatically authenticated with Bearer tokens
  • WebSocket Connections: Include authentication headers for real-time communication
  • Server Configuration: Application configured with IDP-provided server URL and device metadata
  • Token Refresh: Automatic token renewal before expiration
  • Offline Support: Cached tokens allow operation during IDP server unavailability

Troubleshooting

1. Common Setup Issues

OTP Expired

Error: OTP has expired or is invalid
Solution: Generate a new OTP using the API endpoint and retry activation.

Client Pool Not Found

Error: Unknown client pool ID
Solution: Verify the authPoolId configuration matches the generated client pool from environment creation.

JWKS Unreachable

Error: Unable to fetch JWKS from remote server
Solution: - Verify IDP server is running and accessible - Check network connectivity and firewall settings - Ensure JWKS endpoint URL is correctly configured

Token Validation Failures

Error: JWT signature verification failed
Solution: - Ensure client is using tokens from correct client pool - Verify JWKS endpoint is accessible from Commerce server

2. Configuration Validation

Verify IDP Server Endpoints

# Test JWKS endpoint  
curl http://localhost:8080/client-pool-development-abc123/.well-known/jwks.json

3. Development Tips

Reset Device Credentials

If old credentials cause issues, clear local storage and refresh.

Monitor Authentication Flow

Enable debug logging for detailed authentication flow visibility:

logging:
    level:
        org.jumpmind.idp: DEBUG
        org.springframework.security.oauth2: DEBUG

Offline Development

For testing offline scenarios: 1. Complete initial setup with IDP server running 2. Stop IDP server to simulate offline conditions 3. Verify application continues to function with cached tokens and JWKs 4. Test token refresh behavior when server returns online


Summary

The IDP development setup requires coordination between three main components:

  1. IDP API Server: Provides organizational structure, device management, and OAuth2 token issuance
  2. Commerce Server: Validates JWT tokens and enforces authentication policies
  3. Client Application: Handles device activation and transparent token management