Skip to main content
Version: v0.21.0

Configuration

In this section, the configuration of the analytics data plane is explained. Configuration is used based on a config.yaml file which should be placed in the apps/backend folder. This config.yaml file is loaded when booting the application. The values get type checked, and it gives a clear error message if there is a configuration field missing or provided incorrectly. Next to the config.yaml file, you can also set environment variables. These override the values that are listed in the config.yaml file.

Databases​

By default, the development database is sqlite. We use postgres databases for production type instances of the analytics data planes.

Authentication​

Authentication for frontend services can be done via OAuth. This helps users who need to login to several components to authenticate themselves faster. The data plane is tested against the SSO Bridge, with an Helm chart provided alongside the Helm chart of the data plane, but other OAuth services should be usable (e.g. Keycloak, or hosted OAuth services).

Execution sources​

A transferred dataset carries only { sourceId, path } in its private asset configuration. The media type stays in catalog metadata. The source ID resolves through this deployment's role-local source configuration. The orchestration app has its own inspection configuration for the same logical sourceId; its physical path and credentials may differ. The control plane receives neither.

datasources:
sources:
- sourceId: party-a-lake
executionScope:
issuer: https://identity.example
controlPlaneId: control-plane-api
tenantId: 11111111-1111-4111-8111-111111111111
type: s3
endpoint: http://minio:9000
bucket: party-a
region: eu-west-1
forcePathStyle: true
- sourceId: local-dataset
executionScope:
issuer: https://identity.example
controlPlaneId: control-plane-api
tenantId: 11111111-1111-4111-8111-111111111111
type: local
root: /data

Relative local roots resolve from config.yaml. With Helm, sources live under config.datasources.sources, so the existing ConfigMap and rollout checksum are sufficient. Put credentials in configFromSecrets.datasources.sources at the same list index; the chart projects them as TSG__... environment overrides. In split mode configure sources only on the LAN client runner, not the DMZ server.

Jobs read source bytes through the owner-scoped worker proxy with a per-job DATA_ACCESS_TOKEN. Local files and S3 objects stay behind that proxy. Jobs receive no dataset mounts, storage credentials or presigned S3 URLs. The ADP does not inspect CSV, author metadata, upload datasets, or maintain a catalog.

Every standalone worker and split server requires explicit controlplaneId, dataplaneId and a nonempty controlPlane.executionScopes list. A deployment serving one owner uses one scope and the same runtime restrictions. Split clients use split.executionScopes and an authenticated assigned runner identity. See tenant-aware execution for complete runtime settings and upgrade steps. Old unowned jobs are fenced; drain them before upgrading and submit fresh flows and jobs with explicit ownership.

Configuration parameters​

