Skip to content

Configuration overview configuration

The flat configuration hub remains the compatibility route. This page is the canonical source-checked field reference for its family, including nested tables and list rows.

Paths in the tables are relative to the section heading. Each row gives the serde type and source default or unset meaning; secrets stay in protected files or the supported environment overlay. Check parsing, unknown keys, and cross-field rules with gdsgate doctor --config <PATH> --json, then follow the configuration templates.

Layering

The effective config is built in three layers:

  1. Defaults. The loopback development profile and each source-defined field default. Fields without a source default remain unset until configured.
  2. TOML file from --config. Any field present overwrites the default.
  3. Environment overlay. Any GDSGATE_* variable present overwrites the file. An unset variable changes nothing.

Use the layers to keep secrets and per-host values out of committed files. See Environment overrides.

Secret references

A configuration value that is a secret, or a path to one, can name where the value actually lives instead of holding it directly. A value written as the whole string ${scheme:argument} is a reference; every other value is read literally, so a file written before the notation existed keeps working unchanged. Only a value that both opens with ${ and closes with } is parsed as a reference at all: ${file:unclosed and $TOKEN are literal values, not broken ones.

Scheme Value
(no prefix) The value itself; for a parameter that names a path, the file at that path.
file:PATH The file's contents, trailing newline stripped.
env:NAME An environment variable of the process.
exec:COMMAND ARG... Standard output of a command, trailing newline stripped.
[audit]
anchor_key_path     = "/var/lib/gdsgate/anchor.key"                      # bare path, unchanged
approval_key_path   = "${file:/var/lib/gdsgate/approval.key}"            # the same thing, written out
revocation_key_path = "${env:REVOCATION_KEY_MATERIAL}"                   # a variable of this process
delegation_key_path = "${exec:/usr/local/bin/gdsgate-unwrap delegation}" # a helper's standard output

Which reading a bare value gets depends on the parameter, not on the notation. A parameter that names a path reads a bare value as a file, exactly as before the notation existed: anchor_key_path = "/var/lib/gdsgate/anchor.key" and anchor_key_path = "${file:/var/lib/gdsgate/anchor.key}" mean the same thing. A parameter whose value is not a path, an agent delegation profile's env entries, the one-time enrollment token, reads a bare value as the value itself.

What accepts it

Parameter Documented at
[audit].anchor_key_path Operations
[audit].approval_key_path Operations
[audit].revocation_key_path Operations
[audit].delegation_key_path Operations
[audit].inventory_key_path Operations
[authority].enroll_key_file Authority
[proxy].web_key_file Proxy
[proxy].webapps_key_file Proxy
[proxy].public_key_file Proxy
store_password_file Top level
[enroll].token Enrollment
[[connector.backends]].service_account_password_file Connector
[[connector.backends]].token_path Connector
[[connector.backends]].credential_file Connector
[connector.backends.discovery].password_file Connector

Running a command

exec: starts a helper and takes what it prints, which is how an operator reaches a hardware module or a secret store this process has no driver for.

  • The command runs without a shell. The string is split on whitespace and the first word is executed directly; a pipeline, a redirect, or a second command cannot be written this way, and neither can an argument that contains a space. A helper that needs one is a wrapper script that takes none.
  • Nothing travels in the arguments. What the reference resolves to is read from the command's standard output, and the command is given nothing on its standard input. An argument is readable by every account on the host and is kept by the shell history of whoever runs the command by hand.
  • A nonzero exit code is a refusal. The parameter is treated as unresolved and the process does not start; nothing is substituted for a secret the command could not produce.
  • The environment is inherited unchanged. Whatever authenticates the helper to wherever the secret lives is expected to already be there; gdsgate adds no authentication scheme of its own for this.
  • The command has 30 seconds to answer before it is killed and the reference refused.

A reference is resolved while configuration loads, never on a session's data path. The one exception is a listener's certificate key: the pair is re-read whenever the certificate file changes, so a helper or variable behind web_key_file, webapps_key_file, public_key_file, or enroll_key_file runs again at each rotation, not only at start-up.

env: and where it shows up

env: reads a variable of the process's own environment. It stays the right choice where a value has to reach a child process that would receive it in its own environment regardless, an agent delegation profile's env entries being the example. For a parameter in the table above, prefer file: or exec:: a process's environment is visible to anyone who can read /proc/<pid>/environ on the host, and it routinely ends up in a crash dump.

gdsgate doctor reports which form each covered parameter is using, without reading the material behind it.

Wrapping a source: ${kms.<name>+<source>}

Any of the three sources above can itself be ciphertext, held under a key an external service holds rather than one this process has. ${kms.<name>+file:PATH} says the file's contents are that ciphertext, and that the key <name>, one of the keys [[kms_keys]] declares, is what turns it back into a value; env: and exec: take the same prefix the same way. <name> can be left out, ${kms+file:PATH}, only while [[kms_keys]] declares exactly one key; naming a key that is not declared, or leaving the name out while more than one is declared, is refused when the configuration loads rather than resolved to a guess.

Written Means
${kms.<name>+file:PATH} The file holds ciphertext; the key <name> unwraps it.
${kms.<name>+env:VAR} The variable holds ciphertext; the key <name> unwraps it.
${kms.<name>+exec:CMD} The command's standard output is ciphertext; the key <name> unwraps it.
${kms+file:PATH} (name left out) As above, meaning the single key [[kms_keys]] declares.

A wrapper cannot sit on another wrapper: ${kms.a+kms.b+file:PATH} is refused rather than read as double protection. And a source under a wrapper that turns out to hold a keyring document rather than ciphertext is refused too, before the key is even asked: what came back is parsed as a keyring, and a parse that succeeds means there was nothing to unwrap, the material sitting in the open under a reference that claimed otherwise.

Only a parameter that reads a whole keyring accepts this prefix today: [security.integrity].control_keyring and .audit_keyring. Every other parameter in What accepts it reads a ${kms...} value and refuses it outright, naming the parameter and pointing at the plain form as the fix.

A wrapping key answers to three actions and no more:

Action Given Gets back
unwrap ciphertext the material
wrap the material ciphertext
generate nothing fresh material and its ciphertext, together, in one answer

generate is what a first authority init or a keys rotate --prepare calls under a wrapped keyring: the pair comes back from the service in one call, so the material never has to exist anywhere it is not needed, on its way to being encrypted. wrap is what writes a wrapped keyring back: a keyring is wrapped whole, as one document, so adding a key to one, or converting one off the five legacy key files, goes through it. No material crosses in an argument, in either direction, on any of the three: an argument is readable by every account on the host and is kept in the shell history of whoever ran the command by hand. A non-zero exit is a refusal and nothing else; a start that could not reach the key stops rather than carrying on under material invented locally, and what a refused call printed is never read back into an error message.

For the exec kind, the three actions are a command run three ways. Whatever command declares is run with one word appended, and everything else about it is unchanged from running a command above: no shell, nothing split beyond the declared words, a 30-second timeout.

Action Argument appended Standard input Standard output
unwrap unwrap the ciphertext the material
wrap wrap the material the ciphertext
generate generate nothing {"ciphertext":"...","plaintext":"..."}, both base64

The native kinds answer the same three actions over their own service's protocol; see [[kms_keys]] for which build carries which.

[[kms_keys]]

Used by: Authority.

The external keys this deployment's wrapped material sits under: what a ${kms.<name>+...} reference names, and what [authority].ca_kms_key names by itself. A key here belongs to a service that only ever wraps and unwraps: it takes ciphertext and gives back the material that was sealed under it, or takes material and gives back ciphertext, and the key itself never leaves the service. That is a narrower thing than a secret store that hands out a whole secret on request, and the two are not interchangeable: a key-value store has nothing to unwrap, so it is reached through exec: directly, as a source, rather than through this array. The transit engine of one product can be both at once. Vault and OpenBao's transit mount wraps and unwraps, which is what provider = "vault" means here; the same product's key-value store hands out whole secrets, which is a different mount reached a different way.

Key Type Default Purpose
name string required What a wrapper names between kms. and +. See naming below.
provider string required exec, vault, aws, or gcp. Which of the fields below this row reads.
command array of strings [] exec only, and required for it: the program and its arguments, the action word appended when it runs. An array rather than a line, so a path or an argument with a space in it needs no quoting.
key string "" Required for the three native kinds: the service's own name for the key. The key's name inside the transit engine (vault), an ARN, alias, or key id (aws), or the key's full resource name (gcp).
address string "" Where the service answers, as a base URL. Required for vault, reached nowhere else. Optional for aws, to name an interface endpoint or a separate compliance-regime endpoint in place of the region's public one. Unused by gcp, whose address is fixed.
mount string "" vault only: where the transit engine is mounted. Empty means transit.
region string "" aws only: which region the key lives in.
[[kms_keys]]
name     = "audit"
provider = "exec"
command  = ["/usr/local/bin/gdsgate-kms", "--key", "audit"]
[[kms_keys]]
name     = "audit"
provider = "vault"
address  = "https://vault.example.invalid:8200"
mount    = "kms-transit"
key      = "gdsgate-audit"

[[kms_keys]]
name     = "control"
provider = "aws"
region   = "eu-central-1"
key      = "arn:aws:kms:eu-central-1:123456789012:key/2f1c"

[[kms_keys]]
name     = "ca"
provider = "gcp"
key      = "projects/p/locations/europe-west1/keyRings/r/cryptoKeys/k"

Authentication for all three native kinds comes from the process environment; gdsgate keeps no credential of its own for any of them, matching exec. Read in the order given, first found wins:

  • vault: the token, VAULT_TOKEN, or the file ~/.vault-token where that is unset. Separately, VAULT_NAMESPACE names a request's namespace where the deployment uses them, and VAULT_CACERT names a private root of trust where the service's certificate is not signed by a public one.
  • aws: AWS_ACCESS_KEY_ID with AWS_SECRET_ACCESS_KEY (AWS_SESSION_TOKEN alongside them for a temporary pair), then the credentials a container runtime hands out, then the role the instance is running under, asked of its metadata service.
  • gcp: a service-account file named by GOOGLE_APPLICATION_CREDENTIALS, exchanged for a token by signing an assertion; failing that, the identity of the instance itself, asked of its metadata service.

Each native kind is carried only by a build compiled with its own feature, kms-vault, kms-aws, or kms-gcp, because each links a client for somebody else's service and a binary carrying all three carries most of them unused. exec is in every build. A row naming a kind the running binary was not built with is still parsed, not rejected as an unknown name; it is refused when the declared keys are assembled, and the refusal names the feature that would carry it, so the operator reads "this binary does not have it" rather than "this name is wrong".

There is no native pkcs11 kind. The shipped binary is statically linked, and a statically linked binary cannot dlopen a vendor's module, which is how PKCS#11 is reached; the module itself is built against glibc regardless. A hardware module, a KMIP device, or a key service with no native kind here is reached through provider = "exec" instead: a small helper the operator builds against the vendor's own library links it directly, on a host free to be linked dynamically.

Naming a key

A name is a boundary of revocation. [[kms_keys]] can declare more than one key, and naming them apart is what makes withdrawing this cluster's access to one of them stop only what that key covers, rather than everything any ${kms...} reference points at. One key for everything would put the split the two keyrings exist for back together a layer down, in whichever service holds the key: the audit journal that outlives the decisions it records, and may be handed to somebody outside the cluster, would unwrap under the same access as those decisions themselves. See [security.integrity] for what the split is for. Declaring keys under different providers costs nothing extra and is written the same way as declaring them under the same one.

A reference may leave the name out only while there is a single key to mean; Wrapping a source has the grammar.

What is checked against a running service

exec asks nothing external: the contract is a process boundary, and tests hold down both sides of it. The three native kinds each speak a real service's protocol, and each has been run against one, though not to the same depth:

Kind Checked against a running service Not exercised
vault Vault 1.18.5 and OpenBao 2.6.2: a keyring wrapped, read back, rotated, CA seeds wrapped, Authority restarted on ciphertext. A namespace (VAULT_NAMESPACE), a private root of trust (VAULT_CACERT), and a token read from ~/.vault-token rather than the environment.
aws The same chain, plus the service's own request validation (a wrong signature, a wrong region, a stale timestamp, headers signed out of order, or a body changed after signing each draw its own refusal; a wrong action name draws another), a ciphertext refused under a key that did not produce it, and the direct-encryption limit measured at the service itself. The role of an EC2 instance, credentials a container runtime hands out, refreshing a temporary credential before it expires, key policies and grants, an interface or compliance endpoint reached through address, and a region outside the default partition.
gcp The same chain, plus the exact shape of the three calls, that protectionLevel = "HSM" is the only level the service accepts from any location, and the signed-assertion exchange for a token. The real metadata server (this run supplied its own), a token actually expiring in real time rather than exercising the below-margin branch, the other kinds of service-account credential file, and telling "not enough permission" apart from "the request is malformed" on a live refusal.

The direct-encryption limit

AWS KMS encrypts at most 4096 bytes of plaintext in one call to Encrypt or Decrypt; GenerateDataKey is unaffected, since it returns its own ciphertext already inside that limit. A CA seed is 32 bytes and is nowhere near it. What can reach the limit is a wrapped keyring, which travels as one document: it holds 20 keys that only seal, or 14 that sign and so carry a public half, before the document stops fitting in one call. A keyring under ordinary rotation holds far fewer, since keys rotate --retire removes a key once nothing seals under it any more; the limit is reachable only by keeping verify-only keys around rather than retiring them. Either way the refusal happens on this side, before anything is sent: it names the limit and the size that was handed to it, and nothing is sent or written.

Top level

Used by: Authority, Proxy, Connector, and the foreground Resident client (profile); Authority (store_url, store_password_file, store_auto_migrate).

Key Type Default Purpose
profile string (optional) unset, no deployment label Deployment name. Labels service metrics, logs, and exported traces. The foreground Resident client labels its journal but exports no service metrics or traces.
store_url string (optional) unset, ~/.gdsgate/state/store.db (persistent file SQLite) State backend Authority consumes: audit chain, the transport CA's private key, the SSH CAs, registration tokens, resource catalog. SQLite (file or :memory:) or PostgreSQL. Unset persists next to the node identity so a restart keeps the same CA; set :memory: only for ephemeral tests.
store_password_file string (optional) unset The state backend's password, kept out of store_url. A path, or a secret reference. PostgreSQL only.
store_auto_migrate bool true Whether a starting service may bring the store's schema up to date itself. false means a service start never changes the schema: a store with pending migrations stops the process, naming how many are pending and the command that applies them.

profile security endpoints store_url store_password_file store_auto_migrate enroll authority transport client proxy policy mcp mfa oidc identity workload ca_rotation ha approvals discovery connector recording admin audit telemetry doctor agent_profiles delegation_profiles kms_keys

profile = "prod-eu"
store_url = "postgres://gdsgate@store-db.example.invalid:5432/gdsgate"
store_auto_migrate = false   # schema changes are a step of the rollout

profile names the deployment. Authority, Proxy and Connector each read it and label their own telemetry with it. Set it and each service Prometheus series carries profile="<value>", each structured service log line carries a profile field, and each exported service trace carries a profile resource attribute. A foreground Resident client also labels its journal, but exports no service metrics or traces. Leave the value unset to omit the label. See Metrics and health.

The value must be non-empty, at most 64 bytes, and drawn from A-Z a-z 0-9 . _ -. It comes from the configuration only: a request, a header or a token cannot set it, and it is read once, at startup. Environment overlay: GDSGATE_PROFILE.

Anything else stops a service (authority, proxy, connector, all, and gdsgate up --foreground) at start, naming the character it refused. Those are the processes that publish under the label. Every other command runs without a label and says so on stderr, since it exports nothing, and gdsgate doctor reports the value as a config.profile finding.

Left unset, store_url defaults to a persistent file SQLite at ~/.gdsgate/state/store.db; set it explicitly for PostgreSQL or a custom path. sqlite::memory: loses everything on restart and is only useful for tests.

store_password_file names the state backend's password separately from store_url, so store_url itself carries only the user (postgres://gdsgate@store-db.example.invalid:5432/gdsgate) and the two are joined only to open a connection. It applies to PostgreSQL only; a SQLite store has no password, and naming both this field and a password inside store_url at once is refused at start-up. A password written directly into store_url still works and is redacted wherever the URL is printed, and gdsgate doctor warns and names this field as the place to move it. Environment overlay: GDSGATE_STORE_PASSWORD_FILE.

store_auto_migrate is on by default, so a start applies whatever the store is missing. Turn it off where a schema change is a scheduled step: the operator runs gdsgate authority migrate once, then starts the fleet. Either way a start refuses a store whose schema is newer than the binary, since that database was migrated by a newer build. Environment overlay: GDSGATE_STORE_AUTO_MIGRATE.

admin admin.endpoint admin.identity_dir admin.transport agent_profiles agent_profiles[].checked agent_profiles[].config_args agent_profiles[].config_env agent_profiles[].config_format agent_profiles[].config_path agent_profiles[].model_config_key agent_profiles[].model_url_env agent_profiles[].model_url_path agent_profiles[].name agent_profiles[].note agent_profiles[].source agent_profiles[].tools_entry agent_profiles[].tools_key approvals approvals.min_approvers approvals.per_environment audit audit.anchor_key_path audit.approval_key_path audit.checkpoint_interval_secs audit.delegation_key_path audit.export_path audit.inventory_key_path audit.revocation_key_path audit.verify_interval_secs authority authority.ca_kms_key authority.emergency_socket authority.enroll_cert_file authority.enroll_key_file ca_rotation ca_rotation.check_secs ca_rotation.enabled ca_rotation.interval_secs ca_rotation.proactive_secs ca_rotation.propagation_secs ca_rotation.retire_secs client client.access client.allow_insecure_http client.direct client.direct.basic_port_range client.direct.catalog_sync_secs client.direct.v4_pool client.intercept_names client.notify client.resolver client.step_up_on_denial client.transparent client.transparent.dns_zone client.transparent.reuse_grace_secs client.transparent.v4_pool client.transparent.v6_pool client.transport_ca client.transport_sni client.warm_access connector connector.authority_transport connector.backends connector.backends[].addr connector.backends[].admin connector.backends[].allow connector.backends[].allow_agent_forward connector.backends[].allow_elicitation_url connector.backends[].allow_encoded_separator connector.backends[].allow_fastpath_function connector.backends[].allow_local_forward connector.backends[].allow_port_forward connector.backends[].allow_remote_forward connector.backends[].allow_unpinned_upstream connector.backends[].allowed_backend_hosts connector.backends[].allowed_input_requests connector.backends[].allowed_models connector.backends[].allowed_query_params connector.backends[].allowed_request_headers connector.backends[].allowed_tools connector.backends[].api_url connector.backends[].audit connector.backends[].auth_mode connector.backends[].ca_path connector.backends[].cage connector.backends[].cage.allow_degraded connector.backends[].cage.cpu_quota connector.backends[].cage.memory_max connector.backends[].cage.private_network connector.backends[].cage.private_tmp connector.backends[].cage.protect_home connector.backends[].cage.read_only_paths connector.backends[].cage.read_write_paths connector.backends[].cage.report_denied_paths connector.backends[].cage.restrict_address_families connector.backends[].cage.tasks_max connector.backends[].command connector.backends[].command_env connector.backends[].credential connector.backends[].credential_file connector.backends[].credential_format connector.backends[].credential_header connector.backends[].db_roles connector.backends[].db_roles[].db_user connector.backends[].db_roles[].name connector.backends[].db_roles[].read_only connector.backends[].decider_ca_path connector.backends[].decider_command connector.backends[].decider_command_env connector.backends[].decider_fail_closed connector.backends[].decider_timeout_ms connector.backends[].decider_url connector.backends[].decision_cache_ttl_secs connector.backends[].discovery connector.backends[].discovery.allowlist connector.backends[].discovery.connection connector.backends[].discovery.denylist connector.backends[].discovery.freshness_secs connector.backends[].discovery.interval_secs connector.backends[].discovery.mode connector.backends[].discovery.password_file connector.backends[].enforce_query_categories connector.backends[].enforce_tool_policy connector.backends[].forwarded_headers connector.backends[].host_key_fingerprints connector.backends[].host_key_fingerprints_file connector.backends[].identity connector.backends[].identity_headers_trust_the_network connector.backends[].inspect connector.backends[].kind connector.backends[].login_user connector.backends[].max_request_bytes connector.backends[].pin_tool_descriptors connector.backends[].record_request connector.backends[].record_response connector.backends[].refuse_unfiltered_tool_listing connector.backends[].resource connector.backends[].routed_ranges connector.backends[].routes connector.backends[].routes[].audit connector.backends[].routes[].match connector.backends[].routes[].name connector.backends[].service_account connector.backends[].service_account_password_file connector.backends[].service_account_tls_ca_file connector.backends[].settable_parameters connector.backends[].statement_timeout_ms connector.backends[].token_path connector.backends[].url connector.backends[].websocket connector.id delegation_profiles delegation_profiles[].agent_profile delegation_profiles[].can delegation_profiles[].env delegation_profiles[].exec delegation_profiles[].exec_args delegation_profiles[].model delegation_profiles[].name delegation_profiles[].renewable delegation_profiles[].sandbox delegation_profiles[].sandbox_allow delegation_profiles[].sandbox_cpu delegation_profiles[].sandbox_memory delegation_profiles[].sandbox_processes delegation_profiles[].ttl_secs discovery discovery.import_rules discovery.import_rules[].environment discovery.import_rules[].labels discovery.import_rules[].match discovery.resources discovery.resources[].aliases discovery.resources[].hostname discovery.resources[].id discovery.resources[].kind discovery.resources[].min_approvers discovery.resources[].native_name discovery.resources[].pin_tool_descriptors discovery.resources[].port discovery.resources[].project doctor doctor.check_interval_secs endpoints endpoints.authority endpoints.authority_enroll endpoints.authority_failover endpoints.proxy_internal endpoints.proxy_join endpoints.proxy_public endpoints.proxy_ws enroll enroll.background_renewal enroll.endpoint enroll.node_name enroll.renew_endpoint enroll.state_dir enroll.token enroll.transport_ca ha ha.enabled ha.lease_ttl_secs ha.owner ha.renew_secs identity identity.allow_system_groups identity.max_groups identity.max_length kms_keys kms_keys[].address kms_keys[].command kms_keys[].key kms_keys[].mount kms_keys[].name kms_keys[].provider kms_keys[].region mcp mcp.destructive_patterns mfa mfa.webauthn mfa.webauthn.allow_any_port mfa.webauthn.allow_localhost mfa.webauthn.origins mfa.webauthn.rp_id mfa.webauthn.rp_origin oidc oidc.allow_insecure_http oidc.audience oidc.client_id oidc.id_token_signing_algs oidc.issuer oidc.jwks_refresh_secs oidc.request_timeout_secs policy policy.editor policy.editor.break_glass_policy_file policy.editor.min_approvers policy.path profile proxy proxy.internal_accept_burst proxy.internal_accept_rate_per_ip proxy.join_accept_burst proxy.join_accept_rate_per_ip proxy.join_idle_timeout_secs proxy.join_max_connections proxy.join_peek_timeout_secs proxy.max_bytes_per_second_per_session proxy.max_public_connections proxy.max_sessions proxy.max_streams_per_tunnel proxy.public_admin_max_connections proxy.public_anonymous_burst proxy.public_anonymous_rate_per_ip proxy.public_cert_file proxy.public_join proxy.public_join_burst proxy.public_join_rate_per_ip proxy.public_key_file proxy.public_origin proxy.public_proxy_protocol_from proxy.public_renewal_max_connections proxy.session_rate_burst_bytes proxy.single_port proxy.web_addr proxy.web_cert_file proxy.web_key_file proxy.webapps_addr proxy.webapps_cert_file proxy.webapps_key_file proxy.webapps_proxy_protocol_from proxy.webapps_session_ttl_secs proxy.webapps_zone recording recording.capture_stdin recording.mode security security.integrity security.integrity.audit_keyring security.integrity.control_keyring security.profile store_auto_migrate store_password_file store_url telemetry telemetry.metrics_listen telemetry.otel_endpoint transport transport.cert_ttl_secs transport.front_sni workload workload.cert_ttl_secs workload.issuers workload.issuers[].audience workload.issuers[].groups workload.issuers[].issuer workload.issuers[].owner_claim workload.issuers[].owner_service workload.issuers[].path_template workload.issuers[].single_use_jti workload.issuers[].slug workload.trust_domain

profile|None security|Security::default() endpoints|Endpoints::default() store_url|None store_password_file|None store_auto_migrate|true enroll|Enroll::default() authority|Authority::default() transport|Transport::default() client|Client::default() proxy|Proxy::default() policy|Policy::default() mcp|Mcp::default() mfa|Mfa::default() oidc|Oidc::default() identity|Identity::default() workload|Workload::default() ca_rotation|CaRotation::default() ha|Ha::default() approvals|Approvals::default() discovery|Discovery::default() connector|Connector::default() recording|Recording::default() admin|Admin::default() telemetry|Telemetry::default() doctor|Doctor::default() agent_profiles|Vec::new() delegation_profiles|Vec::new() kms_keys|Vec::new()

Environment overrides

Each configuration override listed below overlays the file; an unset variable changes nothing. Other GDSGATE_* variables can be command inputs or switches instead. Use the supported overrides for secrets and per-host values.

Variable Overrides
GDSGATE_PROFILE profile
GDSGATE_STORE_URL store_url
GDSGATE_STORE_PASSWORD_FILE store_password_file
GDSGATE_STORE_AUTO_MIGRATE store_auto_migrate
GDSGATE_AUTH_ADDR endpoints.authority
GDSGATE_AUTH_ENROLL_ADDR endpoints.authority_enroll
GDSGATE_PROXY_PUBLIC_ADDR endpoints.proxy_public
GDSGATE_PROXY_INTERNAL_ADDR endpoints.proxy_internal
GDSGATE_PROXY_WS_ADDR endpoints.proxy_ws
GDSGATE_PROXY_JOIN_ADDR endpoints.proxy_join
GDSGATE_ENROLL_ENDPOINT enroll.endpoint
GDSGATE_ENROLL_TOKEN enroll.token
GDSGATE_ENROLL_STATE_DIR enroll.state_dir
GDSGATE_ENROLL_RENEW_ENDPOINT enroll.renew_endpoint
GDSGATE_ENROLL_NODE_NAME enroll.node_name
GDSGATE_CLIENT_TRANSPORT_CA client.transport_ca
GDSGATE_CLIENT_TRANSPORT_SNI client.transport_sni
GDSGATE_CLIENT_ALLOW_INSECURE_HTTP client.allow_insecure_http
GDSGATE_PROXY_SINGLE_PORT proxy.single_port
GDSGATE_POLICY_PATH policy.path
GDSGATE_OIDC_ISSUER oidc.issuer
GDSGATE_OIDC_CLIENT_ID oidc.client_id
GDSGATE_OIDC_AUDIENCE oidc.audience
GDSGATE_OIDC_ALLOW_INSECURE_HTTP oidc.allow_insecure_http
GDSGATE_OIDC_JWKS_REFRESH_SECS oidc.jwks_refresh_secs
GDSGATE_OIDC_REQUEST_TIMEOUT_SECS oidc.request_timeout_secs
GDSGATE_IDENTITY_ALLOW_SYSTEM_GROUPS identity.allow_system_groups
GDSGATE_IDENTITY_MAX_LENGTH identity.max_length
GDSGATE_IDENTITY_MAX_GROUPS identity.max_groups
GDSGATE_CONNECTOR_ID connector.id
GDSGATE_CONNECTOR_AUTH_TRANSPORT connector.authority_transport
GDSGATE_CA_ROTATION_ENABLED ca_rotation.enabled
GDSGATE_CA_ROTATION_INTERVAL_SECS ca_rotation.interval_secs
GDSGATE_CA_ROTATION_PROACTIVE_SECS ca_rotation.proactive_secs
GDSGATE_CA_ROTATION_PROPAGATION_SECS ca_rotation.propagation_secs
GDSGATE_CA_ROTATION_RETIRE_SECS ca_rotation.retire_secs
GDSGATE_CA_ROTATION_CHECK_SECS ca_rotation.check_secs
GDSGATE_HA_ENABLED ha.enabled
GDSGATE_HA_OWNER ha.owner
GDSGATE_HA_LEASE_TTL_SECS ha.lease_ttl_secs
GDSGATE_HA_RENEW_SECS ha.renew_secs
GDSGATE_AUDIT_ANCHOR_KEY_PATH audit.anchor_key_path
GDSGATE_AUDIT_APPROVAL_KEY_PATH audit.approval_key_path
GDSGATE_AUDIT_REVOCATION_KEY_PATH audit.revocation_key_path
GDSGATE_AUDIT_DELEGATION_KEY_PATH audit.delegation_key_path
GDSGATE_AUDIT_INVENTORY_KEY_PATH audit.inventory_key_path
GDSGATE_AUDIT_EXPORT_PATH audit.export_path
GDSGATE_TELEMETRY_METRICS_LISTEN telemetry.metrics_listen
GDSGATE_TELEMETRY_OTEL_ENDPOINT telemetry.otel_endpoint

GDSGATE_ADMIN_ENDPOINT GDSGATE_ADMIN_IDENTITY_DIR GDSGATE_ADMIN_TRANSPORT GDSGATE_AUDIT_ANCHOR_KEY_PATH GDSGATE_AUDIT_APPROVAL_KEY_PATH GDSGATE_AUDIT_DELEGATION_KEY_PATH GDSGATE_AUDIT_EXPORT_PATH GDSGATE_AUDIT_INVENTORY_KEY_PATH GDSGATE_AUDIT_REVOCATION_KEY_PATH GDSGATE_AUTH_ADDR GDSGATE_AUTH_ENROLL_ADDR GDSGATE_CA_ROTATION_CHECK_SECS GDSGATE_CA_ROTATION_ENABLED GDSGATE_CA_ROTATION_INTERVAL_SECS GDSGATE_CA_ROTATION_PROACTIVE_SECS GDSGATE_CA_ROTATION_PROPAGATION_SECS GDSGATE_CA_ROTATION_RETIRE_SECS GDSGATE_CLIENT_ALLOW_INSECURE_HTTP GDSGATE_CLIENT_TRANSPORT_CA GDSGATE_CLIENT_TRANSPORT_SNI GDSGATE_CONNECTOR_AUTH_TRANSPORT GDSGATE_CONNECTOR_ID GDSGATE_ENROLL_ENDPOINT GDSGATE_ENROLL_NODE_NAME GDSGATE_ENROLL_RENEW_ENDPOINT GDSGATE_ENROLL_STATE_DIR GDSGATE_ENROLL_TOKEN GDSGATE_HA_ENABLED GDSGATE_HA_LEASE_TTL_SECS GDSGATE_HA_OWNER GDSGATE_HA_RENEW_SECS GDSGATE_IDENTITY_ALLOW_SYSTEM_GROUPS GDSGATE_IDENTITY_MAX_GROUPS GDSGATE_IDENTITY_MAX_LENGTH GDSGATE_OIDC_ALLOW_INSECURE_HTTP GDSGATE_OIDC_AUDIENCE GDSGATE_OIDC_CLIENT_ID GDSGATE_OIDC_ISSUER GDSGATE_OIDC_JWKS_REFRESH_SECS GDSGATE_OIDC_REQUEST_TIMEOUT_SECS GDSGATE_POLICY_PATH GDSGATE_PROFILE GDSGATE_PROXY_INTERNAL_ADDR GDSGATE_PROXY_JOIN_ADDR GDSGATE_PROXY_PUBLIC_ADDR GDSGATE_PROXY_SINGLE_PORT GDSGATE_PROXY_WS_ADDR GDSGATE_STORE_AUTO_MIGRATE GDSGATE_STORE_PASSWORD_FILE GDSGATE_STORE_URL GDSGATE_TELEMETRY_METRICS_LISTEN GDSGATE_TELEMETRY_OTEL_ENDPOINT

| GDSGATE_ADMIN_ENDPOINT | admin.endpoint | | GDSGATE_ADMIN_IDENTITY_DIR | admin.identity_dir | | GDSGATE_ADMIN_TRANSPORT | admin.transport |

A few client-only variables are not config overrides but switches:

Variable Purpose
GDSGATE_ID_TOKEN Identity token a client command should present (headless / CI).
GDSGATE_USER Local-dev principal name when no [oidc] is configured.
RUST_LOG Log filter. Default warn,gdsgate=info: gdsgate* at INFO, everything else at WARN. A set value replaces the default.

The [[connector.backends]] list is structured data and has no environment override; it is file-only.