Files
silo/docs/CONFIGURATION.md
Forbes 21c592bcb2 docs: update all docs for sessions, solver, approvals, and recent features
- STATUS.md: migration count 18→23, endpoint count 86→~140, add approval
  workflows, solver service, workstations, edit sessions, SSE targeted
  delivery rows, update test file count 9→31, add migrations 019-023
- MODULES.md: add solver and sessions to registry, dependencies, endpoint
  mappings (sections 3.11, 3.12), discovery response, admin settings,
  config YAML, and future considerations
- CONFIGURATION.md: add Approval Workflows, Solver, and Modules config
  sections, add SILO_SOLVER_DEFAULT env var
- ROADMAP.md: mark Job Queue Complete (Tier 0), Audit Trail Complete
  (Tier 1), Approval/ECO Complete (Tier 4), update Workflow Engine tasks,
  add Recently Completed section, update counts, resolve job queue question
- GAP_ANALYSIS.md: mark approval workflow Implemented, locking Partial,
  update workflow comparison (C.2), update check-in/check-out to Partial,
  task scheduler to Full, update endpoint counts, rewrite Appendix A
- INSTALL.md: add MODULES.md, WORKERS.md, SOLVER.md to Further Reading
- WORKERS.md: status Draft→Implemented
- SOLVER.md: add spec doc, mark Phase 3b as complete
2026-03-03 13:26:08 -06:00

14 KiB

Configuration Reference

Last Updated: 2026-03-01


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.read_only bool false Start in read-only mode. All write endpoints return 503. Can be toggled at runtime with SIGUSR1.
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)
database:
  host: "localhost"
  port: 5432
  name: "silo"
  user: "silo"
  password: ""  # use SILO_DB_PASSWORD env var
  sslmode: "require"
  max_connections: 10

Storage (Filesystem)

Files are stored on the local filesystem under a configurable root directory.

Key Type Default Description
storage.backend string "filesystem" Storage backend (filesystem)
storage.filesystem.root_dir string Root directory for file storage (required)
storage:
  backend: "filesystem"
  filesystem:
    root_dir: "/opt/silo/data"

Ensure the directory exists and is writable by the silo user:

sudo mkdir -p /opt/silo/data
sudo chown silo:silo /opt/silo/data

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: ""

Approval Workflows

Key Type Default Description
workflows.directory string "/etc/silo/workflows" Path to directory containing YAML workflow definition files

Workflow definition files describe multi-stage approval processes using a state machine pattern. Each file defines a workflow with states, transitions, and approver requirements.

workflows:
  directory: "/etc/silo/workflows"

Solver

Key Type Default Env Override Description
solver.default_solver string "" SILO_SOLVER_DEFAULT Default solver backend name
solver.max_context_size_mb int 10 Maximum SolveContext payload size in MB
solver.default_timeout int 300 Default solver job timeout in seconds
solver.auto_diagnose_on_commit bool false Auto-submit diagnose job on assembly revision commit

The solver module depends on the jobs module being enabled. See SOLVER.md for the full solver service specification.

solver:
  default_solver: "ondsel"
  max_context_size_mb: 10
  default_timeout: 300
  auto_diagnose_on_commit: true

Modules

Optional module toggles. Each module can be explicitly enabled or disabled. If not listed, the module's built-in default applies. See MODULES.md for the full module system specification.

modules:
  projects:
    enabled: true
  audit:
    enabled: true
  odoo:
    enabled: false
  freecad:
    enabled: true
  jobs:
    enabled: false
  dag:
    enabled: false
  solver:
    enabled: false
  sessions:
    enabled: true

The auth.enabled field controls the auth module directly (not duplicated under modules:). The sessions module depends on auth and is enabled by default.


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_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
SILO_SOLVER_DEFAULT solver.default_solver Default solver backend name

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:
  backend: "filesystem"
  filesystem:
    root_dir: "./data"

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"