KeyRequiredTypeDescriptionDefault
ManagementConfig
managementManagementConfigWorker global management policy
OperatorPrincipal
management.operatorPrincipalsOperatorPrincipal[]Global human operators allowed to inspect this worker; tenant grants never confer operator access[]
management.operatorPrincipals[].issuerYesStringVerified operator issuer
management.operatorPrincipals[].subjectYesStringVerified operator subject
DatabaseConfig
dbYesDatabaseConfigDatabase configuration
db.retryAttemptsNumberConnection attempts during application startup, three seconds apart10
db.typeYes"sqlite" | "postgres"Type of database
db.databaseYesStringName of the database
db.synchronizeBooleanSynchronize database schemafalse
db{type=sqlite}YesSQLiteConfigDatabase configuration
db{type=sqlite}.retryAttemptsNumberConnection attempts during application startup, three seconds apart10
db{type=sqlite}.type"sqlite" | "postgres"Type of database"sqlite"
db{type=sqlite}.databaseYesStringName of the database
db{type=sqlite}.synchronizeBooleanSynchronize database schemafalse
db{type=postgres}YesPostgresConfigDatabase configuration
db{type=postgres}.hostYesStringHost of the database
db{type=postgres}.portYesNumberPort of the database
db{type=postgres}.usernameYesStringUsername of the database
db{type=postgres}.passwordYesStringPassword of the database
db{type=postgres}.sslObjectSSL configuration of the databasefalse
db{type=postgres}.retryAttemptsNumberConnection attempts during application startup, three seconds apart10
db{type=postgres}.type"sqlite" | "postgres"Type of database"postgres"
db{type=postgres}.databaseYesStringName of the database
db{type=postgres}.synchronizeBooleanSynchronize database schemafalse
ServerConfig
serverServerConfigServer configuration
server.listenStringIP address the server listens on"0.0.0.0"
server.portNumberPort the server listens on3000
server.publicDomainStringPublic domain of the server"localhost"
server.publicAddressStringPublic address of the server"http://localhost:3000"
server.subPathStringSub path of the server
AuthConfig
authYesAuthConfigManagement authentication configuration
auth.signalingIdStringReceiving plane identity for signaling tokens. Defaults to clientId.
auth.expectedIssuerStringExpected API token issuer; defaults to the discovered OpenID issuer
auth.expectedAudienceStringExpected API token audience; defaults to clientId.
auth.enabledBooleanEnable authenticationtrue
auth.openIdConfigurationURLStringOpenID configuration URL
auth.callbackURLURLCallback URL the auth service will redirect users
auth.redirectURLURLRedirect URL to UI after login/logout
auth.clientIdStringClient ID
auth.clientSecretStringClient secret (required for client_secret_post authentication)
auth.tokenEndpointAuthMethod"client_secret_post" | "private_key_jwt"Token endpoint authentication method: client_secret_post (default) or private_key_jwt"client_secret_post"
auth.privateKeyJwkObjectPrivate key in JWK format for private_key_jwt authentication. Alternative to privateKeyJwkFile.
auth.privateKeyJwkFileStringPath to file containing private key JWK for private_key_jwt authentication. Alternative to privateKeyJwk.
auth.permissionPathStringJSON path to extract permissions from the token"$.permissions[*]"
ControlPlaneConfig
controlPlaneYesControlPlaneConfigControl plane configuration
controlPlane.controlplaneIdYesStringLogical control-plane client identity verified on signaling
controlPlane.dataplaneIdYesStringStable worker identity and audience for authenticated signaling
ExecutionScopeConfig
controlPlane.executionScopesExecutionScopeConfig[]Exact execution owners accepted by this worker. Required on signaling servers; split runners use their bridge assignments[]
controlPlane.executionScopes[].issuerYesStringVerified signaling issuer
controlPlane.executionScopes[].controlPlaneIdYesStringLogical control-plane client identity
controlPlane.executionScopes[].tenantIdYesStringCanonical tenant UUID
LoggingConfig
loggingLoggingConfigLogging configuration
logging.debugBooleanEnable debug request loggingfalse
DataSourcesConfig
datasourcesDataSourcesConfigParticipant-local sources used for job execution
SourceConfig
datasources.sourcesYesSourceConfig[]Configured source bindings; workers require an exact executionScope on each source. Local paths resolve from this configuration file
SourceExecutionScopeConfig
datasources.sources[].executionScopeSourceExecutionScopeConfigOwner required by analytics executors: issuer, controlPlaneId and tenantId
datasources.sources[].executionScope.issuerYesStringVerified issuer that grants this execution ownership
datasources.sources[].executionScope.controlPlaneIdYesStringLogical control-plane identity that owns this execution scope
datasources.sources[].executionScope.tenantIdYesStringCanonical tenant UUID that owns this execution scope
datasources.sources[].sourceIdYesStringStable logical source identifier shared across components
datasources.sources[].typeYes"local" | "http" | "s3"Source type: local, http or s3
datasources.sources[].rootStringlocal: root directory visible to this component
datasources.sources[].baseUrlStringhttp: base URL under which dataset paths are resolved
datasources.sources[].bucketStrings3: bucket containing the datasets
datasources.sources[].keyPrefixStrings3: configured object-key prefix containing this owner's datasets
datasources.sources[].endpointStrings3: endpoint URL for an S3-compatible service
datasources.sources[].regionStrings3: region
datasources.sources[].forcePathStyleBooleans3: use path-style addressing
datasources.sources[].authorizationStringhttp: upstream Authorization header value
datasources.sources[].accessKeyIdStrings3: access key ID
datasources.sources[].secretAccessKeyStrings3: secret access key
EventsConfig
eventsEventsConfigAlgorithm event configuration
events.peerEndpointsStringapproved remote analytics API bases for peer event channels; the local worker API is always allowed[]
EventPayloadStoreConfig
events.payloadsEventPayloadStoreConfigWhere algorithm event payloads are stored. When unset, payloads are stored in the database, which does not scale past a few hundred megabytes
events.payloads.type"local" | "s3"Store type: 'local' or 's3'"local"
events.payloads.rootStringlocal: directory that payloads are written under"./data/event-payloads"
events.payloads.bucketStrings3: bucket holding the payloads
events.payloads.endpointStrings3: endpoint URL, for S3-compatible stores such as MinIO
events.payloads.regionStrings3: region
events.payloads.forcePathStyleBooleans3: use path-style addressing instead of virtual-hosted style
events.payloads.accessKeyIdStrings3: access key id
events.payloads.secretAccessKeyStrings3: secret access key
events.payloads.prefixStringKey prefix that payloads are written under"events"
RuntimeConfig
runtimeYesRuntimeConfigRuntime configuration
runtime.colorStringPrimary UI color"#3B8BF6"
runtime.lightThemeUrlStringLight theme logo URL
runtime.darkThemeUrlStringDark theme logo URL
runtime.jobRefreshIntervalMsNumberInterval in milliseconds for auto-refreshing the jobs table in the UI (0 to disable)10000
OrchestrationConfigBase
orchestrationOrchestrationConfigBaseJob runtime configuration, unused on a split server
orchestration.typeYes"kubernetes" | "docker"Orchestration type: 'kubernetes' or 'docker'
orchestration{type=kubernetes}KubernetesConfigJob runtime configuration, unused on a split server
KubernetesApprovedImage
orchestration{type=kubernetes}.allowedImagesYesKubernetesApprovedImage[]Administrator-qualified cooperative images and their fixed commands
orchestration{type=kubernetes}.allowedImages[].imageYesStringExact qualified image reference; prefer immutable digests
orchestration{type=kubernetes}.allowedImages[].commandYesStringOperator-approved executable and arguments, independent of submitted algorithm commands
orchestration{type=kubernetes}.preloadedImagesStringExact approved images whose cached copies every tenant may execute without registry authorization[]
orchestration{type=kubernetes}.jobServiceAccountYesStringPre-created unprivileged job service account without image pull secrets; default is not accepted
orchestration{type=kubernetes}.callbackUrlYesStringWorker Pod IP callback URL on server.port. The {POD_IP} host placeholder resolves from the environment and brackets IPv6 addresses. Must match a running non-hostNetwork worker pod
orchestration{type=kubernetes}.workerNamespaceYesStringNamespace containing the selected worker callback pods
orchestration{type=kubernetes}.workerPodSelectorYesObjectExact worker pod labels allowed by job egress policy
orchestration{type=kubernetes}.runAsUserNumberNonroot UID for job processes and writable volumes1000
KubernetesResources
orchestration{type=kubernetes}.resourceRequestsKubernetesResourcesCPU and memory requested for each job
orchestration{type=kubernetes}.resourceRequests.cpuYesStringCPU quantity, for example '100m' or '1'
orchestration{type=kubernetes}.resourceRequests.memoryYesStringMemory quantity, for example '128Mi' or '512Mi'
KubernetesResources
orchestration{type=kubernetes}.resourceLimitsKubernetesResourcesCPU and memory limits for each job
orchestration{type=kubernetes}.resourceLimits.cpuYesStringCPU quantity, for example '100m' or '1'
orchestration{type=kubernetes}.resourceLimits.memoryYesStringMemory quantity, for example '128Mi' or '512Mi'
orchestration{type=kubernetes}.contextStringExplicit kubeconfig context for execution, or 'in-cluster' for the current pod service account
orchestration{type=kubernetes}.namespaceStringKubernetes namespace"default"
orchestration{type=kubernetes}.pullPolicy"IfNotPresent" | "Always" | "Never"Kubernetes image pull policy. Jobs verify registry manifest authorization and always pull unless listed in preloadedImages without submitted credentials. Leave unset to use Kubernetes defaults for approved preloaded images.
orchestration{type=kubernetes}.nodeSelectorObjectKubernetes Node selector for scheduling jobs. See https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector for format details and usage examples.
orchestration{type=kubernetes}.affinityObjectKubernetes Node affinity for scheduling jobs. See https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ for format details and usage examples.
orchestration{type=kubernetes}.tolerationsArrayKubernetes Tolerations for scheduling jobs on tainted nodes. See https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ for format details and usage examples.
orchestration{type=kubernetes}.type"kubernetes" | "docker"Orchestration type: 'kubernetes' or 'docker'"kubernetes"
orchestration{type=docker}DockerConfigJob runtime configuration, unused on a split server
orchestration{type=docker}.preloadedImagesStringApproved images whose cached copies every accepted tenant may execute[]
DockerLimits
orchestration{type=docker}.limitsDockerLimitsnonroot identity, writable temporary space, CPU and memory limits
orchestration{type=docker}.limits.runAsUserNumberNonroot UID and GID for jobs and their runtime directory1000
orchestration{type=docker}.limits.tmpfsSizeNumberWritable /tmp size in bytes per job; the root filesystem is read-only67108864
orchestration{type=docker}.limits.memoryNumberMemory limit in bytes per job; swap is disabled536870912
orchestration{type=docker}.limits.nanoCpusNumberCPU limit per job in units of 1e-9 CPUs1000000000
orchestration{type=docker}.allowedImagesStringexact administrator-approved image references. Prefer immutable digest references[]
orchestration{type=docker}.workerContainerStringWorker container ID or name; jobs use internal networks attached only to this verified standalone worker or split runner
orchestration{type=docker}.socketPathStringDocker socket path (e.g., /var/run/docker.sock)"/var/run/docker.sock"
orchestration{type=docker}.platformStringPlatform to use for Docker containers (e.g., 'linux/amd64')
orchestration{type=docker}.pullPolicy"IfNotPresent" | "Always" | "Never"Docker image pull policy. Jobs always pull unless explicitly listed in preloadedImages without submitted credentials. Use IfNotPresent or Never for approved preloaded development images."Always"
orchestration{type=docker}.type"kubernetes" | "docker"Orchestration type: 'kubernetes' or 'docker'"docker"
SplitConfig
splitSplitConfigClient/server split configuration
RunnerConfig
split.runnersRunnerConfig[]Server runner identity and owner assignments[]
split.runners[].idYesStringStable runner identity used in persisted job assignments
split.runners[].issuerYesStringVerified OAuth issuer of the runner service principal
split.runners[].subjectYesStringVerified OAuth subject of the runner service principal
split.runners[].clientIdStringOptional verified OAuth client ID required for the runner
SourceExecutionScopeConfig
split.runners[].executionScopesYesSourceExecutionScopeConfig[]Exact verified execution owners assigned exclusively to this runner
split.runners[].executionScopes[].issuerYesStringVerified issuer that grants this execution ownership
split.runners[].executionScopes[].controlPlaneIdYesStringLogical control-plane identity that owns this execution scope
split.runners[].executionScopes[].tenantIdYesStringCanonical tenant UUID that owns this execution scope
split.runnerIdStringClient's immutable runner identity
SourceExecutionScopeConfig
split.executionScopesSourceExecutionScopeConfig[]Client's exact allowed execution ownership scopes[]
split.executionScopes[].issuerYesStringVerified issuer that grants this execution ownership
split.executionScopes[].controlPlaneIdYesStringLogical control-plane identity that owns this execution scope
split.executionScopes[].tenantIdYesStringCanonical tenant UUID that owns this execution scope
split.bridgeAudienceStringAudience requested by the runner for its authenticated bridge connection
split.allowInsecureBridgeBooleanAllow a plain HTTP bridge only in an explicitly trusted local test networkfalse
split.maxPayloadBytesNumberSplit event payload limit in bytes, at most 64 MiB. Applies before buffering or chunk assembly67108864
split.mode"standalone" | "client" | "server"Runtime mode: standalone (current behavior), client (network-constrained runner), or server (open-network exchanger)"standalone"
split.bridgePeerWsUrlStringPeer WebSocket URL for bridge connection (Socket.IO server base URL)
split.bridgeChunkSizeNumberChunk size in bytes for large event data transfers over WebSocket (default: 512KB)
AuditModuleConfig
auditAuditModuleConfigAudit logging configuration
audit.enabledBooleanEnable audit loggingtrue
audit.minSeverity"debug" | "info" | "warning" | "error" | "critical"Minimum severity level to log"info"
audit.logDeniedBooleanAlways log denied access attempts regardless of action typetrue
audit.logDelegatedBooleanLog delegated access attempts when enabled, while still respecting action-specific success filterstrue
audit.logMutationsBooleanLog successful mutation actions (create, update, delete, manage)true
audit.logExecuteBooleanLog successful execute actionsfalse
audit.logReadsBooleanLog successful read actions — disabled by default as reads are frequent and rarely relevant for auditingfalse
audit.sensitiveResourcesArrayResources logged regardless of minimum severity, while still respecting action-specific success filters["w.key","w.credential","sso.user"]
AuditHandlersConfig
audit.handlersAuditHandlersConfigHandler configuration
audit.handlers.consoleBooleanEnable console audit log handlerfalse
audit.handlers.databaseBooleanEnable database audit log handlertrue
audit.handlers.otlpBooleanEnable OTLP audit log handlerfalse
OtlpAuditHandlerConfig
audit.otlpOtlpAuditHandlerConfigOTLP audit log handler configuration
audit.otlp.urlStringOTLP HTTP logs endpoint URL"http://localhost:4318/v1/logs"
audit.otlp.headersObjectAdditional HTTP headers to include in OTLP requests
audit.otlp.timeoutMillisNumberOTLP export timeout in milliseconds5000
audit.otlp.concurrencyLimitNumberMaximum number of concurrent OTLP export requests1
audit.otlp.serviceNameStringService name included on OTLP log attributes"tsg-dsp-api"
audit.otlp.serviceVersionStringOptional service version included on OTLP log attributes