Skip to Content
Configuration Reference

Configuration Reference

This page is a structured reference to the full configuration surface for a Marshal install — every Terraform variable (Terraform path) and its corresponding raw Helm chart value (ArgoCD / GitOps path). For task-oriented walkthroughs, see the Installing Marshal guides; for the onboarding credentials themselves, see Prerequisites — this page assumes you already have them and covers everything else.

Both installers configure the same underlying Helm chart. The Terraform variable names below are how you set things when installing via Terraform; the “Chart value” noted in each row is the equivalent raw Helm value, useful if you’re on the ArgoCD/GitOps path and writing valuesObject (or a values.yaml) directly.

Almost everything here has a sensible default. Only three settings are required with no default: the installation JWT, the chart version, and the ingress hostname.

Release identity & chart

SettingValuesDefaultNotes
release_namestringmarshalHelm release name.
namespacestringmarshalControl-plane namespace.
create_namespacebooltrueWhether Terraform creates the namespace. On the ArgoCD path this is instead syncOptions: [CreateNamespace=true] on the Application — but the seeded Secrets (below) still need the namespace to exist beforehand.
chartstringmarshalChart name inside the OCI registry. You won’t normally change this.
chart_versionstring(none — required)Exact product version to install. Chart value: targetRevision on the ArgoCD Application. Always the version given in your onboarding materials.

Credentials

The three onboarding credentials (installation_jwt, deployment_id, registry_pull_token) are explained in full in Prerequisites → Onboarding credentials — this table only maps them to their settings.

SettingValuesDefaultNotes
installation_jwtJWT string(none — required)Your license. Stored as a K8s Secret. Chart value: not set directly — on the ArgoCD path this is a pre-seeded Secret referenced by license.secretName / license.key.
deployment_iddep_...(none — required)Registry username (convention only — the registry ignores the username and authenticates on the token).
registry_pull_tokenmrpt_...(none — required)Registry password. Authenticates chart pulls, product image pulls, and (in secret registry mode) session tool-image pulls.

Registry & image pulls

Controls where product and session tool images are pulled from. The effective image prefix is image_cache_registry when set, else registry.

SettingValuesDefaultNotes
image_cache_registryregistry host/path(empty)Your shared pull-through cache. Recommended, required at scale. One per customer, set up once, reused by every install (prod, staging, …). Chart value: global.registry.
registryregistry hostregistry.marshal.codesDirect-pull registry. Only used when image_cache_registry is unset.
registry_auth_modesecret | workloadIdentity | nonesecretsecret: chart builds a dockerconfigjson from your pull token and stamps it on pods — simplest, good for a single-node eval. workloadIdentity: nodes pull via GKE Workload Identity / EKS IRSA — no in-cluster secret, pairs with a pull-through cache. none: an open in-network mirror, anonymous pulls. Chart value: registryAuth.mode.
registry_secret_serverstringderivedName of the generated image-pull Secret replicated into the sessions namespace when registry_auth_mode = secret.

Direct pull (registry_auth_mode = secret) shares Marshal’s registry rate limit across every customer pulling at once. It’s fine for a single-node eval; for a real install, run a pull-through cache and set image_cache_registry.

Datastores

Postgres and Redis are configured independently. Recommended posture: external Postgres + bundled Redis.

SettingValuesDefaultNotes
database_modeexternal | bundledexternalexternal (recommended): supply database_url; Postgres is the source of truth for sessions, orgs, credentials, manifests, and audit, and needs real backups/HA. bundled is demo/eval only.
database_urlPostgres DSN(none)Required when database_mode = external. Stored as a K8s Secret; never enters Helm release state. Chart value: externalDatabaseSecret.name / .key, pointing at a Secret you (or the module) create.
redis_modebundled | externalbundledbundled (default, recommended): in-cluster Redis. Everything Marshal keeps in Redis is ephemeral/TTL’d/reconstructible (WS tokens, SSE streams, pod addresses, OAuth state, usage buffers) — nothing durable lives only in Redis, so a managed instance buys durability you don’t need. external: supply redis_url to point at managed Redis.
redis_urlRedis URL(none)Required when redis_mode = external. Chart value: bundledDeps.redis.enabled: false plus your own Redis connection value.

Ingress & TLS

SettingValuesDefaultNotes
ingress_hosthostname(none — required)Required on day one — plans fail without it even before real DNS exists. Point DNS at the load balancer whenever convenient. Chart value: ingress.host.
ingress_enabledbooltrueWhether the chart creates an Ingress at all. Chart value: ingress.enabled.
ingress_class_namestringcloud-specificThe IngressClass to use (e.g. gce-internal, nginx, alb). Chart value: ingress.className.
ingress_annotationsmap(empty)Extra annotations merged onto the Ingress object — useful for controller-specific config (e.g. a cert-manager issuer annotation).
ingress_tlslist(empty)Low-level TLS escape hatch — always wins over any higher-level TLS option below. Use this if you manage TLS via your own ingress controller / cert-manager instead of a cloud flavor’s built-in TLS handling.
preview_domaindomain(empty)Base domain for per-session preview subdomains (*.<preview_domain>). Leave unset if you don’t use preview URLs.
preview_schemehttp | httpshttpsScheme used when constructing preview URLs.

