# Configuration Reference **Last Updated:** 2026-02-06 --- ## Overview Silo is configured via a YAML file. Copy the example and edit for your environment: ```bash cp config.example.yaml config.yaml ``` The server reads the config file at startup: ```bash ./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. | ```yaml 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 encryption - `require` — encrypted but no certificate verification (default) - `verify-ca` — verify server certificate is signed by trusted CA - `verify-full` — verify CA and hostname match (recommended for production) ```yaml 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 | ```yaml 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. ```yaml 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) | ```yaml 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. ```yaml 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. ```yaml 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. ```yaml 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. ```yaml 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) ```yaml 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 ```yaml 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 ```yaml 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 ```yaml 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" ```