Skip to content

Running the Engine in Development Mode

Warning

This mode is intended for development purposes and/or as a playground and should not be used in production environments.

Background

When the engine application runs in development mode, non-essential components and services—such as the Read Model and the History application—are not served. However, the engine will provide an embedded OpenID Connect (OIDC) server for handling authentication and authorization. This server comes preloaded with a set of test users for development purposes.

An application can be run in development mode by setting the ENGINE_DEV_MODE environment variable in the docker compose file to true. The example below shows the minimal configuration that is required by the engine.

services:
  postgres:
    image: postgres:14.17-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_PASSWORD: postgres

  engine:
    build: .
    ports:
      - "12000:12000"
      - "11000:11000"
    environment:
      ENGINE_DEV_MODE: true
      ENGINE_DB_PASSWORD: postgres

Note

Some services like the Read Model and the History application are considered non-essential as the engine is able to run and support a full application lifecycle independently of those services. Those services can be leveraged for more advanced features like audit trails and complex data read queries.

Embedded OIDC and seeded users

The server is reachable on port 11000 and it can be configured via a YAML file. The default configuration is loaded from classpath:users.yaml and comes with these presets:

oidc:
  token:
    expiration: 3600  # Token expiration in seconds
    refresh_expiration: 86400  # Refresh token expiration in seconds
    signing_key: "default-secret-key"  # Secret key for signing tokens

  users:
    - credentials:
        username: alice
        password: password123
      claims:
        sub: '012345'
        name: Alice
        email: alice@example.com
        preferred_username: alice

    - credentials:
        username: bob
        password: password123
      claims:
        sub: '012346'
        name: Bob
        email: bob@example.com
        preferred_username: bob

    - credentials:
        username: eve
        password: password123
      claims:
        sub: '012347'
        name: Eve
        email: eve@example.org
        preferred_username: eve

    - credentials:
        username: carol
        password: password123
      claims:
        sub: '012348'
        name: Carol
        email: carol@example.com
        preferred_username: carol
        role: payee

    - credentials:
        username: ivan
        password: password123
      claims:
        sub: '012349'
        name: Ivan
        email: ivan@example.com
        preferred_username: ivan
        role: issuer

    - credentials:
        username: dave
        password: password123
      claims:
        sub: '012350'
        name: Dave
        email: dave@example.com
        preferred_username: dave
        company: Noumena Digital
        groups: technology
        address: 1234 Lois Lane

    - credentials:
        username: frank
        password: password123
      claims:
        sub: '012351'
        name: Frank
        email: frank@example.com
        preferred_username: frank
        company: Noumena Digital
        groups: finance

    - credentials:
        username: peggy
        password: password123
      claims:
        sub: '012352'
        name: Peggy
        email: peggy@example.com
        preferred_username: peggy
        company: Noumena Digital
        groups: procurement

    - credentials:
        username: grace
        password: password123
      claims:
        sub: '012353'
        name: Grace
        email: grace@example.com
        preferred_username: grace
        company: Noumena Digital
        groups:
          - technology
          - finance
        preference:
          - mailingList: true
          - sms: false

    - credentials:
        username: heidi
        password: password123
      claims:
        sub: '012354'
        name: Heidi
        email: heidi@example.com
        preferred_username: heidi
        company: Noumena Digital
        groups:
          - entertainment
          - technology

API Endpoints

  • /.well-known/openid-configuration - OpenID Connect discovery endpoint
  • /.well-known/jwks.json - JSON Web Key Set endpoint
  • /token - Token endpoint for obtaining access and refresh tokens
  • /userinfo - User info endpoint for retrieving user claims

Example Requests

Get Token with Password Grant

curl -X POST http://localhost:11000/token \
  -d "grant_type=password" \
  -d "username=alice" \
  -d "password=password123"

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "eyJhbGciOiJIUzI1NiJ9..."
}

Get User Info

curl -X GET http://localhost:11000/userinfo \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
  "sub": "123456",
  "name": "Alice",
  "email": "alice@example.com",
  "preferred_username": "alice"
}

Refresh Token

curl -X POST http://localhost:11000/token \
  -d "grant_type=refresh_token" \
  -d "refresh_token=YOUR_REFRESH_TOKEN"

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "eyJhbGciOiJIUzI1NiJ9..."
}

Nested Claims Support

The embedded OIDC server supports nested claims in JWT tokens.

Example user configuration with nested claims:

    - credentials:
        username: grace
        password: password123
      claims:
        sub: '012353'
        name: Grace
        email: grace@example.com
        preferred_username: grace
        company: Noumena Digital
        groups:
          - technology
          - finance
        preference:
          - mailingList: true
          - sms: false

Example request

Get User Info with Nested Claims

# First get a token for a user with nested claims
curl -X POST http://localhost:11000/token \
  -d "grant_type=password" \
  -d "username=grace" \
  -d "password=password123"

# Then use the token to get user info
curl -X GET http://localhost:8080/userinfo \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response with nested claims:

{
  "sub": "012353",
  "name": "Grace",
  "email": "grace@example.com",
  "preferred_username": "grace",
  "company": "Noumena Digital",
  "groups": [
    "technology",
    "finance"
  ],
  "preferences": {
    "mailingList": true,
    "sms": false
  }
}

Nested object such as preferences and groups will be properly serialized in the JWT token and returned in the user info response.

Running the engine in production

Dev mode is unsuitable for production purposes. When running the engine in production mode, it should be configured according to the Engine configuration reference.

Particular attention should be given to the database and OIDC configurations.

Database

ENGINE_DEV_MODE uses the base image of postgres and its defaults (more information can be found in the official postgres docker documentation).

Environment variable Default in Development Mode Default value
ENGINE_DB_URL jdbc:postgresql://postgres/postgres jdbc:postgresql://localhost:5432/platform
ENGINE_DB_USER postgres platform_owner
ENGINE_ALLOWED_ISSUERS http://localhost:11000 http://localhost:11000/realms/noumena
ENGINE_MANAGEMENT_HOST 0.0.0.0 127.0.0.1

For comprehensive information regarding production configuration options, please consult the database section of the configuration documentation.

OIDC

Configuring a production-ready OIDC provider is a prerequisite for running the Engine, as the embedded provider is only available in development mode. The required environment variables for integrating your authentication service with the Engine are documented in the authentication section of the configuration guide.