Some cloud flavors layer additional, more opinionated TLS handling on top of the shared ingress_tls escape hatch. For example, the GKE flavor exposes a tls_mode variable:

SettingValuesDefaultNotes
tls_mode (GKE flavor)self_signed | inline | secret | noneself_signedself_signed: Terraform generates a clearly-marked placeholder cert and manages the Secret for you — HTTPS works out of the box, with a browser warning until you replace it. inline: paste real PEM cert/key into tfvars. secret: point tls_secret_name at a Secret you manage yourself (e.g. via cert-manager). none: HTTP-only. Switching between these needs no other config change.

If you use preview_domain, the certificate needs to cover *.<preview_domain>, not just ingress_host. GKE-managed certificates don’t support wildcard domains at all, and cert-manager needs a DNS-01 solver (not the default HTTP-01) to issue one. The self_signed default covers the wildcard correctly out of the box. See Troubleshooting if a wildcard cert request is stuck.

Secrets management

Controls how the two critical app secrets — JWT_SECRET (signs session/API tokens) and KMS_LOCAL_KEY (envelope-encrypts every stored credential) — are sourced. Chart value: secrets.provider.

secrets_provider valueChart valueWhat it meansWhen to use it
generatedsecrets.provider: generatedThe chart generates random values on first install and (via Helm’s lookup function) reuses the same ones on every subsequent helm upgrade.Terraform installs only — Terraform actually runs helm install/helm upgrade, so lookup works. Default for the Terraform path.
existingsecrets.provider: existingYou create a stable Secret yourself, once; the chart only references it via secrets_existing_secret and never manages or rotates it.Required for the ArgoCD/GitOps path. ArgoCD renders and applies manifests directly — it never runs helm install, so lookup never executes, and generated would mint fresh secrets on every sync.
externalSecretssecrets.provider: externalSecretsAn External Secrets Operator installation populates the Secret from your own cloud secret manager.GitOps installs that already run External Secrets Operator and want the app secrets sourced from a central secret store instead of a manually-seeded Secret.
SettingValuesDefaultNotes
secrets_providergenerated | existing | externalSecretsgeneratedSee table above.
secrets_existing_secretSecret name(none)Required when secrets_provider = existing. The Secret must carry JWT_SECRET and KMS_LOCAL_KEY keys.
secrets_external_secretsconfig(none)Required when secrets_provider = externalSecrets.
kms_backendbackend identifiermodule defaultSelects the backend that manages the key used to envelope-encrypt stored credentials.

Never switch secrets_provider back to generated on an install that’s already running, and never delete the Secret backing existing / externalSecrets — losing KMS_LOCAL_KEY makes every stored credential permanently unrecoverable, and rotating JWT_SECRET invalidates every issued session and API token. See Troubleshooting for the failure mode this causes.

Session namespace & marketplace

SettingValuesDefaultNotes
spaces_namespacestringderived from namespaceThe namespace session pods run in, separate from the control-plane namespace.
marketplace_upstreamURLMarshal’s default catalogWhere the marketplace pulls its default catalog of tools, agents, and MCP servers from.
marketplace_token_exchange_urlURLMarshal’s defaultEndpoint the marketplace uses to exchange for short-lived credentials when installing a catalog item into a session.
marketplace_customer_reposlist(empty)Additional customer-specific repos to include in the marketplace catalog, beyond the default upstream set.

License tuning

SettingValuesDefaultNotes
license_jwks_urlURLhttps://keys.marshal.codes/.well-known/jwks.jsonWhere the api fetches the public JWKS used to verify your installation JWT’s signature.
license_refresh_urlURLhttps://tokens.marshal.codes/v1/licenseWhere the installation JWT is exchanged for a short-lived operational license (online tier).
license_enforcebooltrueWhether the api hard-enforces license verification.

Web sign-in

SettingValuesDefaultNotes
basic_auth_enabledboolfalsePuts HTTP basic auth in front of the web dashboard, in addition to normal sign-in.

Escape hatch

SettingValuesDefaultNotes
values_overrideslist of YAML strings (Terraform)(empty)Raw Helm values merged on top of everything else — for chart settings that don’t have a first-class Terraform variable yet. On the ArgoCD path, the equivalent is simply adding more keys to valuesObject (or your values.yaml) directly.
values_overrides = [ <<-EOT redis: image: repository: some/override EOT ]

Every chart value surfaced above is cross-checked against the umbrella chart’s own values.yaml — if you need something not listed here, it likely still exists as a raw chart value reachable through this escape hatch.