The desk's configuration
The shortest useful file, and the one key that catches everybody.
The wizard does this for you. This page is what it does, for when you would rather do it yourself.
nils-desk serve --config nils-desk.toml. The repository ships nils-desk.example.toml with every key commented; the shortest useful file is:
bind = "127.0.0.1:7200"
origin = "http://127.0.0.1:7200"
mode = "off"
store = "nils-desk.sqlite"
[engine]
url = "http://127.0.0.1:8437"
origin is not bind
bind is the address the desk listens on. origin is the address a browser reaches it at, and every write is checked against it. Get it wrong and the desk refuses your own requests with “the request’s Origin is not this desk”.
Behind a reverse proxy, origin is the public URL:
bind = "127.0.0.1:7200"
origin = "https://nils.example.org"
The session cookie is marked Secure when the origin is https, so a public desk must be https end to end.
also_origins, when the same desk has two addresses
A desk on a laptop is often reached both at 127.0.0.1 and at the machine’s own address on the wifi. Name the others and both work; what the desk advertises, mints and redirects to is always origin.
also_origins = ["http://192.168.1.20:7200", "http://localhost:7200"]
The engine
[engine]
url = "http://127.0.0.1:8437"
# token = "..." # only when the engine runs with --auth token
In off mode the desk holds no token and the engine has no login. In token mode the desk holds one, and a browser never sees it. In local and oidc modes the desk sends a token it signs for the person, with their grants and detail, so the engine knows who is asking and the audit says so.
The rest
[kvasir]
url = "http://127.0.0.1:7100" # the model gateway, when you have one
[assistant]
url = "http://127.0.0.1:7300" # the assistant, when you have one
[supervisor]
url = "http://127.0.0.1:8470" # the updater on this host, when you run one
Each is optional. A part that is absent is absent from the desk as well; nothing is shown that is not there.
Exporting, and apps of your own
export = "query:work"
[[apps]]
id = "pipelines"
title = "Analysis pipelines"
url = "http://127.0.0.1:7400"
entitlement = "pipelines:work"
export is what downloading a result needs: a grant, or an old name such as reader standing for its set. off turns exporting off, and unless set it is query:work.
Each [[apps]] table is a web application of yours that the desk serves under /apps/{id}/, with the person’s token and the desk’s own defences, to a person who holds its entitlement: a grant, or an old name standing for its set. Groups and grants lists both.
Next: pick your mode. One machine, no login, the desk keeps the people, or an identity provider.
Updated 15 September 2026