-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
445 lines (401 loc) · 27.2 KB
/
Copy path.env.example
File metadata and controls
445 lines (401 loc) · 27.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# ─────────────────────────────────────────────────────────────────────────────
# Couchbase Admin MCP Server — configuration
#
# Copy to `.env` and adjust. All variables are optional unless noted; defaults
# are chosen to be SAFE first (read-only, everything gated) rather than
# convenient, so an unconfigured server cannot mutate a cluster by accident.
# ─────────────────────────────────────────────────────────────────────────────
# ── Cluster connection (shared with the base MCP-Couchbase server) ───────────
# These are intentionally the same variable names as the data-plane server, so
# a working connection config can point at either server unchanged.
CB_CONNECTION_STRING=couchbases://your-cluster.example.com
CB_USERNAME=Administrator
CB_PASSWORD=change-me
# Management port for REST admin calls (default 18091 for TLS, 8091 non-TLS).
# CB_MGMT_PORT=18091
# TLS certificate paths (optional; for mutual TLS supply BOTH cert and key).
# CB_CA_CERT_PATH=/path/to/ca.pem
# CB_CLIENT_CERT_PATH=/path/to/client.pem
# CB_CLIENT_KEY_PATH=/path/to/client.key
# Never set this to true against a real cluster — disables TLS verification.
# CB_ADMIN_TLS_INSECURE=false
# ── Read-only mode ───────────────────────────────────────────────────────────
# DEFAULT: true. The server comes up read-only — only the ~80 read tools load;
# every write/mutating tool is unloaded entirely and cannot be called. You must
# opt IN to writes explicitly. This is the outermost safety layer.
CB_ADMIN_READ_ONLY_MODE=true
# ── Dry run / preview mode ───────────────────────────────────────────────────
# DEFAULT: false. When true, every WRITE is authorized, audited and then NOT
# performed: the response says which tool would have run, against which target,
# with which arguments. Reads still execute, because a read changes nothing and
# a plan is worth nothing without one.
#
# A caller may also pass `dry_run: true` with any write tool's arguments. This
# variable OVERRIDES that: `dry_run: false` cannot escape preview mode, because a
# control a caller can switch off is not a control.
#
# Use it for the first run of an unattended pipeline against a new organization,
# and keep the output as the artifact you attach to the change request. Audit
# records the decision as `dry_run`, not `allowed`, so previews do not inflate
# your count of privileged writes.
# CB_ADMIN_DRY_RUN=false
# ─────────────────────────────────────────────────────────────────────────────
# CONFIRMATION AND AUTOMATION
#
# There are two independent trust models. Read this section before enabling
# writes in anything but a throwaway dev cluster.
# ─────────────────────────────────────────────────────────────────────────────
# ── Interactive confirmation (the default trust model) ───────────────────────
# When writes are enabled, EVERY write tool requires a per-call confirmation:
# the caller must re-invoke with `confirm: true` in the arguments, or (on
# clients that support it) answer an elicitation prompt. This is designed for a
# human driving an MCP client.
#
# Add extra tools to the confirmation set (comma-separated). Rarely needed since
# all writes are gated by default.
# CB_ADMIN_CONFIRMATION_REQUIRED_TOOLS=
# Show the "re-call with confirm: true" hint in the confirmation message.
# Recommended ON so agents know how to proceed.
CB_ADMIN_ELICITATION_HINTS=true
# ── Automation mode (the second trust model — for unattended workflows) ──────
# For CI/CD pipelines and workflow agents where NO human is present per call.
# The authorization happens ONCE, when your IdP issues the workflow's service
# principal a token carrying the automation scope — NOT by the agent answering
# a prompt (which would be impersonating a human it isn't).
#
# A token carrying this scope IN ADDITION TO the write scope may execute gated
# write tools WITHOUT a per-call confirmation. The automation scope never
# substitutes for the write scope: an automation token with no write scope still
# cannot write. The scope is bound to the token, so a caller cannot self-promote
# by putting a value in tool arguments.
CB_ADMIN_SCOPE_AUTOMATION=couchbase-admin-mcp:automation
# ── The hard ceiling (the control that makes automation safe) ────────────────
# Tools listed here ALWAYS require a per-call human confirmation, EVEN for an
# automation-scoped principal. A workflow can create buckets and deploy eventing
# functions unattended, but anything in this list still stops for a human.
#
# CRITICAL: this list is set HERE, on the server, by whoever deploys it — a
# human. No token scope, tool argument, or client-supplied value can remove a
# tool from it. The automated caller provably cannot bypass it.
#
# DEFAULT: empty — friction-free for a developer's own cluster.
# For a PRODUCTION admin server, set a strict list. Recommended starting point:
# CB_ADMIN_ALWAYS_CONFIRM=admin_bucket_delete,admin_bucket_flush,admin_node_remove,admin_failover_hard,admin_failover_graceful,admin_rebalance_start,admin_user_delete,admin_group_delete,admin_xdcr_replication_delete,admin_cluster_leave
CB_ADMIN_ALWAYS_CONFIRM=
# ── OAuth scopes (only relevant on the HTTP transport with OAuth configured) ──
# CB_ADMIN_SCOPE_READ=couchbase-admin-mcp:read
# CB_ADMIN_SCOPE_WRITE=couchbase-admin-mcp:write
# ── Tool exposure ────────────────────────────────────────────────────────────
# Comma-separated tool names to disable entirely (never loaded, never callable).
# CB_ADMIN_DISABLED_TOOLS=
# ── Transport ────────────────────────────────────────────────────────────────
# stdio (default) or http (opt in for a long-running networked service).
CB_ADMIN_TRANSPORT=stdio
# For http transport:
# CB_ADMIN_HOST=127.0.0.1
# CB_ADMIN_PORT=8000
# Require and validate OAuth bearer tokens on HTTP (needs OAUTH_ISSUER set).
# CB_ADMIN_HTTP_REQUIRE_AUTH=false
# CB_ADMIN_HTTP_TIMEOUT=30
# CB_ADMIN_HTTP_RETRIES=3
# ── OAuth / OIDC (optional; HTTP transport only) ─────────────────────────────
# OAUTH_ISSUER=https://your-idp.example.com/
# OAUTH_AUDIENCE=couchbase-admin-mcp
# OAUTH_JWKS_URI=https://your-idp.example.com/.well-known/jwks.json
# OAUTH_ALGORITHMS=RS256
#
# ⚠ OAUTH_SKIP_VERIFY — DEVELOPMENT ONLY. NEVER SET THIS IN PRODUCTION.
# When true, bearer tokens are decoded WITHOUT signature verification: any token
# is accepted, issuer/audience/expiry are not checked, and the scope model
# (including the automation scope) rests on forged claims. This makes
# authentication meaningless and lets any caller self-grant write and automation
# scope. Leave unset. Defaults to false.
# OAUTH_SKIP_VERIFY=false
# ── Logging ──────────────────────────────────────────────────────────────────
# Level: OFF, DEBUG, INFO, WARNING, ERROR (default INFO).
CB_ADMIN_LOG_LEVEL=INFO
# Sinks: stderr and/or file (comma-separated, default stderr).
# The file sink writes ONE ROTATING FILE PER LEVEL — cb_admin_mcp.info.log,
# .warning.log, .error.log — so support can ask for just the error log.
# CB_ADMIN_LOG_SINKS=stderr,file
# CB_ADMIN_LOG_FILE=cb_admin_mcp.log
# ─────────────────────────────────────────────────────────────────────────────
# COUCHBASE CAPELLA (control plane)
#
# Capella does NOT expose the ns_server admin REST API on 8091/18091 to
# tenants: a Capella database credential carries bucket-scoped data roles and
# never Full Admin. So the admin_* tools in this server cannot work against
# Capella, and are unloaded when Capella is detected. Their Capella equivalents
# are the capella_* tools, which use the Management API v4 control plane.
# ─────────────────────────────────────────────────────────────────────────────
# ── Deployment mode ──────────────────────────────────────────────────────────
# auto (default) | capella | self_managed | both
# auto — infer: a *.cloud.couchbase.com connection string means
# Capella; a Capella API key with no connection string means
# Capella; both configured means 'both'.
# both — load everything, gate nothing. For one server administering a
# self-managed cluster AND a Capella organization. You accept
# that some tools will fail against whichever side lacks them.
CB_DEPLOYMENT=auto
# Set false to keep every tool loaded regardless of detected mode. Prefer
# CB_DEPLOYMENT=both, which is the explicit spelling of the same intent.
CB_DEPLOYMENT_GATE=true
# ── Capella v4 credentials ───────────────────────────────────────────────────
# The API key SECRET, from Capella: Settings -> API Keys -> Create API Key.
# This is the secret half of the pair, used directly as a Bearer token. It is
# shown ONCE at creation and cannot be retrieved afterwards.
#
# The key's organization and per-project roles are an independent authorization
# layer: reads need at least projectViewer, writes need projectManager or
# organizationOwner. Grant the least that works — this server's guardrails and
# Capella's RBAC are both in force, and the stricter one wins.
# CAPELLA_API_KEY_SECRET=
# CAPELLA_BASE_URL=https://cloudapi.cloud.couchbase.com
# CAPELLA_HTTP_TIMEOUT=30
# CAPELLA_HTTP_RETRIES=3
# perPage for list calls (max 100). List calls auto-paginate to completion.
# CAPELLA_PAGE_SIZE=100
# Cap on auto-paginated results — a guard against handing an LLM a 50,000-row
# audit dump. A truncated result says so explicitly.
# CAPELLA_MAX_ITEMS=1000
# ─────────────────────────────────────────────────────────────────────────────
# CAPELLA GUARDRAILS — the blast-radius controls
#
# The ephemeral-environment workflow is destructive by nature and runs with no
# human in the loop: CI creates a cluster, tests against it, deletes it. So
# cluster deletion must be callable without confirmation — which is exactly the
# operation you least want pointed at production by a mistaken argument.
#
# Read-only mode is off by definition here, the confirm:true gate is bypassed
# for automation principals by design, and CB_ADMIN_ALWAYS_CONFIRM would stop
# teardown dead. None of them can express "delete freely, but only inside the
# sandbox." These settings do.
#
# Every one is server-side configuration, set by a human at deploy time. No tool
# argument, token scope, or model assertion can relax them.
# ─────────────────────────────────────────────────────────────────────────────
# Pin the organization. A caller-supplied organization_id that differs is
# REFUSED rather than honored.
# CAPELLA_ORG_ID=
# THE IMPORTANT ONE. Comma-separated project UUIDs in which destructive
# operations are permitted. Production projects must be left OFF this list —
# that omission is what makes them unreachable.
#
# UNSET = FAIL CLOSED: the server will create but refuse to delete. That is
# deliberate; "delete anything in the organization" is not a defensible default
# for a tool an agent can call.
# CAPELLA_ALLOWED_PROJECTS=
# Default project for the capella_env_* tools when project_id is omitted.
# CAPELLA_DEFAULT_PROJECT_ID=
# Required name prefix for resources this server creates. Destructive operations
# REFUSE any resource whose name lacks it — the guard against a hand-made
# production cluster that happens to sit inside an allowlisted project.
# Strongly recommended in any shared organization.
# CAPELLA_ENV_NAME_PREFIX=mcptest-
# Spend guard: maximum concurrent managed environments. A retry loop cannot
# provision clusters without bound.
CAPELLA_MAX_ENVIRONMENTS=10
# Default TTL for a new environment, in hours. capella_env_reap tears down
# environments past their TTL — the backstop for a CI job that crashed before
# its teardown step. 0 on an individual environment means never expire.
CAPELLA_ENV_TTL_HOURS=8
# Cluster UUIDs that may never be deleted by this server, regardless of project
# or prefix. Belt and braces for a known-critical cluster.
# CAPELLA_PROTECTED_CLUSTERS=
# Lifts the CAPELLA_ALLOWED_PROJECTS requirement, allowing destructive
# operations anywhere in the organization. Intended for a personal throwaway
# organization. Named so that enabling it in a customer organization is an
# obviously deliberate act. Leave unset.
# CAPELLA_ALLOW_UNSCOPED_DESTRUCTIVE=false
# ─────────────────────────────────────────────────────────────────────────────
# CLUSTER EGRESS ALLOWLIST — where COUCHBASE itself may be told to connect
#
# Several admin operations take a hostname from the caller and make the CLUSTER
# open the connection. The agent picks the destination; the cluster — inside your
# trust boundary, often holding a cloud instance role — does the dialling:
#
# admin_logs_collect_start(uploadHost=) a full diagnostic bundle from every
# node, containing query text, document
# keys, config and sometimes credentials
# admin_xdcr_reference_create(hostname=) + replication_create: an entire bucket,
# streamed continuously
# admin_node_add(hostname=) a joining node receives replica data
# admin_kmip_set(kmipHost=) where the master encryption key comes
# from; repoint it and the cluster cannot
# decrypt its own data after a restart
# admin_alerts_set(emailHost=) arbitrary outbound TCP, on demand
#
# They can also be aimed inward, at addresses the agent itself cannot reach:
# 169.254.169.254 returns cloud IAM credentials, and RFC1918 ranges become
# reachable through the cluster.
#
# Comma-separated hosts, IPs, CIDRs, or '.domain.example' for a suffix match.
# UNSET = FAIL CLOSED: no destination is permitted and those five tools refuse.
# CB_ADMIN_EGRESS_ALLOWED_HOSTS=.couchbase.com,10.20.0.0/16,smtp.corp.example
# Lifts the allowlist. Loopback, link-local and cloud-metadata addresses stay
# denied regardless — that denial cannot be configured away. Leave unset.
# CB_ADMIN_EGRESS_ALLOW_ANY=false
# ── GUI (gui/gui_server.py) ──────────────────────────────────────────────────
# The GUI is a separate Flask app, not part of the MCP server process. It was
# previously unauthenticated by default; it now refuses to serve /api/* unless
# one of the following is set.
#
# Enable OIDC login for the GUI. This is the supported posture.
# OAUTH_ENABLED=true
#
# Explicit acknowledgement that you are running the admin console with NO
# authentication. Loopback development only.
# CB_GUI_INSECURE_NO_AUTH=false
#
# Server-side automation mode for the GUI. Previously this could also be supplied
# in the request body, which let any caller skip the confirmation gate for every
# write tool. That path is removed; only this variable is honoured.
# CB_ADMIN_GUI_AUTOMATION — REMOVED. The console's automation posture is no longer
# a separate environment variable: it is read from the presented token's automation
# scope, the same source the MCP transport uses (see authz.py). A second, env-driven
# notion of "this session is automation" is how the console came to disagree with the
# server about what was authorized.
# ─────────────────────────────────────────────────────────────────────────────
# DEPLOYMENT PROFILE — state which of the two shapes this is. No default.
#
# workstation Developer laptop. Docker container or local process driven by
# Claude Desktop over stdio. No IdP, no token. A HUMAN IS PRESENT
# at the client, so `confirm: true` is a real second look, and the
# audit identity is the OS user. Nothing network-exposed.
#
# enterprise A human pushes code; a workflow-manager agent notices and
# instructs a child agent; the child performs the admin task with
# NO HUMAN at the moment of action — correctly, because the
# authorization happened when the IdP issued that child's service
# principal a token carrying the automation scope. Here
# `confirm: true` means nothing (the model supplies it); the real
# controls are the token scopes, the allowlists and the audit log.
#
# The profile only fills variables you have NOT set — explicit settings win. What
# it will not do is let an incoherent pair through: under `enterprise`,
# OAUTH_SKIP_VERIFY, CB_GUI_INSECURE_NO_AUTH, a missing OAUTH_ISSUER/AUDIENCE,
# CB_ADMIN_EGRESS_ALLOW_ANY or CB_ADMIN_TLS_INSECURE make the server REFUSE TO
# START rather than run a posture that cannot be secure.
CB_ADMIN_PROFILE=workstation
# ── The unattended authorization path (enterprise) ───────────────────────────
# Issue the child agent's service principal a token carrying BOTH the write scope
# and the automation scope. With automation the per-call confirmation is skipped
# entirely — by design, not by loophole: the human decision happened once, at
# credential issuance.
#
# Scope names are matched against the token's scope / scp / scopes / roles /
# permissions claims, all unioned. `roles` matters specifically for Microsoft
# Entra: client-credentials tokens carry APP PERMISSIONS in `roles`, not `scp`.
# CB_ADMIN_SCOPE_READ=couchbase-admin-mcp:read
# CB_ADMIN_SCOPE_WRITE=couchbase-admin-mcp:write
# CB_ADMIN_SCOPE_AUTOMATION=couchbase-admin-mcp:automation
# ── Audit trail ──────────────────────────────────────────────────────────────
# One structured JSON record per tool call: principal, scopes held, whether
# automation applied, decision (allowed / denied_scope / denied_confirmation /
# error), duration, redacted arguments. Authentication failures recorded too.
#
# PROVENANCE: a caller may pass `correlation_id` with any tool's arguments — a git
# SHA, a workflow run URL. It is recorded, stripped before the call, and has NO
# effect on authorization. It is what ties a cluster change back through the child
# agent and the workflow run to the human who pushed the code; without it the trail
# stops at "service principal X created a bucket".
# CB_ADMIN_LOG_SINKS=stderr,file
# CB_ADMIN_LOG_MAX_BYTES=33554432
# CB_ADMIN_LOG_BACKUP_COUNT=10
# ── HTTP transport (enterprise) ──────────────────────────────────────────────
# Each client gets its own MCP session, and the authenticated principal is
# resolved from the request inside the dispatch task — so the token's scopes, and
# therefore the automation trust model, actually apply. (Previously one shared
# session with no binding, and claims that could never cross the task boundary.)
#
# Origins permitted to drive the server from a browser. Without this a page on the
# operator's machine can drive a loopback-bound server via DNS rebinding.
# CB_ADMIN_ALLOWED_ORIGINS=https://console.corp.example
# The server REFUSES TO START if asked to bind a non-loopback address while
# CB_ADMIN_HTTP_REQUIRE_AUTH is false — that combination would expose the whole
# admin tool surface unauthenticated. Note the transport is plain HTTP: terminate
# TLS in front of it, or bearer tokens cross the network in clear.
# CB_ADMIN_HOST=127.0.0.1
# CB_ADMIN_PORT=8000
# ─────────────────────────────────────────────────────────────────────────────
# Hardening added in the third security review pass
# ─────────────────────────────────────────────────────────────────────────────
# Host header values the HTTP transport will answer to.
#
# DNS-rebinding protection compares the request's Host header against a list derived
# from the bind address. Behind a Kubernetes Service or an ingress, the bind is
# 0.0.0.0 while the Host header is a service name — which matched nothing, so the
# transport answered HTTP 421 to every request. List the names clients actually use.
# A bare hostname is also accepted with the server's port appended.
# CB_ADMIN_ALLOWED_HOSTS=cb-mcp.corp.example,cb-mcp.svc.cluster.local
# Acknowledge that a non-loopback bind under CB_ADMIN_PROFILE=workstation is the
# CONTAINER case, where the port is published to loopback on the host
# (-p 127.0.0.1:8080:8080) and the 0.0.0.0 bind is an artifact of containerisation.
#
# Without this, workstation + http + a non-loopback host is FATAL at startup — because
# the workstation profile's relaxations (HTTP auth off, unauthenticated console) are
# all justified by "nothing is network-reachable", and the realistic way to reach that
# combination is an operator copying a dev compose file into a data centre.
#
# Note this waives the STARTUP check only. It does not make `confirm: true` count as a
# human approval: that requires the stdio transport, where a person is at the MCP
# client by construction.
# CB_ADMIN_WORKSTATION_CONTAINER_BIND=1
# Maximum outbound JWKS refreshes per minute, across all key ids.
#
# `kid` is read from the UNVERIFIED part of a token, so it is attacker-chosen, and
# PyJWT refetches the key set on a miss. Without a budget, 200 requests carrying 200
# invented key ids produced 200 outbound fetches: 1:1 amplification against the
# identity provider from a trusted source address, plus one blocked worker thread each.
# Raise this only if a legitimate key rotation needs more headroom.
# CB_ADMIN_JWKS_REFRESH_BUDGET=10
# Field names the cluster-egress guard should NOT treat as destinations.
#
# The guard matches by key SHAPE (anything containing host/url/uri/server/endpoint/
# address), so it catches new host-bearing fields the day an endpoint gains one rather
# than the day someone remembers to list it. The cost is occasional false positives on
# fields like a contact emailAddress, which are exempted by default — add any others
# here rather than editing the source.
# CB_ADMIN_EGRESS_EXEMPT_FIELDS=notificationAddress,siteUrl
# Extra browser origins permitted to drive the admin console.
#
# The console validates Origin on state-changing requests and requires
# Content-Type: application/json, which together stop a page the operator happens to
# visit from driving the API. flask_cors alone does not: CORS governs whether the
# browser lets the calling page READ the response, while the request executes either
# way. Loopback origins are always allowed.
# CB_GUI_ALLOWED_ORIGINS=https://console.corp.example
# Rotation for the dedicated audit sink (CB_ADMIN_AUDIT_FILE).
# CB_ADMIN_AUDIT_MAX_BYTES=33554432
# CB_ADMIN_AUDIT_BACKUP_COUNT=10
# ─────────────────────────────────────────────────────────────────────────────
# Transport encryption (HTTP transport only)
# ─────────────────────────────────────────────────────────────────────────────
#
# The bearer tokens this transport carries hold the automation scope, and that token is
# the credential the entire unattended model rests on — the scope gate, the hard ceiling
# and the audit principal are all downstream of "the caller holds a legitimate token".
# An observer who captures one becomes an authorized child agent and bypasses all of
# them at once. So a NON-LOOPBACK http bind with neither a certificate nor the
# external-termination acknowledgement below is FATAL at startup.
#
# Loopback binds are exempt: traffic that never leaves the host cannot be sniffed.
# ── Option A: this process terminates TLS ───────────────────────────────────
# Self-contained, no infrastructure dependency. You own certificate rotation inside
# the container.
# CB_ADMIN_TLS_CERT_FILE=/etc/tls/server.crt
# CB_ADMIN_TLS_KEY_FILE=/etc/tls/server.key
# CB_ADMIN_TLS_KEY_PASSWORD= (only if the key is encrypted)
# Mutual TLS (optional, recommended for the enterprise agent chain). With this set the
# caller must present a client certificate signed by this CA, so a STOLEN BEARER TOKEN
# ALONE is not sufficient to reach the tool surface.
# CB_ADMIN_TLS_CLIENT_CA_FILE=/etc/tls/client-ca.crt
# ── Option B: something in front terminates TLS ─────────────────────────────
# An ingress controller, service mesh sidecar, or load balancer terminates TLS and
# forwards cleartext over a network you consider trusted. This is how most Kubernetes
# deployments work.
#
# The acknowledgement is MANDATORY rather than inferred, because "a mesh handles it" and
# "nobody configured it" produce byte-identical processes — the only difference is
# whether a human decided. Setting this asserts that TLS is handled in front.
# CB_ADMIN_TLS_TERMINATED_EXTERNALLY=1