Configuration
formae is configured using a Pkl configuration file that controls agent behavior, datastore settings, discovery, synchronization, logging, and observability.
Configuration Format
The configuration file uses Pkl syntax and amends the base formae:/Config.pkl schema, which provides validation and defaults for all settings.
Default Configuration
The configuration file is located at $HOME/.config/formae/formae.conf.pkl. If no configuration file exists, formae uses default settings. The config file is not automatically created. Create one if you want to customize settings.
To create a minimal configuration file:
amends "formae:/Config.pkl"
agent {
}
cli {
}
Complete Configuration Reference
Below is a complete configuration showing all available options with their defaults:
amends "formae:/Config.pkl"
agent {
server {
nodename = "formae"
hostname = "localhost"
port = 49684
secret = ""
tlsCert = null
tlsKey = null
}
datastore {
datastoreType = "sqlite"
sqlite {
filePath = "~/.pel/formae/data/formae.db"
}
postgres {
host = "localhost"
port = 5432
user = "postgres"
password = "admin"
database = ""
schema = ""
connectionParams = ""
}
auroraDataAPI {
clusterArn = ""
secretArn = ""
database = ""
region = ""
}
}
synchronization {
enabled = true
interval = 5.min
}
discovery {
enabled = true
labelTagKeys = new Listing {
"Name"
}
interval = 10.min
resourceTypesToDiscover = new Listing { }
}
logging {
filePath = "~/.pel/formae/log/formae.log"
fileLogLevel = "debug"
consoleLogLevel = "info"
}
oTel {
enabled = false
serviceName = "formae-agent"
otlp {
enabled = true
endpoint = "http://localhost:4317"
protocol = "grpc"
insecure = true
temporality = "delta"
}
prometheus {
enabled = true
}
}
retry {
statusCheckInterval = 10.s
maxRetries = 9
retryDelay = 10.s
}
}
cli {
api {
url = "http://localhost"
port = 49684
}
}
pluginDir = "~/.pel/formae/plugins"
Several optional sections are omitted above because they have no defaults: Authentication (agent.auth, cli.auth), Resource plugins (agent.resourcePlugins), and Network (top-level network). See the respective sections below to configure them.
Configuration Reference
Server Settings
Controls the agent's network configuration and cluster identity. Essential for multi-agent deployments.
| Property | Type | Default | Description |
|---|---|---|---|
nodename |
String | "formae" |
Unique identifier for this agent in the cluster |
hostname |
String | "localhost" |
Network interface where the agent listens for incoming connections |
port |
Number | 49684 |
Port number for the agent API |
secret |
String | "" |
Cluster-wide authentication token for secure agent communication |
tlsCert |
String? | null |
Path to TLS certificate file for secure connections |
tlsKey |
String? | null |
Path to TLS private key file for secure connections |
Datastore
Choose between SQLite (default, suitable for single-agent), PostgreSQL (recommended for production with high availability requirements), or Aurora Data API (for AWS deployments).
| Property | Type | Default | Description |
|---|---|---|---|
datastoreType |
String | "sqlite" |
Type of datastore to use: "sqlite", "postgres", or "auroradataapi" |
SQLite Configuration:
| Property | Type | Default | Description |
|---|---|---|---|
filePath |
String | "~/.pel/formae/data/formae.db" |
Path to the SQLite database file |
PostgreSQL Configuration:
| Property | Type | Default | Description |
|---|---|---|---|
host |
String | "localhost" |
PostgreSQL server hostname |
port |
Number | 5432 |
PostgreSQL server port |
user |
String | "postgres" |
Database user for authentication |
password |
String | "admin" |
Database password for authentication |
database |
String | "" |
Database name to connect to |
schema |
String | "" |
PostgreSQL schema to use |
connectionParams |
String | "" |
Additional connection parameters |
Aurora Data API Configuration:
Use Aurora Data API for data access via AWS RDS Data API.
| Property | Type | Default | Description |
|---|---|---|---|
clusterArn |
String | "" |
ARN of the Aurora Serverless cluster |
secretArn |
String | "" |
ARN of the Secrets Manager secret containing database credentials |
database |
String | "" |
Database name to connect to |
region |
String | "" |
AWS region where the cluster is located (uses default region if empty) |
Synchronization
Enable synchronization of managed resources. When enabled, formae periodically checks if resources have been modified outside of the tool.
| Property | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | true |
Enable synchronization of managed resources |
interval |
Duration | 5.min |
How frequently to check for external changes |
Discovery
Automatically finds and catalogs infrastructure resources not yet under formae management. Useful for onboarding existing infrastructure.
Discovery scans targets that have been marked as discoverable = true in your forma files. See the discovery documentation for details on configuring discoverable targets.
| Property | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | true |
Enable automatic resource discovery |
labelTagKeys |
List<String> | ["Name"] |
Tag keys to use when building resource labels (concatenated with dashes) |
interval |
Duration | 10.min |
How frequently to run discovery scans |
resourceTypesToDiscover |
List<String> | [] |
Specific resource types to discover (empty list discovers all supported types) |
Logging
Configure log output levels and file locations. Keep file log level at debug for troubleshooting support.
| Property | Type | Default | Description |
|---|---|---|---|
filePath |
String | "~/.pel/log/formae.log" |
Path to the log file |
fileLogLevel |
String | "debug" |
Log level for file output: "debug", "info", "warn", "error" |
consoleLogLevel |
String | "info" |
Log level for console output: "debug", "info", "warn", "error" |
OpenTelemetry
Enable telemetry export to your observability platform. When enabled, metrics, logs, and traces are pushed via OTLP.
| Property | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | false |
Enable OpenTelemetry integration |
serviceName |
String | "formae-agent" |
Service name for telemetry identification |
OTLP Configuration:
| Property | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | true |
Whether to enable OTLP push export for traces, metrics, and logs |
endpoint |
String | "http://localhost:4317" |
OTLP collector endpoint URL |
protocol |
String | "grpc" |
Protocol to use: "grpc" or "http" |
insecure |
Boolean | true |
Whether to use insecure connections (disable TLS) |
temporality |
String | "delta" |
Metric temporality: "delta" (OTel-native) or "cumulative" (for Prometheus/Mimir backends without delta support) |
Prometheus Configuration:
| Property | Type | Default | Description |
|---|---|---|---|
enabled |
Boolean | true |
Enable Prometheus /metrics endpoint for pull-based scraping |
Retry
Control how formae handles transient failures during resource operations. These values are the agent-wide defaults and can be overridden per plugin in Resource plugins.
| Property | Type | Default | Description |
|---|---|---|---|
statusCheckInterval |
Duration | 10.s |
How frequently to check the status of a resource operation |
maxRetries |
Number | 9 |
Maximum number of retries for a recoverable failed operation |
retryDelay |
Duration | 10.s |
How long to wait before retrying a failed operation |
Resource plugins
agent.resourcePlugins is a list of per-plugin configuration blocks that override defaults published by each plugin. Each installed plugin ships its own typed configuration that you import through the plugins:/ scheme. Any plugin that is not listed uses its built-in defaults.
Available overrides on every resource plugin:
| Property | Type | Description |
|---|---|---|
enabled |
Boolean | Set to false to disable the plugin. When disabled no other fields apply. Default: true. |
rateLimit |
RateLimitConfig? | Cap the request rate this plugin issues to its provider. maxRequestsPerSecondForNamespace is the per-target cap. |
retry |
RetryConfig? | Override the agent-wide retry settings for this plugin. |
resourceTypesToDiscover |
List<String>? | Restrict which resource types this plugin reports during discovery. An empty/absent value means "all supported types". |
discoveryFilters |
List<MatchFilter>? | Exclude specific discovered resources by matching on properties (for example, skipping resources that carry a Kubernetes-owner tag). |
labelConfig |
LabelConfig? | Customize how human-readable labels are generated for discovered resources. defaultQuery is a JSONPath query; resourceOverrides sets per-resource-type queries that win over the default. |
Plugins may also expose plugin-specific fields defined in their own schema/Config.pkl. These appear alongside the fields above on the same configuration block.
Disabling a plugin
Use enabled = false to stop the agent from loading a plugin. No other options apply in this case.
amends "formae:/Config.pkl"
import "plugins:/Azure.pkl" as Azure
agent {
resourcePlugins {
new Azure.PluginConfig {
enabled = false
}
}
}
Tuning an installed plugin
This example uses the SFTP plugin because it exposes plugin-specific fields (defaultTimeoutSeconds, defaultFilePermissions) in addition to the common overrides.
amends "formae:/Config.pkl"
import "plugins:/Sftp.pkl" as Sftp
agent {
resourcePlugins {
new Sftp.PluginConfig {
// Common overrides
rateLimit {
maxRequestsPerSecondForNamespace = 5
}
retry {
maxRetries = 3
retryDelay = 30.s
}
// Plugin-specific fields defined by the SFTP plugin
defaultTimeoutSeconds = 60
defaultFilePermissions = "0600"
}
}
}
You can combine multiple plugin blocks under a single resourcePlugins { ... } listing. The type field is automatically set by each plugin's wrapper, so you only need to fill in the overrides you care about.
CLI
Configure how the CLI connects to the agent API. See Authentication for cli.auth.
| Property | Type | Default | Description |
|---|---|---|---|
api.url |
String | "http://localhost" |
Base URL for the agent API |
api.port |
Number | 49684 |
Port number for the agent API |
Authentication
Authentication is configured separately for the agent and CLI. The agent.auth block controls server-side validation; the cli.auth block provides client-side credentials. Both fields are optional — if unset, the agent serves unauthenticated requests.
Each auth plugin ships its own typed configuration that you import through the plugins:/ scheme, the same pattern used for Resource plugins. The example below uses the auth-basic plugin, which is the default HTTP Basic Authentication option.
amends "formae:/Config.pkl"
import "plugins:/AuthBasic.pkl" as AuthBasic
agent {
auth = new AuthBasic.AgentConfig {
authorizedUsers {
new AuthBasic.AuthorizedUser {
username = "alice"
// bcrypt hash — generate with:
// htpasswd -bnBC 10 "" yourPassword | tr -d ':'
password = "$2y$10$ki1wCrM94EViuTv0dRNEVuP3ujj2/uu2Zh8/FyFvExjZyrsdtr1SS"
}
}
}
}
cli {
auth = new AuthBasic.CliConfig {
username = "alice"
password = "mySecretPass"
}
}
See Security and networking for more detail on the auth-basic setup.
Network
Top-level network configuration. The type field selects the network plugin.
| Property | Type | Default | Description |
|---|---|---|---|
network.type |
String | — | Network plugin type (e.g. "tailscale") |
network.tailscale |
TailscaleConfig? | null |
Tailscale-specific configuration |
See Tailscale for setup instructions.
Plugin directory
Top-level setting for where formae discovers installed plugins.
| Property | Type | Default | Description |
|---|---|---|---|
pluginDir |
String | "~/.pel/formae/plugins" |
Directory where installed plugins live. Can also be set via the FORMAE_PLUGIN_DIR environment variable. |
Deprecated plugins block
Earlier releases configured authentication, network access, and the plugin directory under a single top-level plugins { ... } block. That block is still accepted for backwards compatibility but emits deprecation warnings at startup. Migrate as follows:
| Old location | New location |
|---|---|
plugins.authentication |
agent.auth + cli.auth |
plugins.network |
top-level network |
plugins.pluginDir |
top-level pluginDir |