Skip to content

Plus ​

Optional ops plugin for the CLI (and Inspector panels). For operators who want a dashboard, metrics, auth, and a thin web application firewall (WAF) without writing custom code.

Next: install with titanium update --plus, enable in YAML, open the dashboard.

What you get ​

OutcomeCapability
DashboardHTML admin on an ephemeral port (or explicit controlPlane.dashboardPort)
ObservabilityPrometheus-style metrics for destination state / latency
SecurityCIDR allow-list, JWT/OIDC (JWKS), API key / Basic auth
Web application firewall (WAF)Thin deny-list (paths, methods, headers, body size) — not a full WAF suite
Control planeLoopback HTTP API with shared-secret header; snapshot get/put; cache purge
OperationsDrain / healthy / maintenance destination states
DiscoveryFile watch, DNS poll; Consul / Kubernetes best-effort
StateFixed-window per-IP rate limit (state.mode=memory or state.redis)
ResilienceActive HTTP/TCP health probes, circuit outlier ejection, bounded idempotent connection retries
CORSOpt-in preflight + Access-Control-* response headers
CacheIn-memory HTTP response cache (cache.enable)
gRPC-JSON transcodingREST/JSON ↔ gRPC (unary + multi-frame streaming; optional gzip) via FileDescriptorSet + google.api.http (guide)

File-based route/cluster reload (titanium reload / SIGHUP / run --watch) does not require Plus — use the control plane when you want programmatic snapshot updates or discovery watches.

Install ​

Plus is distributed as a sidecar next to the CLI. There is no public Plus download button on this site.

shell
titanium update --plus
titanium version --check --plus
# Prerelease / beta channel:
titanium update --plus --channel beta
titanium version --check --plus --channel beta

titanium version --check --plus reports local → remote and exit code 2 when a newer Plus is available or Plus is missing. titanium update --plus installs or upgrades only when needed; if Plus is already current it prints that and skips the download.

Enable / disable ​

Day-to-day control is config — keep Plus installed and toggle features:

yaml
plus:
  enabled: true
  controlPlane:
    host: "127.0.0.1"
    port: 9080
    sharedSecret: "<shared-secret>"
  options:
    cache.enable: "true"

Set plus.enabled: false (or remove the plus: block) to stop using Plus without deleting it from disk.

Use a strong secret in production. Dev-only default secrets require an explicit environment opt-in on loopback.

Engine knobs (profiles, timeouts, TLS, limits, upstream, …) are configured under server: in twp.yaml — not plus.options. See Configuration.

Remove ​

To delete Plus from disk:

shell
titanium update --remove-plus

This removes Plus beside the CLI (and .bak / .new). It does not stop a running proxy, OS service, or the in-process Plus control plane / dashboard — stop titanium run or titanium service stop, then start again so Plus unloads. It does not edit your config; disable plus.enabled separately if it is still set. Re-install later with titanium update --plus.

plus.options keys (reference) ​

String values under plus.options (examples):

KeyRole
discovery.modefile, dns, consul, or k8s
discovery.filePath for mode=file
discovery.dnsName / discovery.dnsPortDNS discovery target
discovery.consulUrl / discovery.k8sUrlBest-effort HTTP poll endpoints
discovery.intervalMs / discovery.clusterIdPoll interval and cluster id
security.allowCidrsComma-separated client CIDR allow-list
security.jwtAuthority / security.jwtAudience / security.jwksUrlJWT/OIDC validation
security.apiKeysComma-separated API keys (X-Api-Key by default)
security.apiKeyHeaderAlternate API key header name
security.basicUsersComma-separated user:password pairs for HTTP Basic
cors.enabledEnable CORS helper (true)
cors.allowOrigin / cors.allowMethods / cors.allowHeaders / cors.allowCredentials / cors.maxAgeSecondsCORS knobs
waf.enabledEnable thin deny-list WAF
waf.denyPaths / waf.denyMethods / waf.denyHeaderDeny rules
waf.maxBodyBytes / waf.rulesFileBody cap and optional rules file
state.modememory or use Redis via state.redis
state.redis / state.rateLimitPerMinuteRedis connection and rate limit
resilience.activeHealthEnable active probes
resilience.intervalMs / resilience.unhealthyThreshold / resilience.path / resilience.protocol / resilience.timeoutMsProbe knobs
resilience.circuit.enabledOutlier ejection on consecutive 5xx → Unhealthy
resilience.circuit.failureThreshold / resilience.circuit.cooldownMsCircuit knobs
resilience.retry.idempotentAttemptsRaise connection retries for safe methods (1–5)
cache.enableIn-memory response cache
grpc.transcode.enabledEnable gRPC-JSON transcoding
grpc.transcode.descriptorSetPath to FileDescriptorSet (.pb)
grpc.transcode.servicesComma-separated fully-qualified service names
grpc.transcode.convertGrpcStatusMap non-OK grpc-status to HTTP + JSON body (default true)
grpc.transcode.ignoreUnknownQueryParametersIgnore unknown query keys (default true)
grpc.transcode.preserveProtoFieldNamesUse proto field names in JSON (default false)
grpc.transcode.alwaysPrintPrimitiveFieldsAlways emit primitive defaults in JSON (default false)
grpc.transcode.compressiontrue or gzip to gzip framed payloads

See also ​

Core, CLI, and website: MIT