Installation policies
On this page
Admin Console → Installation policies with managed services, Settings → General on the open-source build. Platform admin only.
Values that decide things for the whole installation. Each one used to be an environment variable and is now a column on the single platform_settings row the two-factor mandate already used, so changing one is a form and an audit row rather than a redeploy. A saved change takes effect within about ten seconds.
The page groups the fields in three blocks. The defaults are the values the old environment variables shipped with.
| Group | Field | What it decides | Default |
|---|---|---|---|
| General | Public address of the engine | The origin external services use to reach the engine. Every webhook URL, OAuth redirect and agent card is built from it, so a wrong value is a webhook that never arrives. Origin only, with no path and no trailing slash. | BASE_URL |
| General | Analytics retention (days) | How far back the daily housekeeping keeps ai_logs and pipeline_traces | 90 |
| Limits | Live streams in total | Concurrent activity-stream subscribers the process holds across all users; the rest get 503 | 50 |
| Limits | Live streams per user | Concurrent activity-stream subscribers one authenticated user may hold; the rest get 503 | 5 |
| Limits | Rate-limit window (ms) | The window the request limit is counted over. Routes that declare their own limit keep it. | 60000 |
| Limits | Requests per window | How many requests one caller may make per window before the API answers 429 | 30 |
| Timeouts | Agent-to-agent call (ms) | How long one agent waits for another it invoked before the call comes back as an error | 60000 |
| Timeouts | MCP connection (ms) | How long an external MCP server has to connect and list its tools. Past it the server is skipped for that turn. | 10000 |
| Timeouts | Orphaned-run grace (ms) | How long a scheduled run left behind by a dead process is left alone before it is recovered | 900000 (15 minutes) |
| Timeouts | Default run deadline (ms) | The deadline for a scheduled task that declares none of its own. Past it the run is marked failed. | 1800000 (30 minutes) |
| Timeouts | Conversations list query (ms) (managed services) | How long the conversations list may spend in the database before it is cancelled. Between 1000 and 120000. | 15000 |
| Timeouts | Dev-mode tool call (ms) (managed services) | How long the dev-mode bridge waits for a developer’s machine to answer one tool call | 30000 |
| Timeouts | Dev token lifetime (hours) (managed services) | Default life of a new dev token when the request names none. At most 24. | 8 |
THROTTLE_ENABLED is not here, and stays an environment variable: it exists for parallel local runs, and a rate limiter that could be switched off from inside the product is no use to an administrator it has locked out.
The public address is the one field with an environment variable behind it. BASE_URL is what a fresh installation boots with, because the engine has to name itself before anyone has opened the panel. Once an address is stored here, it wins.
Why platform admin only, and not a permission
Every field decides for every organization at once. A grantable right to change them would let one tenant’s administrator shorten another tenant’s history or exhaust the installation’s capacity - which is why they sit beside the two-factor mandate under the same platformAdminOnly gate rather than in the permission taxonomy.
An empty field is not zero
Empty means the installation declares nothing and the shipped default applies, which is why the placeholder shows the value in force rather than the field being pre-filled with it. Clearing a field hands the value back to that default. For the public address, the default is BASE_URL.
The old environment variables are not read any more, even as a default. A deployment that still sets one gets a warning at boot naming where the value is set now, and the value has no effect. If you had set one to something other than its default, type the same value here. See Upgrading.
Shortening the retention window deletes history
The next housekeeping run deletes everything older than the new window, and there is no undo. The change is recorded in the management audit trail (platform_settings.update) with the actor and the fields changed, because the row itself keeps only the current value and is overwritten by the next change.
Read the window before trusting an old analytics query: see Analyse production traffic.
Outbound mail
Managed services. Outbound mail ships in the managed-services build.
Admin Console → Installation policies also holds the installation’s mailer, which was seven environment variables until it became six columns on the same row plus one encrypted secret. The old variables are not read as a fallback: an installation upgraded from them has no mailer until a platform admin enters one here.
| Field | What it is |
|---|---|
| SMTP host, port, implicit TLS | Your relay. Port defaults to 587; implicit TLS belongs to port 465 only, and everything else starts plain and upgrades with STARTTLS. |
| Username, password | Leave both empty for a relay that needs no authentication. Set a username and the password becomes required - a user that authenticates as nothing is a mailer that could never have worked. |
| Sender | The address recipients see. It must be one the relay is allowed to send as, which is the usual reason mail configures cleanly and then bounces. |
| Panel origin | The public origin of this panel, not of the engine. Every emailed link points at a panel page (/invitations/accept, /reset-password), so the engine’s own address mints links that do not open. |
The mailer is saved whole, or not at all. The host, the sender and the panel origin are refused unless all three are present. That refusal used to happen at boot - the engine would not start with a half-configured mailer - and it happens on save now, where there is somebody to read it.
The password is written and never read back. It is stored encrypted in its own table, so opening this page cannot disclose it: the field says whether one is stored, an empty field keeps the current one, and typing replaces it. Remove mailer clears everything including the password. A new password is used from the next message on, with no engine restart.
No mailer is a supported state. An invitation still returns a shareable link and reports emailSent: false, and a password-reset request logs an error instead of sending. What never happens is a silent no-op.
Every write leaves a management-audit row (platform_mail.update) - its own action rather than a settings change, because whoever sets the relay decides where password-reset links are delivered, and that link is the credential.
One mailer for the installation, not one per organization. A tenant sending from its own domain needs SPF and DKIM and a verified-sender flow; without them the mail lands in spam or is refused, which is worse than not offering the field. The organization an invitee is joining is named in the subject and the body of the invitation, which is what they need to know.