- Update COMPONENT_AUDIT.md: replace htmx reference with React SPA - Add server.read_only to config.example.yaml and CONFIGURATION.md
365 lines
12 KiB
Markdown
365 lines
12 KiB
Markdown
# 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. |
|
|
| `server.read_only` | bool | `false` | Start in read-only mode. All write endpoints return 503. Can be toggled at runtime with `SIGUSR1`. |
|
|
|
|
```yaml
|
|
server:
|
|
host: "0.0.0.0"
|
|
port: 8080
|
|
base_url: "https://silo.example.com"
|
|
read_only: false
|
|
```
|
|
|
|
---
|
|
|
|
## 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"
|
|
```
|