Configuration properties
The tSM system is built on top of Spring Boot, which allows it to leverage Spring’s powerful externalized configuration capabilities. In tSM, configuration is primarily managed through the application.yml file, which defines common properties that apply to all microservices. These configurations can be easily customized for different environments such as development, testing, and production.
tSM also supports optional usage of Spring Cloud Config to centralize configuration across multiple microservices. This setup ensures consistency and easier management of shared properties like data sources, messaging services (Kafka), and environment-specific settings.
Please consult Spring Externalized Configuration for more info.
Common Configuration for tSM Microservices
In tSM, every microservice shares some common configuration properties, which can be centrally managed. This is especially useful when using Spring Cloud Config, where you can maintain one application.yml for all services. Here’s an example of a minimal common configuration:
# ----------------------------------------------------------------------------
# Common configuration
# ----------------------------------------------------------------------------
tsm:
prefix: projectX
datasource:
host: my.postgres.database:5401
database: tsm
username: tsm_admin
password: myPass
elastic:
address: tsm-elastic
username: elastic
password: elasticdata
kafka:
address: my.kafka.cluster:9092
autocreate:
enabled: true
partitions: 2
elk:
enabled: true
logstash:
url: tsm-log-server:5044
locale:
locale: cs-CZ
timezone: "Europe/Prague"
Explanation of Common Properties:
- tsm.prefix: A unique identifier for the project, which is used to distinguish between different projects in the same environment. It is used as a prefix for all Kafka topics, elasticsearch indexes, and other project-specific settings.
- tsm.datasource: Defines the database connection details for tSM microservices.
- tsm.elastic: Specifies the ElasticSearch configuration for logging and searching within tSM.
- tsm.kafka: Configures Kafka settings, including the address of the Kafka broker and topic autocreation.
Topic autocreation runs only when
tsm.kafka.autocreate.enabledis explicitly set totrue— the beans that create the topics are conditional on that property being present, so settingpartitionsalone has no effect.partitionsdefaults to10andreplicasto0. - tsm.elk: Controls ELK stack logging, including connection to Logstash.
- tsm.locale: Sets locale and timezone settings for tSM microservices.
These properties are common across all tSM microservices and ensure consistency in the way services connect to databases, messaging queues, and logging systems.
Deployment Options
When deploying tSM microservices, you have multiple options to manage configurations. The most common approach is using Spring Cloud Config for cloud environments, such as Kubernetes (K8s), where configurations are managed centrally and shared across all microservices. For on-premise deployments, configurations are typically managed locally via application.yml files.
Cloud Config Deployment
In cloud-based deployments, such as Kubernetes, Spring Cloud Config can be used to manage configuration files centrally. This enables easy scaling and maintenance of configurations across all microservices.
To use Spring Cloud Config, you need to specify the configuration source using the spring.config.import environment variable. This can be done directly in the Kubernetes deployment spec.
Example: Kubernetes Deployment with Spring Cloud Config
spec:
containers:
- env:
- name: spring.config.import
value: 'configserver:http://tsm-config-server'
image: 'registry.datalite.cz/tsm/tsm-calendar:2.2'
In this example:
- spring.config.import points to the Spring Cloud Config server URL, which provides the configurations for the microservice.
- The tsm-calendar microservice image is pulled from the registry and uses the configurations provided by the config server.
To deploy the Spring Cloud Config server, you need to ensure that it is configured to pull configurations from a Git repository or other storage. Here's an example Kubernetes configuration for deploying the config server:
spec:
containers:
- env:
- name: JAVA_TOOL_OPTIONS
value: '-Xms150m -Xmx150m'
- name: spring.cloud.config.server.git.uri
value: https://gitlab.datalite.cz/tsm/config.git
- name: spring.cloud.config.server.git.username
value: user
- name: spring.cloud.config.server.git.password
value: pass
- name: encrypt.key
value: myPass
image: 'registry.datalite.cz/tsm/tsm-config-server:2.2'
Make sure you have the Spring Cloud Config Server up and running and pointing to the correct repository where your application.yml files are stored.
On-Premise Deployment
For on-premise deployments, configurations are typically managed locally by placing the application.yml file directly in the classpath of the microservice. No external configuration server is required, and each microservice will load its configuration from the local file system.
Built in Configuration Properties
The following properties are common to all profiles, environments, and customizations.
They are included to all microservices and can be overridden by the environment or profile.
The block below mirrors tsm-commons/src/main/resources/application-commons.yml on the tSM 2.4 line,
with internal development notes removed. It is the authoritative list of built-in defaults; when in
doubt, check that file for the exact version you deploy.
# ------------------------------------------------------------
# Base shared settings (apply to every profile and environment)
# ------------------------------------------------------------
tsm:
kafka:
# Global topic prefix injected from an env variable or parent YAML
prefix: ${tsm.prefix} # e.g. “prod”, “test”, “local”
# Dead-letter queue: messages that failed processing are routed here
dlqTopic: ${tsm.kafka.prefix}-tsm-dlq
# Default consumer-group name for all listeners in this service
consumerGroupId: ${tsm.name}
# Interval for retrying the poll after a Kafka auth/SSL failure (e.g. an SSL
# handshake error once a broker is restarted); the listener self-heals as
# soon as the broker is reachable again. null = fail-fast: the consumer
# thread is stopped permanently and only a full service restart brings it
# back. Keep below max.poll.interval.ms.
authExceptionRetryInterval: 30s # default
# List of common topics
topics:
# Cache-invalidation events across micro-services
tsmCacheMaintanance: ${tsm.kafka.prefix}-tsm-cache-maintanance
tsmMaintenanceElasticRefresh: ${tsm.kafka.prefix}-tsm-elastic-refresh
elastic:
index:
# Index name prefix in Elasticsearch
prefix: ${tsm.prefix}
storedScript:
autoUpdate:
# Auto-upload stored scripts to Elasticsearch on startup
enabled: true
scripts:
events:
enabled: true # Enable event scripts (https://tsm.datalite.cz/docs/configuration/tsm-languages/SpEL/spel-bindings)
entity:
default:
api:
validation:
chars:
# full | none | defaults-only | elasticsearch-only
mode: defaults-only
allow-non-defined-properties: true
Address:
api:
validation:
chars:
mode: none
CrmAddress:
api:
validation:
chars:
mode: none
Quote:
api:
validation:
chars:
mode: none
CampaignWaveDefinition:
api:
validation:
chars:
mode: none
redis:
cache:
enabled: false
filtering:
compatibilityMode: true
# false (default) = a filter that cannot be compiled (e.g. malformed UUID value) fails the
# request with HTTP 400. true = historical behaviour: such a filter is logged
# and ignored when other filters compiled, silently widening the result set.
bestEffort: false
security:
jwt:
# One deployment-wide authorization-server identifier. Production startup
# rejects the legacy fallback; set the same HTTPS root URL in every service.
issuer: ${TSM_JWT_ISSUER:tSM}
# The default logical service name is resolved through service discovery.
# An explicit HTTPS root or fully qualified cluster-local HTTP address is
# fetched directly.
jwks-base-url: ${TSM_JWT_JWKS_BASE_URL:http://tsm-user-management}
# ------------------------------------------------------------
# Embedded server (Spring Boot)
# ------------------------------------------------------------
server:
port: ${tsm.port} # Listening port
max-http-request-header-size: 64KB # Max size of HTTP request headers
# ------------------------------------------------------------
# Spring Boot – global configuration
# ------------------------------------------------------------
spring:
application:
name: ${tsm.name} # Service name (logs, Actuator /info, etc.)
threads:
virtual:
enabled: true # Run application tasks on lightweight virtual threads (Java 21, JEP 444)
# ---------- Kafka ----------
kafka:
bootstrap-servers: ${tsm.kafka.address} # Comma-separated broker list
consumer:
group-id: ${tsm.kafka.consumerGroupId} # Default group-id
auto-offset-reset: earliest # No offset? Start from beginning
# ErrorHandlingDeserializer catches (de)serialization errors
key-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
value-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
properties:
spring.deserializer.key.delegate.class: org.apache.kafka.common.serialization.StringDeserializer
spring.deserializer.value.delegate.class: org.apache.kafka.common.serialization.StringDeserializer
max.poll.interval.ms: 3600000 # Long-running message processing
max.poll.records: 200 # Messages fetched per poll
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
properties:
batch.size: 262144 # 256 KB
linger.ms: 5 # wait up to 5 ms to fill the batch
compression.type: snappy
# ---------- REST ----------
http:
client:
read-timeout: 5m
# ---------- Data source ----------
datasource:
# JDBC URL built from env variables (host, database, schema, extra params)
url: jdbc:postgresql://${tsm.datasource.host}/${tsm.datasource.database:tsm}?currentSchema=${tsm.datasource.schema}${tsm.datasource.params:}
username: ${tsm.datasource.username}
password: ${tsm.datasource.password}
hikari:
maximum-pool-size: 30 # Max connections in the pool
minimum-idle: 2 # Minimum idle connections
data-source-properties.reWriteBatchedInserts: true # Help in multiple commands
leak-detection-threshold: 60000 # Log "leaked" connections after 60 s (not returning within this timeout)
max-lifetime: 1800000 # But allow even longer queries
# ---------- JPA / Hibernate ----------
jpa:
properties:
hibernate:
# JSON (B) mapper for Kotlin + Jackson → PostgreSQL jsonb type
type.json_format_mapper: cz.datalite.tsm.db.KotlinJacksonFormatMapper
jdbc:
lob.non_contextual_creation: true # Fix for large-object creation
batch_versioned_data: true # batch even @Versioned entities
batch_size: 1000 # batch for high performance
default_batch_fetch_size: 1000 # batch for high performance
order_inserts: true # group inserts
order_updates: true # group updates
hibernate:
ddl-auto: none # Flyway manages the schema
open-in-view: true # Keep session open for lazy-load
# ---------- Jackson ----------
jackson:
mapper:
DEFAULT_VIEW_INCLUSION: true # Fields without @JsonView are always included
deserialization:
FAIL_ON_NULL_FOR_PRIMITIVES: false # Allow null values for primitive types
# ---------- FreeMarker ----------
freemarker:
template-loader-path: classpath:/templates
suffix: .ftl
# ---------- Flyway ----------
flyway:
default-schema: ${tsm.datasource.schema}
schemas: ${tsm.datasource.schema}
locations: classpath:db/release-*/**/{vendor} # Multiple version folders
group: true # Group migrations with the same version
placeholder-prefix: $$FLYWAY$${ # Placeholder syntax in SQL scripts
validate-migration-naming: true
baseline-on-migrate: true
baseline-version: 24.01.0.000 # New baseline
baseline-description: TSM Baseline 2.4
ignore-migration-patterns: "*:missing"
out-of-order: true # Allow hot-fix versions out of sequence
# ---------- Redis / Redisson ----------
redis:
redisson:
file: classpath:redisson.yaml # Deployment-provided Redisson config
# ---------- Auto-configuration exclusions ----------
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration
- org.springframework.boot.autoconfigure.elasticsearch.ReactiveElasticsearchClientAutoConfiguration
- org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration
# Boot's Kafka metrics listeners run on a platform-thread scheduler; tSM registers
# equivalent listeners on a virtual-thread scheduler instead
- org.springframework.boot.actuate.autoconfigure.metrics.KafkaMetricsAutoConfiguration
- org.springframework.boot.security.autoconfigure.UserDetailsServiceAutoConfiguration # Boot 4.x
# ---------- Spring Cloud ----------
cloud:
openfeign:
httpclient.enabled: true # Use Apache HttpClient (supports PATCH)
lazy-attributes-resolution: true # Delay Feign bean initialization
cache.enabled: false # Work-around for occasional startup loop
client:
config: # Global timeouts for all Feign clients
default:
exception-propagation-policy: UNWRAP
logger-level: FULL
connectTimeout: 30000 # 30 s
readTimeout: 300000 # 5 m
tsm-user-management-jwks:
follow-redirects: false # Never downgrade the trusted HTTPS JWKS endpoint
discovery:
reactive.enabled: false # Force blocking discovery client
# ------------------------------------------------------------
# Feign (outside Spring Cloud) – enable Apache HttpClient
# ------------------------------------------------------------
feign:
httpclient.enabled: true
# ------------------------------------------------------------
# JaVers – auditing library
# ------------------------------------------------------------
javers:
auditable-aspect-enabled: false
packages-to-scan: cz.datalite.tsm
sqlSchemaManagementEnabled: false
# ------------------------------------------------------------
# Camunda (workflow engine) – defaults
# ------------------------------------------------------------
camunda:
bpm:
database:
schema-update: false # Enable only if admin grants are in place
auto-deployment-enabled: false # Process definitions are deployed via process designer
application:
scan-for-process-definitions: false
defaultNumberOfRetries: 1 # Avoid automatic retries for REST calls
defaultSerializationFormat: application/json
tenant-id-provider: cz.datalite.tsm.process.camunda.TsmCamundaTenantIdProvider
generic-properties:
properties:
historyTimeToLive: P365D # Keep process history for one year
loggingContextActivityId: tsm.camunda.activityId
loggingContextBusinessKey: tsm.camunda.businessKey
loggingContextProcessDefinitionId: tsm.camunda.processDefinitionId
loggingContextProcessInstanceId: tsm.camunda.processInstanceId
loggingContextApplicationName:
loggingContextTenantId:
job-execution: # Camunda jobs (async, timer etc.). Time is set in milliseconds
max-pool-size: 10 # Maximum number of parallel threads to execute jobs (Java virtual threads)
lock-time-in-millis: 900000 # Time for which jobs are locked, default is 15 minutes to allow long-running jobs to finish
max-jobs-per-acquisition: 20 # The batch size of the acquisition query: how many jobs the acquisition thread locks in one hit
wait-time-in-millis: 1000 # Base sleep time after an acquisition cycle that found fewer jobs than requested.
max-wait: 10000 # Upper ceiling for the exponential back-off sleep
cache:
process-definition:
enabled: false # Enable caching of process definitions
timeout: 100 # Number of milliseconds to cache process definitions.
# The cache is not synchronized in a cluster, after quick repeated deployment it can create
# duplicates. Set a very short time to avid user duplicate deploy on different instances.
# Enable only on environments with thousands of processes per second.
# ------------------------------------------------------------
# Spring Boot Actuator – endpoints and health checks
# ------------------------------------------------------------
management:
tracing:
baggage:
# remote-fields: baggage sent to downstream services alongside the trace context.
# Covers HTTP clients instrumented by Brave (Feign included). Kafka is NOT covered, so
# neither the trace context nor the baggage crosses a topic.
# The wire key is always lower-cased, so the letter case declared here never reaches the
# network. x-traceid is inert: nothing writes that field, so it propagates nothing. The
# trace id itself travels in the standard traceparent header, and X-Trace-Id is added as a
# response-only header. The entry is kept so an incoming x-traceid is still forwarded.
# correlation.fields: MUST stay empty. Naming an MDC key here hands ownership of that key to
# the tracing decorator, which then overwrites it with the baggage value and removes it
# when the baggage is empty. On paths that carry no baggage (Kafka consumers, the frontend
# logger websocket) the value tSM logs would disappear for the duration of any span.
# Every correlation value tSM logs is written to MDC by the application itself, and
# traceId/spanId are added by the tracing bridge.
# Consequence of the empty list: log lines with no application MDC write - the /actuator,
# /health and /static paths - carry traceId but no correlation id.
remote-fields: x-traceid,x-correlation-id,x-debug-level
correlation:
fields: ""
sampling:
probability: 1.0
endpoint:
health:
show-details: always # Show full health details to everyone
probes.enabled: true # Enable liveness / readiness view
endpoints:
web:
exposure.include: flyway,loggers,logfile,env,info,health,configprops,metrics,scheduledtasks,threaddump,heapdump,prometheus
health:
camunda.enabled: false # Enable after upgrading to Camunda 7.20.1
redis.enabled: false # Turn on only if Redis is actually used
# ------------------------------------------------------------
# Custom bean toggles
# ------------------------------------------------------------
bean:
RequestLoggerConfiguration.enabled: true # Log every inbound/outbound HTTP request
Entity chars validation
Controls how tSM validates and applies defaults to chars payloads written through the Public API. Defined in application-commons.yml and shared by all microservices that handle entity APIs.
The shipped values are in the built-in configuration block
above: tsm.entity.default.api.validation.chars.mode is defaults-only with
allow-non-defined-properties: true, and the entity types Address, CrmAddress, Quote and
CampaignWaveDefinition ship with mode: none, i.e. schema processing turned off.
Override the mode per entity type with tsm.entity.<EntityType>.api.validation.chars.mode, replacing
<EntityType> with the actual type (Ticket, Order, …). The shorthand
tsm.entity.<EntityType>.api.validation.chars: <mode> — the mode set directly on the chars key, without the
.mode suffix — is accepted as well and takes precedence over the longer form.
| Mode | Validation | Defaults | Notes |
|---|---|---|---|
full | Yes | Yes | Full schema validation and default application. Code fallback when no property is set (below). |
defaults-only | No | Yes | Defaults are applied, the payload is not validated at all. Shipped platform default. |
none | No | No | Schema-driven processing is skipped entirely; the payload is stored as received. |
elasticsearch-only | No | Flat only | Applies legacy flat defaults only, preserving historical Elasticsearch behaviour. |
full is only the fallback used when no tsm.entity.* property resolves. Because
application-commons.yml sets tsm.entity.default.api.validation.chars.mode: defaults-only, a stock tSM
deployment runs in defaults-only — set the property back to full explicitly if you want payloads rejected
on schema violations.
defaults-only does not validate and does not log validation problems: it fills in schema defaults and returns
the payload. Only full reports schema violations, and it does so by rejecting the request.
See Characteristics — Runtime validation and defaults for the full description.
tsm-user-management
tsm:
# HTTP port on which the TSM User-Management service listens
port: 8088
# Application name (used in logs, tracing, etc.)
name: tsm-user-management
datasource:
# Database schema that holds TSM tables
schema: um # “um” = user-management schema
user:
access:
# Password-reset/email-confirmation links. Production startup rejects this
# development default and values below 32 UTF-8 bytes; inject a random secret.
secret: ${TSM_USER_ACCESS_SECRET:JwtUserNotificationSecretKey}
expiration: 900
url: /account/link-action/token/
restore-password-action: user-restore-password
confirm-email-action: user-confirm-email
kafka:
# Kafka consumer group for all listeners in this service
consumerGroupId: tsm-user-management
topics:
# Topic with user-related events (create / update / delete)
tsmUser: ${tsm.kafka.prefix}-tsm-user
# Topic with WorkForce Management work-resource updates
tsmWfmWorkresource: ${tsm.kafka.prefix}-wfm-workresource
# Topic with calendar events (holidays, shifts, etc.)
tsmCalendar: ${tsm.kafka.prefix}-tsm-calendar
planner:
# When true, send updates about work-resources to the external planner
update-workresource: true
security:
# Password/ROPC grant. Disable in deployments where interactive login is delegated entirely to an IdP.
ropc:
enabled: true
token:
# When true, a token minted from a source token (RFC 8693 token exchange, access-token
# translation) is capped at the source's remaining lifetime and cannot outlive it.
# The flag governs only the cap; an already-expired source token is rejected regardless.
# On by default in every environment. Relax (false) only where legacy code prolongs
# tokens via tsmSecurity.securitySetImpersonateUser for long operations, and only in the
# per-environment configuration.
enforce-source-expiration: true
# Optional per-client access-token lifetime override, in seconds. A client without an
# entry keeps its built-in default.
# Keys use the client enum name in relaxed form (basic-auth == BASIC_AUTH). Example:
# lifetime-seconds:
# basic-auth: 900 # longer interactive integration/debug session
# api-key: 7200 # 2 h for a batch integration that renews infrequently
# Recommended: keep the shortest lifetime the integration tolerates. These clients
# have no refresh token, so a longer TTL widens the revocation window - a revoked
# identity's token stays valid up to its TTL (bounded early only when
# security.jwt.denylist.enabled=true). Avoid raising past ~1 h without a reason.
api-key:
enabled: true
max-per-user: 10
# Optional maximum lifetime of a newly generated key, for example 365d. Empty means no additional cap.
max-validity:
# Retention window for revoked and expired keys.
purge-after: 365d
# Direct X-API-Key authentication belongs only on services intentionally exposed without the gateway.
direct-header-enabled: false
direct-cache-ttl: 60s
jwt:
signing:
# Production requires either an inline PKCS#8 ES256 key or an explicitly configured durable/shared path.
# The user.home default below is accepted only in devel, test, docker-it, or no-security mode. It
# resolves to /app/.tsm in the container image, which the image keeps writable for the runtime user;
# the key lives and dies with the container, and an unusable directory leaves it in memory only.
private-key:
# Optional matching public key. It is derived from the private key when empty.
public-key:
private-key-path: ${user.home}/.tsm/jwt-signing-private-key.pem
# Previous public keys retained during signing-key rotation until their tokens expire.
retained-public-keys: []
refresh-grace-period: 30s
# Optional absolute lifetime of a refresh-token family. Empty keeps sliding expiration only.
refresh-max-lifetime:
denylist:
enabled: false
# Local positive cache only; the database remains the cross-replica source of truth.
maximum-cache-size: 100000
cache-ttl: 5s
refresh-token:
cookie:
enabled: true
name: TSM_REFRESH
same-site: Strict
token-endpoint:
rate-limit:
enabled: true
max-failures: 10
window: 60s
# Exact socket-peer addresses allowed to supply X-Forwarded-For.
# Production startup fails when this list is empty, preventing one shared
# gateway address from becoming a global client-IP rate-limit bucket.
trusted-proxies: ${TSM_TOKEN_ENDPOINT_TRUSTED_PROXIES:}
require-trusted-proxies: ${TSM_TOKEN_ENDPOINT_REQUIRE_TRUSTED_PROXIES:true}
ical-subscription:
# Purpose-bound calendar links expire and must be regenerated; permanent
# general-purpose JWTs are intentionally unsupported.
expiration: 90d
# Fails startup outside devel, test, docker-it, and no-security runtimes when default credentials remain active.
credential-guard:
enabled: true
internal-call:
# Audit successful calls where the user lacked every required privilege and validated service proof was decisive.
log-user-privilege-fallback: false
systemUser:
# Single-tenant compatibility key supplied by deployment secret management.
# It is used only while api-keys is empty; never commit its value.
api-key:
# Database-scoped credentials keyed by the master segment of {master}.{data} tenant IDs.
# An unmapped master uses the configured password fallback, never api-key.
api-keys: {}
ad-config:
# Toggle LDAP authentication against Active Directory
ldap-auth-enabled: false # true → users are authenticated via AD
# Toggle scheduled sync of users / groups from AD to local DB
ldap-sync-enabled: false # true → periodic sync runs
# LDAP endpoint (protocol + host + port)
url: ldap://todo.todo:389 # e.g. ldap://ad.company.com:389
# Kerberos / AD DNS domain; leave blank to infer from base-dn
domain: # e.g. company.com
# Root DN under which all user / group objects reside
base-dn: OU=TODO,DC=in,DC=customer,DC=domain
# Optional narrower subtree to search (overrides base-dn if set)
search-base:
# Service account (bind DN or UPN) used to query the directory
mng-user: Service-account@customer.com
# Password for the service account — keep this secure!
mng-password:
radius: # Auth via RADIUS server; roles sync on login
radius-auth-enabled: false # true → enable RADIUS authentication
# One or more RADIUS servers separated by “|”
server: 127.0.0.1 # Ensure ports 1812 (auth) & 1813 (acct) are open
# Shared secret that must match the RADIUS server configuration
sharedSecret: testing123
database:
# Allow classic username/password auth against internal DB
password-auth-enabled: true # Set false to disable local fallback
password-policy:
# Minimum and maximum password length
min-length: 8
max-length: 64
# List of disallowed weak passwords (lowercased for matching)
weak-passwords:
- "1234"
- "12345"
- "123456"
- "password"
- "qwerty"
- "admin"
- "111111"
# Password composition requirements (set to false to disable specific checks)
require-uppercase: true # true → at least one uppercase letter required
require-lowercase: true # true → at least one lowercase letter required
require-digit: true # true → at least one digit required
require-special-char: true # true → at least one special character required
disallow-whitespace: true # true → whitespace is not allowed in passwords
external:
oidc:
enabled: false
# Bounds acceptance of removed or compromised issuer keys while avoiding a JWKS request per login.
jwks-cache-ttl: 5m
# Bounds discovery/JWKS refreshes caused by attacker-controlled unknown key ids.
unknown-kid-refresh-cooldown: 30s
# Single-provider mode. issuer-uri and client-id are required when enabled;
# issuer/discovered JWKS endpoints must use HTTPS outside explicit non-production runtimes.
issuer-uri:
# Additional exact iss claim values trusted with keys discovered from issuer-uri.
# Aliases are identifiers only; they are never used as discovery or JWKS endpoints.
issuer-aliases: []
client-id:
user-claim: preferred_username
# Local user field matched against the value extracted from user-claim: code or email.
user-mapping-field: code
create-refresh-token: true
provisioning:
enabled: false
default-roles: []
roles-claim:
roles-mode: additive
user-type: INDIVIDUAL
# Configure this list instead of the single-provider fields for multiple identity providers.
providers: []
management:
health:
ldap:
# Include LDAP in Actuator /health only if LDAP is used and should affect status
enabled: false # true → app hits LDAP to report health
# common config
spring:
jmx:
enabled: false
banner:
location: classpath:tsm-banner.txt
application:
name: ${tsm.name}
javers:
sqlSchema: um
# Remove too verbose logging.
# These levels have to be set per service: the shared configuration is loaded too late
# during startup to affect them.
logging:
level:
org.apache.kafka: WARN
org.springframework.cloud.openfeign.FeignClientFactoryBean: WARN
org.flywaydb.core.internal.license.VersionPrinter: WARN
com.zaxxer.hikari.HikariDataSource: WARN
org.springframework.aop.framework.CglibAopProxy: ERROR
org.hibernate.orm.deprecation: ERROR