Configuration
Profiles
Profiles are defined via Spring application-*.yml:
-
local: local developer settings (src/main/resources/application-local.yml) -
mysql: MySQL settings with env overrides (src/main/resources/application-mysql.yml) -
oracle: Oracle settings with env overrides (src/main/resources/application-oracle.yml)
Select the active profile with SPRING_PROFILES_ACTIVE (for example local, mysql, oracle).
Core HTTP settings
-
Context path:
server.servlet.context-path=/configs-service(src/main/resources/application.yml) -
Swagger UI:
springdoc.swagger-ui.doc-expansion=none
Hazelcast client settings
The Hazelcast client is configured by ft-cache:
-
cache-config.path– defaults toclasspath:; the effective resource is${cache-config.path}hazelcast-client.yaml.-
In container environments,
CACHE_CONFIG_PATHis the typical env var name used to provide this value (Spring relaxed binding maps it tocache-config.path).
-
-
HZ_MEMBERS– overrides members list (comma/space separated).-
If a member entry does not contain a port,
:5701is appended by theft-cacheresolver.
-
-
cache.is-server– whentrue, starts an embedded Hazelcast member from${cache-config.path}hazelcast.yaml(not used for this service in production).-
In container environments,
CACHE_IS_SERVERis the typical env var name.
-
Production note: cluster-name is configured as dev.
Database settings
Database configuration is profile-specific:
-
mysqlprofile reads DB settings fromapplication-mysql.yml(env overrides supported). -
oracleprofile reads DB settings fromapplication-oracle.yml(env overrides supported).
See Environment variables for the full env var matrix with verified defaults and examples.
JWT and cookies
JWT and cookie settings come from the active profile YAML and can be overridden via environment variables.
See Environment variables for JWT_* and COOKIE_* inputs, defaults, and usage notes.
Spring Mail is configured in profile YAMLs (host, port, username/password, TLS flags) and used for:
-
user onboarding emails (
mail/registration.html) -
user deletion flows (
auth/deletion/*)
Delivery modes (online / offline)
Email delivery is controlled by MAIL_MODE (property mail.mode), evaluated in MailDeliveryStatus from mail.mode plus Spring MailProperties.
Values are case-insensitive; a blank or unknown value falls back to AUTO with a warning log.
The supported values are AUTO and OFFLINE.
-
AUTO(default) — infers the mode from SMTP config: treated as OFFLINE whenMAIL_HOST,MAIL_USERNAME, orMAIL_PASSWORDare not all set (non-blank); when they are all set it attempts email, but degrades to offline behaviour at runtime if the SMTP server is unreachable (see Runtime fallback below). -
OFFLINE— never send email.
At startup the service logs the resolved mode, for example:
Mail delivery: mode=AUTO, smtpConfigured=false, effectiveOffline=true
Offline behavior
When offline (chosen explicitly via OFFLINE, inferred by AUTO, or reached at runtime when a configured SMTP server is unreachable):
-
Create user (
POST /api/admin/users) and reset password (POST /api/admin/users/{id}/reset-password): the temporary password is not emailed. It is returned in the API response (passwordDelivery=RETURNED) so an admin can deliver it out-of-band. -
User deletion request (
POST /api/admin/users/{id}/deletion/request): OTP email confirmation is disabled. No OTP/token is issued and the response carriesotpRequired=false, signalling the UI to show a plain confirmation. The account is still deleted in the/deletion/confirmstep, called without a token/OTP (allowed only while OTP delivery is unavailable — configured offline or SMTP unreachable).
Online behavior
When online (AUTO with SMTP configured and reachable):
-
Temporary passwords are emailed; create/reset responses carry
passwordDelivery=EMAILandtemporaryPassword=null. -
Deletion issues an OTP intent and emails the OTP to the initiating admin’s address, returning
otpRequired=truewith token/expiry/otpLength/attemptLimit; the admin then calls/deletion/confirmwith the OTP.
Because the OTP is sent to the initiating admin, that admin must have an email in online mode. Otherwise the deletion request fails with error code USER_DELETION_EMAIL_REQUIRED ("User email is required to request account deletion"). This email check applies only in online mode.
|
Runtime fallback on send failure
Under AUTO with SMTP configured, if the server is unreachable or a send throws, delivery degrades to the offline behaviour instead of erroring:
-
Create/reset password delivery degrades to
passwordDelivery=RETURNED. -
User deletion degrades to the no-OTP path: the request returns
otpRequired=falseand the account is deleted in the tokenless confirm step. The deletion confirm probes SMTP reachability (MailDeliveryStatus.isOtpConfirmationAvailable()) so it accepts a tokenless confirm when the server is down, since it has no OTP to send.
To keep this prompt, the JavaMail connect/read/write timeouts are fixed at 5000 ms (previously infinite, which could hang the request thread).
They are configurable via spring.mail.properties.mail.smtp.connectiontimeout, .timeout, and .writetimeout.
See Security — User secret delivery for the rationale behind returning secrets in API responses.
mailAvailable on the environment snapshot
GET /configs-service/environment/snapshot is public (unauthenticated) and returns:
| Field | Type | Description |
|---|---|---|
|
string |
Application version string. |
|
string |
Build identifier from |
|
boolean |
|
mailAvailable is !MailDeliveryStatus.isOffline() — the same config-derived check described above
(mail.mode=OFFLINE, or AUTO with MAIL_HOST/MAIL_USERNAME/MAIL_PASSWORD not all set). It has
no live SMTP probe, so it reflects whether mail is set up, not whether the SMTP server is currently
reachable (compare MailDeliveryStatus.isOtpConfirmationAvailable(), used only by the deletion-confirm
runtime path, described under Runtime fallback on send failure above).
Email template system
Email templates use table-based HTML for maximum email client compatibility:
-
Mobile-responsive — fluid width adapts to device screens
-
Dark-mode — includes
color-scheme: light darkmeta for clients that support it -
MSO conditional comments — Microsoft Outlook rendering fixes
-
Multipart/alternative — every email includes a plain-text alternative for better deliverability and accessibility
Internationalization (i18n)
Email subjects, body text, and the brand name are localized via Spring MessageSource:
-
mail_messages.properties(English, default) -
mail_messages_ru.properties(Russian)
The user’s locale is resolved from user.locale.
If unset, English is used as fallback.
The brand name is controlled by the mail.brand message key:
-
English: "Configuration Center"
-
Russian: "Центр Конфигураций"
The MAIL_FROM_NAME environment variable has been removed.
The sender display name now comes from the mail.brand message key.
|
Call-to-action button
The "Sign In" CTA button in emails is optional and controlled by MAIL_LOGIN_URL:
-
When set to a valid
http://orhttps://URL, a styled button links to that URL. -
When blank or non-HTTP, the button is replaced by a generic text hint ("Please sign in via your organization’s portal").
Security
-
All user inputs and
MessageSourcevalues are HTML-escaped before insertion into templates. -
MAIL_LOGIN_URLis validated at startup; non-HTTP/HTTPS values are ignored with a warning log.
See Environment variables for MAIL_* inputs and profile-specific defaults.
Audit retention
Audit events are automatically cleaned up by AuditRetentionService, which runs daily at 03:00.
-
Default retention: 30 days
-
Configurable via
AUDIT_RETENTION_DAYS(min 3, max 90, or 0 to disable)
See Auditing — Audit retention for full details.
See Environment variables for AUDIT_RETENTION_DAYS and AUDIT_REDACTION_FIELDS.
Actuator exposure (security note)
src/main/resources/application.yml exposes health, info, metrics, and prometheus actuator endpoints (management.endpoints.web.exposure.include=health,info,metrics,prometheus) and permits them without auth (SecurityConfig).
In production, restrict actuator exposure further if needed via:
-
network policy / ingress rules, and/or
-
tightening
management.endpoints.web.exposure.includeand security rules.
Bootstrap admin provisioning
Configured via:
-
ft-configs.bootstrap.admin.username -
ft-configs.bootstrap.admin.password -
ft-configs.bootstrap.admin.email(optional) -
ft-configs.bootstrap.admin.locale(optional)
See Environment variables for FT_CONFIGS_BOOTSTRAP_ADMIN_* defaults and examples.
Environment variables
|
Do not commit secrets ( |
|
|
A) Quick start (most common knobs)
| Variable | Required | Default | Description |
|---|---|---|---|
|
Yes |
|
Active Spring profile: |
|
No |
|
Primary server port. When |
|
No |
|
Plain HTTP port. In dual-mode (HTTP + HTTPS), set this to a different value than |
|
No |
from Hazelcast client config |
Comma-separated Hazelcast members ( |
|
No |
Comma-separated list of allowed CORS origins. Must match the URL the user sees in the browser address bar (where the frontend is loaded from), never the internal Docker service name. Scheme-sensitive: |
|
|
No |
|
Log level for the application package. Values: |
B) Database (MySQL profile: SPRING_PROFILES_ACTIVE=mysql)
Provide either MYSQL_JDBC_URL or the decomposed MYSQL_HOST/MYSQL_PORT/MYSQL_SCHEMA inputs.
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
derived if unset |
Full MySQL JDBC URL. Recommended for Docker/Kubernetes to avoid host, port, and schema drift. |
|
No |
|
Shared DB host fallback used by MySQL and Oracle when profile-specific host is not set. |
|
No |
|
MySQL host used if |
|
No |
|
MySQL port used if |
|
No |
|
MySQL schema used if |
|
No |
|
MySQL username for the service. The env templates in |
|
No |
|
MySQL password for the service. The env templates in |
|
No |
|
Override JDBC driver class if needed. |
|
No |
|
HikariCP max pool size. |
|
No |
|
HikariCP minimum idle connections. |
|
No |
|
HikariCP connection timeout in milliseconds. |
When both *_JDBC_URL and decomposed variables are set, the explicit JDBC URL always takes precedence.
|
C) Database (Oracle profile: SPRING_PROFILES_ACTIVE=oracle)
Provide either ORACLE_JDBC_URL or the decomposed ORACLE_HOST/ORACLE_PORT/ORACLE_SERVICE (plus optional ORACLE_SCHEMA) inputs.
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
derived if unset |
Full Oracle JDBC URL. Recommended for Docker/Kubernetes to avoid host, port, and service drift. |
|
No |
|
Oracle host used if |
|
No |
|
Oracle port used if |
|
No |
|
Oracle service name used if |
|
No |
empty |
Optional schema mapped to |
|
No |
|
Oracle username for the service. |
|
No |
|
Oracle password for the service. Treat as a secret. |
|
No |
|
Override Oracle JDBC driver class if needed. |
D) Hazelcast / cache
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Base path for Hazelcast config files. |
|
No |
|
When true, starts an embedded Hazelcast member from |
|
No |
|
Name of the Hazelcast cache from which ACS publishes product-class groups, consumed by the |
E) Auth / JWT & cookies
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
defined in profile |
Base64-encoded HMAC-SHA256 signing key. Must decode to at least 32 bytes (256-bit) or startup fails. Generate with |
|
No |
|
Access token expiration in milliseconds. |
|
No |
|
Refresh token expiration in milliseconds. |
|
No |
|
Set |
|
No |
empty |
Optional domain for cross-subdomain cookie sharing. |
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Email delivery mode (case-insensitive; blank or unknown falls back to |
|
No |
|
SMTP host used for registration and deletion flows. Under |
|
No |
|
SMTP port. |
|
No |
SMTP username. Under |
|
|
No |
SMTP password. Treat as a secret. Under |
|
|
No |
|
Usually |
|
No |
|
SMTP authentication toggle. |
|
No |
|
STARTTLS toggle. |
|
No |
|
From address used in sent emails. |
|
No |
empty |
URL for the "Sign In" call-to-action button in emails. Must start with |
The MAIL_FROM_NAME variable has been removed.
The sender display name is now localized via the mail.brand message key (mail_messages*.properties), returning "Configuration Center" (EN) or the localized equivalent for other locales.
|
Audit
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Number of days to retain audit events. Minimum 3, maximum 90. Set to |
|
No |
empty |
Comma-separated list of additional sensitive field names to redact in audit snapshots and change records. Added on top of the 18 built-in defaults (password, token, secret, apiKey, etc.). |
Bootstrap admin (first install)
| Variable | Required | Default | Description |
|---|---|---|---|
|
No |
|
Username for first startup when no admin exists. |
|
Yes (first startup) |
empty |
Password for bootstrap admin. Must be set on first startup or the admin account will not be created. Rotate immediately after bootstrap via |
|
No |
empty |
Optional email assigned to bootstrap admin. |
|
No |
empty |
Optional locale for bootstrap admin. |