Obsidian Email SecurityDocumentation Sign in

Settings

Manage › Settings (MSP administrators) holds platform-wide configuration. Each section has its own Save button. Changes reach every service within about 10 seconds; saving General, Mail flow or Spamhaus also re-applies the Postfix configuration automatically.

Secret fields (the Spamhaus key) show set when stored. Leave blank to keep the stored value; enter a single - to clear it.

General

Product name shown to usersgeneral.brand_name
Name shown in the console header, browser titles, digest emails and the authenticator app entry. Change it to white-label Obsidian Email Security for your clients. Default: Obsidian Email Security
Gateway hostname (HELO / MX target)general.hostname
The gateway's fully-qualified host name. Used as the Postfix HELO / banner name, in Authentication-Results headers and in every setup instruction (MX targets, smart hosts). It must resolve in public DNS to the gateway and match the TLS certificate. Saving re-syncs Postfix (myhostname) automatically; values without a dot are ignored by Postfix. Default: obsidian.local
Gateway public IPsgeneral.public_ips
The public IP address(es) mail leaves and arrives from. Only used to fill in setup instructions (M365 inbound connector IP restriction, Google inbound gateway list, SPF records). One per line. List. Default: (none)
Administrator alert addressgeneral.admin_email
Where the gateway's own system mail goes: everything addressed to root, postmaster or any other account on the machine (cron job output, failed sudo attempts, bounces of the gateway's own mail). Without it that mail cannot be delivered: the gateway's mail name is not a domain it accepts mail for, so it would bounce as a loop. Use an address on one of your own domains, such as a shared mailbox for the administrators. The internet still cannot send mail to the gateway's name. Saving re-syncs Postfix. Default: (empty)
Time zonegeneral.timezone
IANA time zone (e.g. America/Chicago), picked from a list grouped by region. It drives the clock and date at the top of every console page, every timestamp in the console, and the digest schedule (digest hours are local to this zone). The clock keeps ticking in this zone whatever time zone the viewer's own computer is in. Default: America/Chicago

Mail flow

Maximum message size (MB)smtp.max_message_size_mb
Largest message Postfix accepts, in MB. Larger messages are refused at SMTP time with a 552 error. Saving re-syncs Postfix. Default: 50
Outbound relay clientssmtp.relay_clients
IP addresses / CIDR ranges allowed to relay OUTBOUND mail through the gateway: your on-premises Exchange servers, and - when a Microsoft 365 or Google tenant sends outbound through Obsidian Email Security - that platform's sending ranges. Relay is only granted for envelope senders in domains that have 'Allow outbound relay' on, and these hosts skip the postscreen DNSBL test. Pair shared-platform ranges with a per-domain relay key. List. Default: (none)
Reject unknown recipientssmtp.reject_unknown_recipients
When on, RCPT TO for an address that is not a known user or alias is rejected (550 5.1.1) - but only for domains with 'Reject unknown recipients' enabled. Requires a directory sync so the user list is complete. Checkbox. Default: on
Trusted internal networkssmtp.internal_networks
LAN address ranges (CIDR, one per line) of your own servers that send mail as your domains - web servers' cron jobs, applications, scanners/copiers, monitoring. Their mail is still virus, attachment, link and content scanned, but skips SPF/DKIM/DMARC, the internal-domain spoof check, impersonation and AI review (those only make sense for internet senders). Typical value: 192.168.0.0/16 and 10.0.0.0/8. Only list ranges internet mail can never appear from - check that your router does not masquerade inbound connections (a message from an internet sender must show its real public IP in Message trace). List. Default: (none)

Spamhaus

Enable Spamhaus checksspamhaus.enabled
Master switch for all Spamhaus lookups (ZEN in postscreen and in the scanner, DBL, ZRD, HBL). Checkbox. Default: on
Data Query Service keyspamhaus.dqs_key
Your Spamhaus Data Query Service key. With a key Obsidian Email Security queries <key>.zen.dq.spamhaus.net etc. and enables ZRD and HBL; postscreen switches to the DQS zone automatically and the key is hidden from SMTP replies. Without a key the free public mirrors are used, which are licensed for non-commercial, low-volume use only. Enter '-' to clear a stored key. Secret. Default: (empty)

Antivirus (ClamAV)

Enable ClamAVclamav.enabled
Master switch for antivirus scanning. Checkbox. Default: on
clamd socketclamav.socket
Where clamd listens: a Unix socket path (default /var/run/clamav/clamd.ctl) or host:port for a remote clamd. Default: /var/run/clamav/clamd.ctl
Largest message to scan (MB)clamav.max_scan_mb
Messages larger than this are not sent to ClamAV (rule AV_TOO_LARGE is recorded instead). Keep it at or below clamd's StreamMaxLength (100 MB as installed). Default: 60
When clamd is downclamav.fail_action
What happens when clamd cannot be reached. 'tempfail' (recommended) answers 451 so the sending server retries later - nothing is lost and nothing unscanned gets through. 'accept' delivers unscanned mail with an X-Obsidian-Error header. One of: tempfail, accept. Default: tempfail

