Every key openlore.yml accepts, in the order the server reads them. Durations are Go duration strings such as 30s or 24h; byte sizes accept KB, MB and GB suffixes.
openlore.yml holds deployment settings; see Configure the server. Identities, roles and docsets belong in lore.json; see Auth.
Top-level keys
version
Type: string
Default: none
Config file format version, reserved for migrations between formats.
version: "1"
debug
Type: boolean
Default: false
Turns on verbose server logs, including unknown-command and syntax telemetry.
debug: true
experimental
Type: list of strings
Default: none
Names of experimental features to switch on; the OPENLORE_EXPERIMENTAL environment variable appends to this list.
experimental: ["analytics"]
port
Type: integer
Default: 2222
TCP port for the SSH server that agents connect to, from 1 to 65535; 0 is rejected because SSH cannot be disabled.
port: 22
metrics_port
Type: integer
Default: 3000
TCP port for the Prometheus metrics endpoint, up to 65535; 0 disables it.
metrics_port: 0
host_key_path
Type: string
Default: .ssh/openlore_ed25519
Path to the SSH host key. Generated on first start if the file does not exist.
host_key_path: /etc/openlore/host_key
motd
Type: string
Default: none
Message shown to every client when it connects.
motd: "Welcome to Acme docs. Type 'tree -L 1 /' to start."
motd_file
Type: string
Default: none
Path to a file whose contents replace motd; read once when the config loads.
motd_file: ./motd.txt
auth_file
Type: string
Default: none
Path to the lore.json file that maps keys to identities, roles and docsets.
auth_file: ./lore.json
skills_dir
Type: string
Default: none
Directory of additional skills (skills.json plus Markdown files) loaded alongside the built-in ones.
skills_dir: ./skills
writable_dir
Type: string
Default: none
Disk-backed content root overlaid on the embedded docs at the virtual root.
writable_dir: ./published
data_dir
Type: string
Default: .openlore
Root for server state such as signing keys, analytics and the write journal; distinct from content.
data_dir: /var/lib/openlore
http_port
Type: integer
Default: 8080
TCP port for the HTTP server that hosts the dashboard, MCP endpoint and JSON API, up to 65535; 0 disables it.
http_port: 80
external_ssh_port
Type: integer
Default: none
SSH port advertised to clients through the X-SSH-Port header when a load balancer remaps port.
external_ssh_port: 22
external_url
Type: string
Default: none
Externally advertised HTTP origin (no path) used in published links, passkey URLs and generated connection instructions; its host is also the advertised SSH host. Unset uses the first passkeys.rp_origins entry, else the local http_port.
external_url: https://docs.example.com
tls_cert
Type: string
Default: none
PEM certificate for the HTTP server; SSH is unaffected. Set with tls_key.
tls_cert: ./cert.pem
tls_key
Type: string
Default: none
PEM private key matching tls_cert.
tls_key: ./key.pem
ca_keys_file
Type: string
Default: none
File of CA public keys trusted to sign user SSH certificates, like OpenSSH’s TrustedUserCAKeys.
ca_keys_file: ./ca_user_key.pub
host_cert_file
Type: string
Default: none
CA-signed certificate for the key at host_key_path, presented to clients instead of a bare host key.
host_cert_file: .ssh/openlore_ed25519-cert.pub
default_cwd
Type: string
Default: /openlore
Directory a session starts in.
default_cwd: /docs
readonly
Type: boolean
Default: true
Rejects every write; set to false to let identities with write grants publish.
readonly: false
write_conflict_policy
Type: string
Default: hash
How overlapping writes to one file resolve: hash makes overwrites compare-and-swap, last_write_wins accepts the newest.
write_conflict_policy: last_write_wins
max_jobs
Type: integer
Default: 8
Maximum number of concurrent background jobs started with spawn; must be positive.
max_jobs: 16
analytics
Usage analytics: how reads and writes are logged, aggregated, indexed and exported.
analytics.enabled
Type: boolean
Default: true
Records agent reads and writes for the dashboard and the analytics command.
analytics:
enabled: false
analytics.dir
Type: string
Default: analytics
Directory for analytics logs and indexes; a relative path is resolved under data_dir.
analytics:
dir: /var/lib/openlore/analytics
analytics.log
Type: object
Rotation and retention of the raw analytics log.
analytics.log.rotate
Type: string
Default: 24h
Interval at which the active log segment is closed and a new one started.
analytics:
log:
rotate: 1h
analytics.log.compress
Type: string
Default: zstd
Compression applied to rotated log segments.
analytics:
log:
compress: zstd
analytics.log.retention
Type: string
Default: none
How long rotated segments are kept before deletion; accepts a d suffix for days. Unset keeps them indefinitely.
analytics:
log:
retention: 90d
analytics.ship
Type: object
Shipping of analytics segments to a remote store.
analytics.ship.interval
Type: string
Default: 30s
How often the shipper looks for completed segments to send.
analytics:
ship:
interval: 1m
analytics.ship.remote
Type: string
Default: none
Destination for shipped segments; none is the only supported value.
analytics:
ship:
remote: none
analytics.pipeline
Type: object
The in-process event pipeline that feeds the analytics log.
analytics.pipeline.enabled
Type: boolean
Default: false
Runs the event pipeline; leave unset to let analytics.enabled decide.
analytics:
pipeline:
enabled: true
analytics.pipeline.buffer
Type: integer
Default: 1024
Number of events the pipeline buffers before back-pressure applies; must be positive.
analytics:
pipeline:
buffer: 4096
analytics.shutdown_timeout
Type: string
Default: 10s
How long the server waits for buffered analytics events to flush on shutdown.
analytics:
shutdown_timeout: 30s
analytics.aggregations
Type: object
Pre-computed aggregates read by the dashboard.
analytics.aggregations.refresh_interval
Type: string
Default: 5m
How often aggregates are recomputed from the log.
analytics:
aggregations:
refresh_interval: 1m
analytics.aggregations.store
Type: string
Default: sqlite
Backend for aggregates: sqlite or file.
analytics:
aggregations:
store: file
analytics.index
Type: object
Indexing of analytics segments for queries.
analytics.index.workers
Type: integer
Default: 2
Number of concurrent indexing workers; must be positive.
analytics:
index:
workers: 4
analytics.history
Type: object
The commit journal that lets you inspect what agents wrote and when.
analytics.history.blobs
Type: boolean
Default: true
Stores the content of each committed write so history can show diffs.
analytics:
history:
blobs: false
analytics.history.retention
Type: string
Default: none
How long journal entries are kept; accepts a d suffix for days. Unset keeps them indefinitely.
analytics:
history:
retention: 365d
analytics.export
Type: object
Export of analytics to monitoring systems.
analytics.export.prometheus
Type: boolean
Default: true
Serves analytics counters on the metrics port alongside server metrics.
analytics:
export:
prometheus: false
mcp
The MCP-over-HTTP endpoint for clients such as Claude Code and Codex.
mcp.enabled
Type: boolean
Default: true
Serves the Streamable HTTP MCP endpoint on the HTTP server.
mcp:
enabled: false
mcp.path
Type: string
Default: /mcp
URL path the MCP endpoint is mounted at.
mcp:
path: /mcp
mcp.require_auth
Type: boolean
Default: none
Forces OAuth for the MCP endpoint and JSON API even when lore.json allows keyless access; requires tokens. Unset inherits the SSH posture.
mcp:
require_auth: true
api
The plain JSON HTTP API backed by the same MCP server.
api.enabled
Type: boolean
Default: true
Serves POST {path}/shell and GET {path}/commands on the HTTP server.
api:
enabled: false
api.path
Type: string
Default: /api
URL path the JSON API is mounted at.
api:
path: /api
auth
Transport-level authentication for the HTTP server.
auth.mtls
Type: object
Optional client-certificate corroboration for authenticated OAuth clients.
auth.mtls.ca_bundle
Type: string
Default: none
PEM CA bundle a presented client certificate must chain to; clients without a certificate can still connect. OpenLore must terminate TLS itself.
auth:
mtls:
ca_bundle: /etc/openlore/connectors-ca.pem
files
Which files in the content root are served.
files.allowed
Type: list of strings
Default: ["*.md", "*.markdown", "*.txt", "*.html", "*.htm", "*.css", "*.js", "*.json", "*.jsonl", "*.yaml", "*.yml", "*.csv", "*.tsv", "*.xml", "*.toml", "*.png", "*.jpg", "*.jpeg", "*.gif", "*.svg", "*.webp"]
Glob patterns a file name must match to be served; an empty list serves every file.
files:
allowed: ["*.md", "*.txt"]
files.denied
Type: list of strings
Default: none
Glob patterns that hide a file even when it matches files.allowed.
files:
denied: ["secret-*.md"]
files.ignore
Type: list of strings
Default: [".git/**", "node_modules/**", ".env*", "**/.DS_Store"]
Glob patterns matched against every path segment; a match hides the file or directory from listings.
files:
ignore: [".git", "node_modules", "*.key"]
passkeys
Browser passkey (WebAuthn) login for the dashboard.
passkeys.enabled
Type: boolean
Default: true
Lets people register a passkey from SSH and sign in to the dashboard with it.
passkeys:
enabled: false
passkeys.rp_id
Type: string
Default: none
WebAuthn relying-party ID, normally the public domain of the dashboard. Unset uses the host of the advertised HTTP origin.
passkeys:
rp_id: docs.example.com
passkeys.rp_name
Type: string
Default: OpenLore
Display name the browser shows in its passkey prompt.
passkeys:
rp_name: "Acme Docs"
passkeys.rp_origins
Type: list of strings
Default: none
Origins allowed to start WebAuthn ceremonies; must include external_url when both are set. Unset uses external_url, else the local http_port origin.
passkeys:
rp_origins: ["https://docs.example.com"]
passkeys.lore_path
Type: string
Default: /lore
URL path prefix for browsing content in the dashboard.
passkeys:
lore_path: /lore
passkeys.passkeys_file
Type: string
Default: ./config/passkeys.json
File that stores registered passkey credentials.
passkeys:
passkeys_file: /var/lib/openlore/passkeys.json
passkeys.session_ttl
Type: string
Default: 24h
How long a browser session lasts after passkey sign-in.
passkeys:
session_ttl: 8h
shellexec
External commands run around reads and writes by the built-in shellexec plugin. Each command receives the OPENLORE_* environment variables.
shellexec.pre_read
Type: list of objects
Commands run before a path is read, debounced per path.
shellexec.pre_read[].cmd
Type: string
Default: none
Command line run with sh -c.
shellexec:
pre_read:
- cmd: ./scripts/pull.sh
shellexec.pre_read[].timeout
Type: string
Default: 30s
Wall-clock limit for the command; a timeout counts as a failure.
shellexec:
pre_read:
- timeout: 10s
shellexec.pre_read[].fail_on_error
Type: boolean
Default: true
Aborts the read when the command exits non-zero.
shellexec:
pre_read:
- fail_on_error: false
shellexec.pre_read[].debounce
Type: string
Default: 2s
Window in which repeated reads of the same path run the command once.
shellexec:
pre_read:
- debounce: 5s
shellexec.pre_read[].async
Type: boolean
Default: false
Runs the command in the background; an async command cannot abort the read.
shellexec:
pre_read:
- async: true
shellexec.pre_commit
Type: list of objects
Commands run before a write is committed.
shellexec.pre_commit[].cmd
Type: string
Default: none
Command line run with sh -c.
shellexec:
pre_commit:
- cmd: ./scripts/lint.sh
shellexec.pre_commit[].timeout
Type: string
Default: 30s
Wall-clock limit for the command; a timeout counts as a failure.
shellexec:
pre_commit:
- timeout: 10s
shellexec.pre_commit[].fail_on_error
Type: boolean
Default: true
Rejects the write when the command exits non-zero.
shellexec:
pre_commit:
- fail_on_error: false
shellexec.pre_commit[].debounce
Type: string
Default: none
Accepted for symmetry with pre_read but ignored for pre-commit commands.
shellexec:
pre_commit:
- debounce: 2s
shellexec.pre_commit[].async
Type: boolean
Default: false
Runs the command in the background; an async command cannot reject the write.
shellexec:
pre_commit:
- async: true
shellexec.post_write
Type: list of objects
Commands run after bytes reach disk; they never halt the write.
shellexec.post_write[].cmd
Type: string
Default: none
Command line run with sh -c.
shellexec:
post_write:
- cmd: ./scripts/push.sh
shellexec.post_write[].timeout
Type: string
Default: 30s
Wall-clock limit for the command.
shellexec:
post_write:
- timeout: 60s
shellexec.post_write[].fail_on_error
Type: boolean
Default: true
Accepted for symmetry with pre_read but ignored, because a post-write command cannot undo the write.
shellexec:
post_write:
- fail_on_error: false
shellexec.post_write[].debounce
Type: string
Default: none
Accepted for symmetry with pre_read but ignored for post-write commands.
shellexec:
post_write:
- debounce: 2s
shellexec.post_write[].async
Type: boolean
Default: false
Runs the command in the background so the write returns before it finishes.
shellexec:
post_write:
- async: true
rules
Server-wide defaults for folder rules; the rules themselves live in lore.json and .lore/config.yaml.
rules.growth
Type: number
Default: 1.25
Multiplier applied to a file’s initial size for max: initial size rules; must be at least 1.
rules:
growth: 1.5
rules.tokenizer
Type: string
Default: none
Reserved for token-based size rules; any value is rejected until a tokenizer ships.
rules:
tokenizer:
tokens
The bearer-token issuer for the MCP endpoint and JSON API. The ES256 signing key is generated under data_dir/auth/ on first start.
tokens.issuer
Type: string
Default: none
Value of the iss claim and base URL for /.well-known/jwks.json.
tokens:
issuer: https://docs.example.com
tokens.audience
Type: string
Default: none
Required aud claim; one value per server.
tokens:
audience: https://docs.example.com
tokens.access_ttl
Type: string
Default: 1h
Lifetime of an access token.
tokens:
access_ttl: 15m
tokens.refresh_ttl
Type: string
Default: 720h
Lifetime of a refresh token.
tokens:
refresh_ttl: 168h
oidc_issuers
External identity providers whose JWTs can be exchanged for OpenLore tokens (workload identity federation).
oidc_issuers[].issuer_url
Type: string
Default: none
Value the iss claim of an exchanged JWT must equal.
oidc_issuers:
- issuer_url: https://token.actions.githubusercontent.com
oidc_issuers[].jwks
Type: object
How the issuer’s public keys are obtained.
oidc_issuers[].jwks.mode
Type: string
Default: discovery
discovery reads keys from the issuer’s .well-known/openid-configuration; url fetches a JWKS document from url.
oidc_issuers:
- jwks:
mode: url
oidc_issuers[].jwks.url
Type: string
Default: none
URL of the JWKS document; required when mode is url.
oidc_issuers:
- jwks:
url: https://spire.example/keys
inbox
HTTP uploads into a docset inbox with a revocable credential.
inbox.max_upload_size
Type: string
Default: 10MB
Largest upload accepted, as a byte size.
inbox:
max_upload_size: 25MB
inbox.allowed_types
Type: list of objects
File types the inbox accepts. Each entry maps extensions to the MIME type the upload must declare.
inbox.allowed_types[].extensions
Type: list of strings
Default: [".md", ".markdown"]
File extensions, including the leading dot, that this entry covers.
inbox:
allowed_types:
- extensions: [".m4a"]
inbox.allowed_types[].mime
Type: string
Default: text/markdown
MIME type an upload with one of these extensions must declare.
inbox:
allowed_types:
- mime: audio/mp4
plugins
Settings for built-in plugins.
plugins.skills
Type: object
The skills plugin, which serves routines to agents.
plugins.skills.enabled
Type: boolean
Default: false
Serves skills from skills_dir and remote skill references.
plugins:
skills:
enabled: true
plugins.skills.remote_check_ttl
Type: string
Default: 60s
How long a fetched remote skill is cached before it is checked again.
plugins:
skills:
remote_check_ttl: 5m
plugins.skills.remote_timeout
Type: string
Default: 3s
Time limit for fetching one remote skill.
plugins:
skills:
remote_timeout: 10s
plugins.skills.remote_max_bytes
Type: string
Default: 10MB
Largest remote skill document accepted, as a byte size.
plugins:
skills:
remote_max_bytes: 1MB