Skip to main content

Configuration Overview

Trident PRISM is configured via a single TOML file. By default, PRISM looks for the configuration at /etc/prism/config.toml. You can override this with the -c flag:

prism -c /path/to/config.toml

Format and Safety

PRISM uses TOML as its configuration format. Every section uses deny_unknown_fields, which means any typo or unrecognized key will cause a startup error instead of being silently ignored. This catches misconfigurations early.

Validation

On startup, PRISM validates the configuration:

  • render.pool.tabs must be greater than 0
  • render.timeout_secs must be greater than 0
  • render.wait_for must be one of load, domcontentloaded, networkidle, or selector:<css-selector>
  • server.origin must not point to PRISM's own listen address (prevents infinite render loops)
  • Enum fields (server.mode, logging.level, logging.format) are validated during deserialization

All sections are optional and have sensible defaults. An empty config file is valid.

Full Example Configuration

[server]
address = "127.0.0.1:4000"
origin = "http://localhost:3000"
mode = "bot-only"
shadow = false
drain_timeout_secs = 30
proxy_timeout_secs = 30
trusted_proxies = []
max_connections = 10000

[render]
wait_for = "load"
timeout_secs = 10
block_resources = ["font", "image", "media", "stylesheet"]
status_from_meta = false
fail_on_console_errors = false
min_html_size = 512
# post_wait_js = "document.querySelector('.lazy')?.classList.remove('hidden')"

[render.pool]
tabs = 8
max_renders_per_tab = 50
queue_max = 100

[render.circuit_breaker]
failure_threshold = 5
recovery_timeout_secs = 30
half_open_max_requests = 1

[render.postprocess]
enabled = true
strip_scripts = true
strip_noscript = true
strip_comments = true
strip_event_handlers = true
strip_hydration_attrs = true
resolve_lazy_images = true

[render.viewport]
enabled = false
mobile_width = 412
mobile_height = 915
desktop_width = 1920
desktop_height = 1080

[render.content_validation]
enabled = true
min_text_length = 100
require_title = true
min_html_bytes = 1024

[cache]
enabled = true
max_entries = 10000
max_memory_bytes = 268435456
default_ttl_secs = 3600
grace_period_secs = 300
strip_query_params = ["utm_*", "fbclid", "gclid", "msclkid", "_ga"]
error_ttl_secs = 30
skip_authenticated = true
synthesize_cache_control = true

[[cache.rules]]
pattern = "/blog/**"
ttl_secs = 86400

[[cache.rules]]
pattern = "/products/**"
ttl_secs = 7200

[routes]
include = ["/**"]
exclude = [
"/api/**",
"/graphql",
"**/*.js",
"**/*.css",
"**/*.json",
"**/*.xml",
"**/*.png",
"**/*.jpg",
"**/*.gif",
"**/*.svg",
"**/*.ico",
"**/*.woff",
"**/*.woff2",
"**/*.ttf",
"**/*.wasm",
"**/*.map",
"/_next/**",
"/static/**",
"/admin/**",
]

[bot]
patterns = [
"Googlebot",
"bingbot",
"Baiduspider",
"YandexBot",
"DuckDuckBot",
"Slurp",
"Applebot",
"GPTBot",
"ClaudeBot",
"facebookexternalhit",
"Twitterbot",
"LinkedInBot",
"Discordbot",
"WhatsApp",
"TelegramBot",
"Slackbot",
"AhrefsBot",
"SemrushBot",
# ... see bot.md for full list
]

[security]
allowed_origins = []
block_private_cidrs = true
rate_limit_per_domain = 10
rate_limit_per_ip = 0

[admin]
enabled = true
address = "127.0.0.1:4001"
# bearer_token = "your-secret-token"

[logging]
level = "info"
format = "pretty"

[detect]
auto = false
max_body_text_bytes = 500
min_script_tags = 2
mount_points = ["app", "root", "__next", "__nuxt"]
header = "X-Prism-Render"

[license]
# path = "/etc/prism/license.lic"

[warmup]
concurrency = 4
rate_limit_per_sec = 5
max_urls = 50000

Configuration Sections

SectionDescription
[server]Listen address, origin, mode, timeouts
[render]Rendering behavior, pool, postprocessing, viewport
[cache]Caching strategy, TTL rules, memory limits
[routes]URL include/exclude patterns
[bot]Bot user-agent detection patterns
[security]SSRF protection, rate limiting, allowed origins
[admin]Admin API endpoint
[logging]Log level and format
[detect]SPA shell auto-detection
[license]License file path
[warmup]Sitemap-based cache warming