Closes #4 — Document all config.yaml options. New file: docs/CONFIGURATION.md covering all 7 config sections: - Server: bind address, port, read/write timeouts - Database: host, port, name, user, password, SSL mode, pool sizes - Storage: MinIO endpoint, bucket, access/secret keys, SSL, region - Schemas: directory path for part number schema YAML files - FreeCAD: command path for server-side thumbnail generation - Odoo: URL, database, API key, default company, field mappings - Auth: enabled flag, session secret/lifetime, JWT secret, CORS origins, local/LDAP/OIDC provider configuration Includes all 12 environment variable overrides, SSL mode guidance, and 4 deployment example snippets (minimal, Docker Compose with env vars, LDAP + OIDC, production hardened).
12 KiB
Configuration Reference
Last Updated: 2026-02-06
Overview
Silo is configured via a YAML file. Copy the example and edit for your environment:
cp config.example.yaml config.yaml
The server reads the config file at startup:
./silod -config config.yaml # default: config.yaml
go run ./cmd/silod -config config.yaml
YAML values support environment variable expansion using ${VAR_NAME} syntax. Environment variable overrides (listed per-key below) take precedence over YAML values.
Server
| Key | Type | Default | Description |
|---|---|---|---|
server.host |
string | "0.0.0.0" |
Bind address |
server.port |
int | 8080 |
HTTP port |
server.base_url |
string | — | External URL (e.g. https://silo.example.com). Used for OIDC callback URLs and session cookie domain. Required when OIDC is enabled. |
server:
host: "0.0.0.0"
port: 8080
base_url: "https://silo.example.com"
Database
| Key | Type | Default | Env Override | Description |
|---|---|---|---|---|
database.host |
string | — | SILO_DB_HOST |
PostgreSQL host |
database.port |
int | 5432 |
— | PostgreSQL port |
database.name |
string | — | SILO_DB_NAME |
Database name |
database.user |
string | — | SILO_DB_USER |
Database user |
database.password |
string | — | SILO_DB_PASSWORD |
Database password |
database.sslmode |
string | "require" |
— | SSL mode: disable, require, verify-ca, verify-full |
database.max_connections |
int | 10 |
— | Connection pool size |
SSL mode guidance:
disable— development only, no encryptionrequire— encrypted but no certificate verification (default)verify-ca— verify server certificate is signed by trusted CAverify-full— verify CA and hostname match (recommended for production)
database:
host: "localhost"
port: 5432
name: "silo"
user: "silo"
password: "" # use SILO_DB_PASSWORD env var
sslmode: "require"
max_connections: 10
Storage (MinIO/S3)
| Key | Type | Default | Env Override | Description |
|---|---|---|---|---|
storage.endpoint |
string | — | SILO_MINIO_ENDPOINT |
MinIO/S3 endpoint (host:port) |
storage.access_key |
string | — | SILO_MINIO_ACCESS_KEY |
Access key |
storage.secret_key |
string | — | SILO_MINIO_SECRET_KEY |
Secret key |
storage.bucket |
string | — | — | S3 bucket name (created automatically if missing) |
storage.use_ssl |
bool | false |
— | Use HTTPS for MinIO connections |
storage.region |
string | "us-east-1" |
— | S3 region |
storage:
endpoint: "localhost:9000"
access_key: "" # use SILO_MINIO_ACCESS_KEY env var
secret_key: "" # use SILO_MINIO_SECRET_KEY env var
bucket: "silo-files"
use_ssl: false
region: "us-east-1"
Schemas
| Key | Type | Default | Description |
|---|---|---|---|
schemas.directory |
string | "/etc/silo/schemas" |
Path to directory containing YAML schema files |
schemas.default |
string | — | Default schema name for part number generation |
Schema files define part numbering formats, category codes, and property definitions. See schemas/kindred-rd.yaml for an example.
schemas:
directory: "./schemas"
default: "kindred-rd"
FreeCAD
| Key | Type | Default | Description |
|---|---|---|---|
freecad.uri_scheme |
string | "silo" |
URI scheme for "Open in FreeCAD" links in the web UI |
freecad.executable |
string | — | Path to FreeCAD binary (for CLI operations) |
freecad:
uri_scheme: "silo"
executable: "/usr/bin/freecad"
Odoo ERP Integration
| Key | Type | Default | Description |
|---|---|---|---|
odoo.enabled |
bool | false |
Enable Odoo integration |
odoo.url |
string | — | Odoo server URL |
odoo.database |
string | — | Odoo database name |
odoo.username |
string | — | Odoo username |
odoo.api_key |
string | — | Odoo API key |
The Odoo integration currently supports configuration and sync-log CRUD. Push/pull sync operations are stubs.
odoo:
enabled: false
url: "https://odoo.example.com"
database: "odoo"
username: "silo-service"
api_key: ""
Authentication
Authentication has a master toggle and three independent backends. When auth.enabled is false, all routes are accessible without login and a synthetic admin user (dev) is injected into every request.
| Key | Type | Default | Env Override | Description |
|---|---|---|---|---|
auth.enabled |
bool | false |
— | Master toggle. Set true for production. |
auth.session_secret |
string | — | SILO_SESSION_SECRET |
Secret for signing session cookies. Required when auth is enabled. |
Local Auth
Built-in username/password accounts stored in the Silo database with bcrypt-hashed passwords.
| Key | Type | Default | Env Override | Description |
|---|---|---|---|---|
auth.local.enabled |
bool | — | — | Enable local accounts |
auth.local.default_admin_username |
string | — | SILO_ADMIN_USERNAME |
Default admin account created on first startup |
auth.local.default_admin_password |
string | — | SILO_ADMIN_PASSWORD |
Password for default admin (bcrypt-hashed on creation) |
The default admin account is only created if both username and password are set and the user does not already exist. This is idempotent.
LDAP / FreeIPA
| Key | Type | Default | Env Override | Description |
|---|---|---|---|---|
auth.ldap.enabled |
bool | false |
— | Enable LDAP authentication |
auth.ldap.url |
string | — | — | LDAP server URL (e.g. ldaps://ipa.example.com) |
auth.ldap.base_dn |
string | — | — | Base DN for the LDAP tree |
auth.ldap.user_search_dn |
string | — | — | DN under which to search for users |
auth.ldap.bind_dn |
string | — | — | Service account DN for user lookups (optional; omit for direct user bind) |
auth.ldap.bind_password |
string | — | SILO_LDAP_BIND_PASSWORD |
Service account password |
auth.ldap.user_attr |
string | "uid" |
— | LDAP attribute for username |
auth.ldap.email_attr |
string | "mail" |
— | LDAP attribute for email |
auth.ldap.display_attr |
string | "displayName" |
— | LDAP attribute for display name |
auth.ldap.group_attr |
string | "memberOf" |
— | LDAP attribute for group membership |
auth.ldap.role_mapping |
map | — | — | Maps LDAP group DNs to Silo roles (see example below) |
auth.ldap.tls_skip_verify |
bool | false |
— | Skip TLS certificate verification (testing only) |
Role mapping maps LDAP group DNs to Silo roles. Groups are checked in priority order: admin, then editor, then viewer. The first match wins.
auth:
ldap:
enabled: true
url: "ldaps://ipa.example.com"
base_dn: "dc=example,dc=com"
user_search_dn: "cn=users,cn=accounts,dc=example,dc=com"
role_mapping:
admin:
- "cn=silo-admins,cn=groups,cn=accounts,dc=example,dc=com"
editor:
- "cn=silo-users,cn=groups,cn=accounts,dc=example,dc=com"
- "cn=engineers,cn=groups,cn=accounts,dc=example,dc=com"
viewer:
- "cn=silo-viewers,cn=groups,cn=accounts,dc=example,dc=com"
OIDC / Keycloak
| Key | Type | Default | Env Override | Description |
|---|---|---|---|---|
auth.oidc.enabled |
bool | false |
— | Enable OIDC authentication |
auth.oidc.issuer_url |
string | — | — | OIDC provider issuer URL (e.g. Keycloak realm URL) |
auth.oidc.client_id |
string | — | — | OAuth2 client ID |
auth.oidc.client_secret |
string | — | SILO_OIDC_CLIENT_SECRET |
OAuth2 client secret |
auth.oidc.redirect_url |
string | — | — | OAuth2 callback URL (typically {base_url}/auth/callback) |
auth.oidc.scopes |
[]string | ["openid", "profile", "email"] |
— | OAuth2 scopes to request |
auth.oidc.admin_role |
string | — | — | Keycloak realm role that grants admin access |
auth.oidc.editor_role |
string | — | — | Keycloak realm role that grants editor access |
auth.oidc.default_role |
string | "viewer" |
— | Fallback role when no role claim matches |
Roles are extracted from the Keycloak realm_access.roles claim. If the user has the admin_role, they get admin. Otherwise if they have editor_role, they get editor. Otherwise default_role applies.
auth:
oidc:
enabled: true
issuer_url: "https://keycloak.example.com/realms/silo"
client_id: "silo"
client_secret: "" # use SILO_OIDC_CLIENT_SECRET env var
redirect_url: "https://silo.example.com/auth/callback"
admin_role: "silo-admin"
editor_role: "silo-editor"
default_role: "viewer"
CORS
| Key | Type | Default | Description |
|---|---|---|---|
auth.cors.allowed_origins |
[]string | — | Origins allowed for cross-origin requests from browser-based clients |
FreeCAD and other non-browser clients use direct HTTP and are not affected by CORS. This setting is for browser-based tools running on different origins.
auth:
cors:
allowed_origins:
- "https://silo.example.com"
Environment Variables
All environment variable overrides. These take precedence over values in config.yaml.
| Variable | Config Key | Description |
|---|---|---|
SILO_DB_HOST |
database.host |
PostgreSQL host |
SILO_DB_NAME |
database.name |
PostgreSQL database name |
SILO_DB_USER |
database.user |
PostgreSQL user |
SILO_DB_PASSWORD |
database.password |
PostgreSQL password |
SILO_MINIO_ENDPOINT |
storage.endpoint |
MinIO endpoint |
SILO_MINIO_ACCESS_KEY |
storage.access_key |
MinIO access key |
SILO_MINIO_SECRET_KEY |
storage.secret_key |
MinIO secret key |
SILO_SESSION_SECRET |
auth.session_secret |
Session cookie signing secret |
SILO_ADMIN_USERNAME |
auth.local.default_admin_username |
Default admin username |
SILO_ADMIN_PASSWORD |
auth.local.default_admin_password |
Default admin password |
SILO_LDAP_BIND_PASSWORD |
auth.ldap.bind_password |
LDAP service account password |
SILO_OIDC_CLIENT_SECRET |
auth.oidc.client_secret |
OIDC client secret |
Additionally, YAML values can reference environment variables directly using ${VAR_NAME} syntax, which is expanded at load time via os.ExpandEnv().
Deployment Examples
Development (no auth)
server:
host: "0.0.0.0"
port: 8080
base_url: "http://localhost:8080"
database:
host: "localhost"
port: 5432
name: "silo"
user: "silo"
password: "silodev"
sslmode: "disable"
storage:
endpoint: "localhost:9000"
access_key: "minioadmin"
secret_key: "minioadmin"
bucket: "silo-files"
use_ssl: false
schemas:
directory: "./schemas"
default: "kindred-rd"
auth:
enabled: false
Local Auth Only
auth:
enabled: true
session_secret: "change-me-to-a-random-string"
local:
enabled: true
default_admin_username: "admin"
default_admin_password: "change-me"
LDAP / FreeIPA
auth:
enabled: true
session_secret: "${SILO_SESSION_SECRET}"
local:
enabled: false
ldap:
enabled: true
url: "ldaps://ipa.example.com"
base_dn: "dc=example,dc=com"
user_search_dn: "cn=users,cn=accounts,dc=example,dc=com"
role_mapping:
admin:
- "cn=silo-admins,cn=groups,cn=accounts,dc=example,dc=com"
editor:
- "cn=engineers,cn=groups,cn=accounts,dc=example,dc=com"
viewer:
- "cn=silo-viewers,cn=groups,cn=accounts,dc=example,dc=com"
OIDC / Keycloak
auth:
enabled: true
session_secret: "${SILO_SESSION_SECRET}"
local:
enabled: false
oidc:
enabled: true
issuer_url: "https://keycloak.example.com/realms/silo"
client_id: "silo"
client_secret: "${SILO_OIDC_CLIENT_SECRET}"
redirect_url: "https://silo.example.com/auth/callback"
admin_role: "silo-admin"
editor_role: "silo-editor"
default_role: "viewer"