Quickstart
This quickstart uses a local server deployment directory, bootstraps one SMTP account, and shows the composed config.
Install
Create a virtualenv and install Arbiter from pip. The virtualenv keeps
the server, client (arbiter-client), and plugin packages isolated from your
system Python.
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install arbiter-suite
The PyPI package arbiter is unrelated to Arbiter. Install
arbiter-suite for the default Arbiter bundle, or install packages such
as arbiter-server, arbiter-client, arbiter-smtp, and arbiter-imap
explicitly.
Use the virtualenv commands directly, or activate it before running examples. For agent skill and standalone client installation, see Installing Arbiter Client.
Security boundary
Arbiter only helps if agents cannot change the deployment and cannot reach the protected service another way. Keep config, credentials, plugins, and startup scripts operator-owned, and do not give agents direct service access.
Before production use, read Security Model and Configuration Model.
Create config
Keep server-owned config in a deployment directory. This quickstart uses
./arbiter-server/conf for YAML config and ./arbiter-server/.arbiter.env
for local environment values:
export ARBITER_DEPLOY_DIR="./arbiter-server"
export ARBITER_CONFIG_DIR="$ARBITER_DEPLOY_DIR/conf"
Pass --config-dir <dir> before the subcommand when targeting that server
deployment directory.
Arbiter config is built with Hydra and OmegaConf. For how the defaults list, config groups, schemas, interpolation, and command-line overrides fit together, see Configuration Model.
Bootstrap the Arbiter server config once per installation. This creates the root server config and the plugin activation file. Plugin-owned account and policy config is bootstrapped separately when you configure that plugin for the first time.
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" bootstrap --server
# wrote ./arbiter-server/conf/arbiter-server.yaml
# wrote ./arbiter-server/conf/plugins.yaml
Add an SMTP account template and its matching policy:
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" bootstrap --plugin smtp --account bot
# wrote ./arbiter-server/conf/arbiter/account/smtp/bot.yaml
# wrote ./arbiter-server/conf/arbiter/policy/smtp/bot_policy.yaml
Edit the generated files:
./arbiter-server/conf/arbiter/account/smtp/bot.yaml
./arbiter-server/conf/arbiter/policy/smtp/bot_policy.yaml
Show generated config shape
The root config selects the server schema, plugin activation file, and server defaults:
defaults:
- arbiter_app_config_schema
- plugins
- _self_
arbiter:
env_file: ../.arbiter.env
server:
name: arbiter
transport: https
bind:
host: 127.0.0.1
port: 8075
path: ""
tls:
source: SELF_SIGNED
deployment_scope: unknown
discovery:
max_account_preview_limit: 25
max_operation_preview_limit: 25
Activating accounts updates the plugin activation file:
defaults:
- arbiter/account:
- smtp/bot
- arbiter/policy:
- smtp/bot_policy
- _self_
The account file extends the plugin-owned schema and uses OmegaConf interpolation for secrets:
defaults:
- /arbiter/account/smtp/schema@_here_
- _self_
policy: bot_policy
host: ${oc.env:SMTP_BOT_ACCOUNT_HOST}
port: ${oc.env:SMTP_BOT_ACCOUNT_PORT,587}
authenticate: true
username: ${oc.env:SMTP_BOT_ACCOUNT_USERNAME}
password: ${oc.env:SMTP_BOT_ACCOUNT_PASSWORD}
from_email: agent@example.com
from_name: Arbiter
tls: starttls
verify_peer: true
timeout_seconds: 30
The generated file keeps deployment-specific connection values in the env file by default. You can edit the YAML directly when a fixed value is clearer for your local setup.
After editing, include the account in the composed config:
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" config activate --plugin smtp --account bot
# updated ./arbiter-server/conf/plugins.yaml
Inspect the composed config:
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" config show
arbiter:
server:
name: arbiter
transport: https
bind:
scheme: https
host: 127.0.0.1
port: 8075
path: ""
public:
scheme: https
tls:
source: SELF_SIGNED
account:
smtp:
bot:
policy: bot_policy
host: ${oc.env:SMTP_BOT_ACCOUNT_HOST}
port: ${oc.env:SMTP_BOT_ACCOUNT_PORT,587}
username: ${oc.env:SMTP_BOT_ACCOUNT_USERNAME}
password: ${oc.env:SMTP_BOT_ACCOUNT_PASSWORD}
policy:
smtp:
bot_policy:
recipient_policy:
allowed_domain_patterns:
- example.com
Environment values
Generated account configs keep secrets out of YAML by referencing environment
variables with ${oc.env:...}. Arbiter does not own those secrets, but it
can help you prepare and check the env file named by the server config. In this
deployment layout, arbiter.env_file: ../.arbiter.env resolves from
./arbiter-server/conf to ./arbiter-server/.arbiter.env.
Use env bootstrap when the config changed and you want the local env file to
catch up:
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" env bootstrap
This scans the composed config for ${oc.env:...} references, creates
./arbiter-server/.arbiter.env if needed, and adds any missing variables
without replacing existing values. After it runs, open that file and fill in the
blank secret values.
Use env check before starting the server, or after editing the env file:
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" env check
This verifies that every ${oc.env:...} reference in the composed config is
available from either the env file or the process environment. If anything is
missing, it prints the variable names and the plugin block they came from.
Run
Validate, then start the server:
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" config check
arbiter-server --config-dir "$ARBITER_CONFIG_DIR" serve
In another terminal, point the Arbiter client at the local server:
arbiter info server arbiter.url=https://127.0.0.1:8075
arbiter plugins smtp arbiter.url=https://127.0.0.1:8075