Skip to content

Configuration

The FlowDesk API follows the .NET configuration conventions: every Section:SubKey setting you write in values.yaml reaches the container as an environment variable with double underscores instead of the colon, so Database:Provider appears inside the container as Database__Provider. The chart does that conversion for you; you only edit values.yaml.

database:
provider: PostgreSql # or SqlServer

The same image runs on either engine; which one you get is decided by this single field in values.yaml. A CONNECTION_STRING (in the secret) that is set wrongly, or does not match the engine you chose, leaves the API unable to connect at startup and the pod restarting continuously. Connection string formats:

  • PostgreSQL (Npgsql format, Search Path=dbo is required): Host=postgres;Port=5432;Database=flowdesk;Username=flowdesk;Password=<password>;Search Path=dbo
  • SQL Server: Server=<host>,1433;Database=flowdesk;User Id=sa;Password=<password>;TrustServerCertificate=True;Encrypt=True

Changing engine later means migrating data. Make this decision before installing.

The API supports three login providers, and more than one can be enabled at the same time:

Provider What it needs
EmailPassword No external dependency: users live in the FlowDesk database and their passwords are stored with PBKDF2. No extra configuration.
Ldap Your organisation’s LDAP/AD server.
Keycloak Your organisation’s Keycloak server (OIDC); a user is authenticated by matching the e-mail in Keycloak exactly against the local FlowDesk user’s e-mail.

Chart note. The current values.yaml of the shftco/flowdesk-kubernetes chart binds only one provider (auth.provider, default Keycloak) to Auth:Providers:0, and renders only the Keycloak-specific settings (authority, clientId, redirectUris). There is no separate values.yaml field for LDAP. You can switch to password-based login by setting auth.provider: EmailPassword (it has no external dependency); enabling LDAP, or several providers at once, is not possible with the chart as it stands today. Talk to SHFT.

If you use Keycloak:

auth:
provider: Keycloak
authority: 'https://<your-keycloak-server>/realms/<realm>'
clientId: flowdesk-web
redirectUris:
- 'https://<your-dashboard-address>/api/auth/callback/keycloak'
requireHttps: true
# KEYCLOAK_CLIENT_SECRET lives in the secret, NOT in values.yaml.

In the Keycloak realm: a confidential client (Client authentication: ON), Standard Flow enabled, PKCE S256, and a redirect URI exactly matching redirectUris (a mismatch gives a redirect_uri error at sign-in). Every user must be defined with Email verified: ON and a password with Temporary: OFF, and must also exist as a FlowDesk user with the same e-mail. If either is missing, that user cannot sign in.

messaging:
provider: RabbitMq # or Kafka

The application always publishes background work through the transactional outbox; this setting only decides which broker the published message reaches, and does not affect application code. With RabbitMq selected, if the broker is unreachable the API drops to “Degraded” but keeps answering HTTP traffic. Background work (notifications, automation) piles up.

If you chose Kafka, extra settings are needed:

messaging:
provider: Kafka
kafka:
bootstrapServers: 'broker1:9092,broker2:9092'
consumerGroup: flowdesk
topicPrefix: flowdesk
securityProtocol: SaslSsl # Plaintext | Ssl | SaslPlaintext | SaslSsl
saslMechanism: ScramSha512 # Plain | ScramSha256 | ScramSha512
saslUsername: flowdesk
# KAFKA_SASL_PASSWORD lives in the secret.

With Application:Environment=Production, a non-local Kafka broker cannot run over an unencrypted (Plaintext) protocol. The API refuses to start.

Licensing is online: one key, one endpoint. There is no manually installed file that requires persistent disk at install time.

# values.yaml; the key itself lives in the secret (License__Key), not here
licensing:
stateDirectory: /var/lib/flowdesk # must be persistent, see below
serverUrl: 'https://license-api.flowdesk.com.tr' # SHFT's server, the default is fine
responseSigningKeys:
{ } # keyId -> public key (PEM), supplied by SHFT, see below

The flow: at startup and every 12 hours thereafter the API sends License:Key to the licence server; the server returns a response signed with ECDSA P-256, the API verifies that signature with the public key under License:ResponseSigningKeys, applies it, and caches it under License:StateDirectory. Verification checks the signature, the keyId, a nonce that prevents replay, and that the response belongs to this installation (installationId). That closes four separate forgery paths. Request content, customer data and user information never appear in the request body.

Both License:Key and License:ResponseSigningKeys:<keyId> are issued by SHFT and delivered to your organisation. The key establishes your organisation’s identity and the signing key proves the response really came from SHFT; they work together, and if either is missing the licence is not considered verified.

No licence state ever blocks startup. Even an installation that cannot reach the licence server at all, or that has no key entered, still starts; the problem is fixed on a running system. There are four states:

State Meaning
Pending No key entered, or no response received yet. The application is fully functional.
Valid The server was reached successfully and the installation is authorised.
Grace The server is unreachable; the API keeps running on the last signed response from cache, and the dashboard shows how many days are left.
Blocked Rejected, or the cache expired. Business endpoints return FD:0011; the licence screen, sign-in and /health stay open. You can still fix the problem in this state.

License:StateDirectory must sit on a persistent volume. If it is not persistent, every restart looks like a brand new installation to the licence server.

application:
environment: Production # or Dev

Dev gives you an easy demo/trial environment with relaxed checks: guest/guest is accepted on RabbitMQ, and connecting to a non-local Kafka broker over an unencrypted protocol is allowed. Use Production in production; leaving it on Dev keeps those relaxed checks open there too.

Move on to E-mail settings to finish outgoing and incoming mail.