AI analysis

Enable AI analysisllm.enabled
Master switch for AI analysis. When off, no message is ever held for the model and policies' AI settings are ignored. Checkbox. Default: on
Ollama endpointllm.endpoint
Base URL of the Ollama server (e.g. http://192.168.6.195:11434). The gateway must be able to reach TCP 11434 on it. Default: http://192.168.6.195:11434
Modelllm.model
Exact Ollama model name (as listed by `ollama list`). System health shows whether it exists and is resident in memory. Default: qwen3.6:35b-a3b
Background review timeout (s)llm.timeout_seconds
How long the background worker waits for one AI review. CPU-only hosts need generous values (240 s default). Default: 240
Inline (SMTP-time) timeout (s)llm.inline_timeout_seconds
Maximum time a policy in 'inline' AI mode may hold the SMTP connection waiting for the model. If exceeded the rule verdict is used. Default: 20
Context window (tokens)llm.num_ctx
Context window passed to Ollama. The dossier Obsidian Email Security sends is small (usually 500-1500 tokens); 4096 leaves ample room. Default: 4096
Body characters sent to the modelllm.max_body_chars
How much of the message body is included in the AI dossier. Prompt processing dominates CPU inference time, so smaller is faster. Default: 3500
Parallel requestsllm.concurrency
Parallel AI requests from the worker. Match OLLAMA_NUM_PARALLEL on the model host (1 on lsllm1); more than the host allows just queues. Default: 1
Score weightllm.weight
Multiplier applied to the score the AI verdict contributes. 1.0 = default; lower it to make the model advisory, raise it to let the model dominate. Default: 1.0

Bayesian learning

Enable Bayesbayes.enabled
Master switch for the Bayesian filter. Checkbox. Default: on
Messages of each class before Bayes scoresbayes.min_messages
Bayes stays silent until both the spam and the ham corpus have at least this many trained messages - an undertrained filter does more harm than good. Default: 50
Auto-learn from confident verdictsbayes.autolearn
Automatically train on confident outcomes: quarantined or rejected mail that scored at least the autolearn spam score or that a confident AI called bad, as spam; delivered clean mail that a confident AI called clean, or that scored at most the autolearn ham score from a DMARC-passing sender, as ham. See Learning in the docs. Checkbox. Default: on

Retention

Message log (days)retention.log_days
How long message records (the trace) are kept for mail that belongs to no organization - each organization keeps its mail as long as its plan says (Settings > Plans). Older records and their raw copies are deleted by the retention job (runs every 6 hours). Default: 90
Quarantine (days)retention.quarantine_days
Quarantined and held messages older than this expire (mail of no organization; organizations follow their plan, Settings > Plans): the raw copy is deleted and their status becomes 'expired'. Default: 30
Raw copy of delivered mail (days)retention.raw_clean_days
How long a raw copy of DELIVERED mail is kept. Needed for clawback, 'Report spam' training and async AI review. 0 = keep raw copies only for quarantined mail. Default: 3

Plans

Trial of Complete for new organizations (days)plans.trial_days
How long a newly created organization gets the Complete plan for free. After that it counts as Essentials until a superadmin picks a plan on the organization page. Default: 30
Essentials keeps mail (days)plans.retention_days_essentials
How long an organization on Essentials keeps its message history and quarantine. Replaces the global message-log and quarantine days for that organization. Default: 30
Complete keeps mail (days)plans.retention_days_complete
How long an organization on Complete (or in its trial) keeps its message history and quarantine. Replaces the global message-log and quarantine days for that organization. Default: 90

Quarantine digests

Send digestsdigest.enabled
Master switch for quarantine digest emails. Checkbox. Default: on
Send at hours (local time)digest.hours
Local hours (0-23, comma separated) at which digests go out, e.g. 8, 16. Each user receives only messages not included in an earlier digest. List. Default: 8, 16
From addressdigest.from_address
Sender address of digests and sign-in links. Default quarantine@<hostname>. Use an address your tenants will not treat as spoofed. Default: (empty)

TLS certificate (Let's Encrypt)

Certificate hostnamestls.names
Host names the certificate covers, one per line - typically the MX host (e.g. mx1.obsidiansuite.net) and the console name if it differs (e.g. portal.obsidiansuite.net). Empty = just the gateway hostname. Wildcards (*.example.com) need the Cloudflare method. List. Default: (none)
Let's Encrypt contact emailtls.email
Contact address registered with Let's Encrypt; it receives expiry warnings if automatic renewal ever fails. Default: (empty)
Validation methodtls.method
How Let's Encrypt verifies you control the names. 'cloudflare' (recommended when the domain's DNS is on Cloudflare) creates a temporary TXT record through the Cloudflare API - the gateway does not need to be reachable from the internet. 'http' serves a file on port 80, so the names must already point at the gateway and TCP 80 must be forwarded to it. One of: cloudflare, http. Default: cloudflare
Cloudflare API tokentls.cloudflare_token
A Cloudflare API token with Zone > DNS > Edit permission, limited to the zone(s) of the certificate names. Stored encrypted; only the root certificate helper can read it back. Enter '-' to clear. Default: (empty)
Use the Let's Encrypt staging server (testing)tls.staging
Use Let's Encrypt's staging server: certificates are not trusted by browsers or mail servers, but there are no rate limits. Use it to test a new setup, then untick it and request again for a real certificate. Checkbox. Default: off

Security

Session length (hours)security.session_hours
How long a sign-in lasts before the user must sign in again. Default: 12
Require MFA for administratorssecurity.require_mfa_admins
When on, administrators who have not enrolled two-factor authentication are sent to the enrolment page right after signing in. (SSO sign-ins are exempt - enforce MFA in Entra ID / Google instead.) Checkbox. Default: off
Failed logins before lockoutsecurity.max_failed_logins
Consecutive failed password attempts before the account is locked. Default: 8
Lockout (minutes)security.lockout_minutes
How long a locked account stays locked. An administrator saving the user record clears the lock immediately. Default: 15
Allow email sign-in links for userssecurity.magic_link_login
Lets end users (role 'user') request a one-time sign-in link by email instead of a password. Links expire after 15 minutes and require a click on a confirmation page. Checkbox. Default: on

Secure messages

Allow encrypted messages to anyone (portal /s/...)secure.enabled
Lets a mail client (with an API token) send a message encrypted to anyone: the recipient gets a link, proves their address with an emailed one-time code and reads it here. The message is encrypted in the sender's client and the key is only in the link's #fragment, which browsers never send - this server stores it without being able to read it. Replies are encrypted the same way. Off: the portal and its API answer 404. Checkbox. Default: on
Longest a secure message stays openable (days)secure.max_days
How long at most a secure message can be opened (the client asks for 1 to this many days; default 30). Expired and withdrawn messages lose their encrypted data within a day (retention job). Default: 90

Reputation

Enable cross-tenant reputationreputation.enabled
Master switch for cross-tenant reputation: the reputation stage (REP_* rules), the evidence it collects and the scorer. Off: no lookups, no new evidence; stored scores stay until retention removes them. Checkbox. Default: on
Organizations needed to pass the capreputation.min_tenants
How many different organizations must contribute strong evidence (AI verdicts) before an entity's score may go above the cap. Stops one client's reports from blocking a sender for everyone. An administrator's confirmed report or clawback lifts the cap at once. Default 2 while you have fewer than about 10 organizations; raise it to 3 then. Default: 2
Score cap with fewer organizationsreputation.single_tenant_cap
Highest score evidence from fewer organizations than the minimum can reach (default 40 = 'suspicious', never 'bad' on its own). Default: 40
Points for a suspicious entity (30-59)reputation.points_suspicious
Points REP_SUSPICIOUS adds to a message when one of its entities scores 30-59. Default: 2.5
Points for a bad entity (60-84)reputation.points_bad
Points REP_BAD adds when an entity scores 60-84. The default 8 equals the default quarantine threshold, so a bad entity quarantines the message on its own. Default: 8.0
Points for a malicious entity (85-100)reputation.points_malicious
Points REP_MALICIOUS adds when an entity scores 85-100 or an administrator blocked it. The default 12 quarantines; it rejects only together with other evidence (reject threshold 15). Default: 12.0
AI confidence needed for evidencereputation.llm_min_confidence
An AI verdict of phish, BEC, malware or scam (or spam) becomes reputation evidence only at this confidence or above (0-1, default 0.85). Every verdict is still recorded for model comparison. A clean verdict never changes a score. Default: 0.85
Keep evidence (days)reputation.evidence_days
How long evidence and recorded AI verdicts are kept (default 180 days). Scores fade long before that through each evidence type's half-life. Default: 180
Never-scored domainsreputation.protected_domains
Domains that are never scored, one per line, on top of the built-in list: free-mail providers, URL shorteners, the real domains of well-known brands, sending platforms and their link domains, and every domain of your organizations. List. Default: (none)
Extra shared sending rangesreputation.protected_ranges
IP ranges (CIDR, one per line) that are never scored, on top of the sending ranges the gateway reads every day from the published SPF records of Microsoft 365, Google, Amazon SES, SendGrid, Mailgun, Mailchimp and other platforms. List. Default: (none)
Look up registration dates (RDAP)reputation.rdap_enabled
Look up when domains new to the network were registered, through each registry's public RDAP service (the successor to WHOIS). Only domains first seen in the last 7 days or already carrying a score are looked up, a few per minute. Needs outbound HTTPS from the gateway to data.iana.org and the registries' RDAP servers. Checkbox. Default: on
RDAP lookups per minutereputation.rdap_per_minute
Most RDAP lookups the worker makes per minute (default 15). Registries rate-limit; a server that answers 'too many requests' is skipped until the next minute. Default: 15
Clean history that earns trust (days)reputation.trust_history_days
Trust is the only evidence that lowers a score: a sender domain with DMARC-aligned mail judged clean for at least this many days (default 90) before its first bad evidence gets the dmarc_history weight (-15). It never comes from the AI. Default: 90
... on at least this many daysreputation.trust_min_aligned_days
...and that aligned, clean mail must have arrived on at least this many different days (default 10), so one old message does not count as a history. Default: 10
Fingerprint confirmed bad messagesreputation.fuzzy_enabled
When an administrator reports a message as spam or claws it back, keep a fingerprint of its text: 32 hash values keyed with the server's secret, never the text. New mail whose text matches scores REP_FUZZY, and its links, domains and attachments get fuzzy_match evidence, so a re-sent campaign with fresh links is caught. 'Not spam' removes the fingerprint; Protect > Reputation lists and removes them. Checkbox. Default: on
Fingerprint match thresholdreputation.fuzzy_threshold
How much of a fingerprint must agree for a match (0-1, default 0.6). The share of agreeing values estimates the share of shared word triples, so 0.6 means clearly the same message with some words changed. Lower catches more variants and risks unrelated mail with shared boilerplate. Default: 0.6
Points for a fingerprint matchreputation.points_fuzzy
Points REP_FUZZY adds, multiplied by the similarity (default 9: a 90% match adds 8.1, which quarantines on its own at the default threshold; a 60% match adds 5.4). Default: 9.0

Advanced settings (command line)

A few rarely-changed values are not on the page. Set them with obsidian-admin set KEY VALUE (value in JSON; see Command line):

spamhaus.zones
Which Spamhaus lists are queried, e.g. {"zen": true, "dbl": true, "zrd": true, "hbl": true} (not on the Settings page). Turn one off to stop its lookups; ZRD and HBL only work with a DQS key anyway.Default: {'zen': True, 'dbl': True, 'zrd': True, 'hbl': True}
llm.temperature
Sampling temperature for the model (not on the Settings page; set with obsidian-admin). Keep it low (0.1) for consistent verdicts.Default: 0.1
bayes.autolearn_spam_score
Score at or above which a message is auto-learned as spam (not on the Settings page; default 15).Default: 15.0
bayes.autolearn_ham_score
Clean, delivered mail at or below this score whose sender passed DMARC is auto-learned as ham (not on the Settings page; default 1.0). Was -2 before 0.1.41, which ordinary clean mail never reached.Default: 1.0
bayes.autolearn_ai_confidence
An AI verdict at least this confident teaches Bayes when the outcome agrees: clean and delivered = ham; spam, phishing, BEC, scam or malware and quarantined / rejected = spam (not on the Settings page; default 0.85).Default: 0.85
digest.include_admin_only
Whether admin-only items (viruses, malware, phishing) are listed in users' digests (without release links). Off by default (not on the Settings page).Default: False

The default policy is edited on Policies, not here.

Server-only configuration

/etc/obsidian/obsidian.toml holds what must exist before the database is reachable. Edit it as root and restart the three obsidian services.

database_url
PostgreSQL connection (written by the installer).
secret_key
Signs sessions, digest and sign-in links. Changing it signs everyone out and invalidates all outstanding links.
data_key
Encrypts connector secrets, DKIM keys and TOTP secrets. Never change it on a running system; back it up.
data_dir
Where the quarantine store lives (default /var/lib/obsidian).
postfix_map_dir
Where Postfix routing tables are written (/var/lib/obsidian-maps).
dns_resolver
Resolver for scanning lookups, normally the local unbound 127.0.0.1:5335.
public_url
Console address used in digest and sign-in links.
setup_code_file
Where the first-run setup code is (default /etc/obsidian/setup-code; see Installation & setup). Earlier versions had a setup_token here; the installer removes it.
web_host, web_port, milter_socket, reinject_host, reinject_port
Internal listeners (127.0.0.1:8440 web, 127.0.0.1:11332 milter, 127.0.0.1:10026 re-injection). Change only together with the systemd units / Postfix configuration.