Editing Manager Settings After Install
Overview
Section titled “Overview”QHx Manager reads its configuration from a Kubernetes ConfigMap at startup and watches it for changes at runtime. Most settings take effect immediately without restarting the manager pod. Sensitive settings such as database credentials are stored separately in a Kubernetes Secret and overlaid onto the ConfigMap configuration.
Target audience: Platform operators, cluster administrators.
How Configuration Works
Section titled “How Configuration Works”The manager reads two Kubernetes objects:
| Object | Name | Purpose |
|---|---|---|
ConfigMap | qhx-manager (in qhx-system) | All non-sensitive settings |
Secret | Configured via --secret-name flag (optional) | Sensitive overrides (e.g. database DSN) |
Both objects are watched via the Kubernetes watch API. When either changes, the manager reloads configuration without restarting. The active configuration is logged at reload time.
The ConfigMap stores a single key qhx-manager.yaml whose value is a YAML document. The Secret (if configured) stores a key qhx-manager-secret.yaml with the same YAML format — only non-zero values in the Secret take effect as overrides.
Viewing the Current Configuration
Section titled “Viewing the Current Configuration”kubectl get configmap qhx-manager -n qhx-system -o yamlTo see just the parsed settings:
kubectl get configmap qhx-manager -n qhx-system \ -o jsonpath='{.data.qhx-manager\.yaml}'To see whether a Secret overlay is configured, check the manager’s flags:
kubectl get deployment manager -n qhx-system \ -o jsonpath='{.spec.template.spec.containers[0].args}'Look for --secret-name and --secret-namespace in the output.
Editing Settings
Section titled “Editing Settings”Edit the ConfigMap directly:
kubectl edit configmap qhx-manager -n qhx-systemThe manager detects the change and reloads within a few seconds. You can confirm the reload in the manager logs:
kubectl logs -n qhx-system deploy/manager --since=1m | grep "Configuration loaded"Alternatively, apply a patch:
kubectl patch configmap qhx-manager -n qhx-system --type merge \ -p '{"data":{"qhx-manager.yaml":"<full yaml content>"}}'Because the value is a multi-line YAML string embedded in JSON, it is usually easier to edit the file locally and kubectl apply it:
kubectl get configmap qhx-manager -n qhx-system -o yaml > qhx-manager-cm.yaml# edit qhx-manager-cm.yamlkubectl apply -f qhx-manager-cm.yamlSettings Reference
Section titled “Settings Reference”All settings live under the qhx-manager.yaml key in the ConfigMap.
Images
Section titled “Images”| Field | Default | Description |
|---|---|---|
qhxProxyImage | set at install | OCI image reference for the QHx proxy sidecar |
pkiServerImage | set at install | OCI image reference for the SPIRE server (qhx-upki-server) |
pkiAgentImage | set at install | OCI image reference for the SPIRE agent (qhx-upki-agent) |
pkiControllerManagerImage | set at install | OCI image reference for the SPIRE controller manager |
spiffeCSIDriverImage | set at install | OCI image reference for the SPIFFE CSI driver |
initImage | set at install | OCI image reference for the init container |
imagePullPolicy | IfNotPresent | Kubernetes image pull policy (Always, IfNotPresent, Never) |
Identity and Trust
Section titled “Identity and Trust”| Field | Default | Description |
|---|---|---|
trustDomain | set at install | SPIFFE trust domain for this cluster (e.g. example.org) |
clusterName | set at install | Logical name for this cluster, used in federation |
PKI / SPIRE Server
Section titled “PKI / SPIRE Server”| Field | Default | Description |
|---|---|---|
pkiServerReplicas | 1 | Number of SPIRE server replicas. Set to 2 or more to enable HA. Requires pkiDatastoreConnectionString (see Sensitive Settings) |
pkiStorageClassName | "" | StorageClass for per-replica PKI data PVCs. Empty string uses the cluster default |
pkiStorageSize | 1Gi | Storage capacity for each PKI data PVC |
| Field | Default | Description |
|---|---|---|
proxyPort | set at install | Port the QHx proxy listens on |
proxyConfigMapNamespace | set at install | Namespace of the ConfigMap that holds proxy configuration |
proxyConfigMapName | set at install | Name of the ConfigMap that holds proxy configuration |
Policy Engine
Section titled “Policy Engine”| Field | Default | Description |
|---|---|---|
policyRateLimit.qps | 5 | Maximum policy evaluation requests per second |
policyRateLimit.burst | 20 | Maximum burst size for policy evaluations |
policyRateLimit.backoffMax | 30s | Maximum backoff duration when the rate limit is exceeded |
SPIRE Instance Lifecycle
Section titled “SPIRE Instance Lifecycle”| Field | Default | Description |
|---|---|---|
spireInstanceCooldown | set at install | Minimum time to wait before deleting an unused SPIRE instance after all its namespaces are removed |
spireNamespaceMapConfigMap | set at install | Name of the ConfigMap that maps namespaces to SPIRE instance hashes |
spireSocketBaseDir | set at install | Base directory on nodes where SPIRE agent sockets are created |
Agent Metrics
Section titled “Agent Metrics”| Field | Default | Description |
|---|---|---|
agentMetricsPortBase | 39000 | First port in the range reserved for SPIRE agent Prometheus metrics endpoints |
agentMetricsPortCount | 1024 | Number of ports in the agent metrics port range |
Federation
Section titled “Federation”| Field | Default | Description |
|---|---|---|
bundleExchangeInterval | 5m | How often the manager reconciles federation trust bundle exchanges between clusters |
| Field | Default | Description |
|---|---|---|
tpmSupportEnabled | false | Enable TPM-backed node attestation. Requires TPM hardware on all nodes |
Sensitive Settings
Section titled “Sensitive Settings”Settings that contain credentials or connection strings must not be stored in the ConfigMap, as ConfigMaps are not encrypted at rest by default. Instead, store them in a Kubernetes Secret whose key is qhx-manager-secret.yaml.
The Secret is only used when the manager is started with the --secret-name and --secret-namespace flags (configured at install time via Helm values). The Secret is also watched at runtime — updating it reloads the manager configuration without a restart.
Currently the only sensitive setting is:
| Field | Description |
|---|---|
pkiDatastoreConnectionString | PostgreSQL DSN for the shared SPIRE datastore. Required when pkiServerReplicas > 1 |
Creating or Updating the Secret
Section titled “Creating or Updating the Secret”kubectl create secret generic qhx-manager-secret \ -n qhx-system \ --from-literal=qhx-manager-secret.yaml='pkiDatastoreConnectionString: "postgresql://spire:password@db.example.com:5432/spire?sslmode=require"' \ --dry-run=client -o yaml | kubectl apply -f -The --dry-run=client -o yaml | kubectl apply pattern is safe to use for both initial creation and updates.
To verify the Secret is being picked up:
kubectl logs -n qhx-system deploy/manager --since=1m | grep -E "Configuration loaded|overlay"Example: Enabling HA After Install
Section titled “Example: Enabling HA After Install”The following steps enable multi-replica PKI servers on a cluster that was initially installed in single-replica mode.
1. Create the Secret with the PostgreSQL DSN (if not already configured at install):
kubectl create secret generic qhx-manager-secret \ -n qhx-system \ --from-literal=qhx-manager-secret.yaml='pkiDatastoreConnectionString: "postgresql://spire:password@db.example.com:5432/spire?sslmode=require"' \ --dry-run=client -o yaml | kubectl apply -f -If the --secret-name flag is not already set on the manager deployment, add it via Helm upgrade:
helm upgrade qhx-core ./qhx-core-chart \ --namespace qhx-system \ --reuse-values \ --set secretName=qhx-manager-secret \ --set secretNamespace=qhx-system2. Update the ConfigMap to set the replica count:
kubectl get configmap qhx-manager -n qhx-system -o yaml > qhx-manager-cm.yamlEdit qhx-manager-cm.yaml and add/update these fields inside qhx-manager.yaml:
pkiServerReplicas: 2pkiStorageClassName: "" # uses cluster default StorageClasspkiStorageSize: "1Gi"Apply the change:
kubectl apply -f qhx-manager-cm.yamlThe manager reloads immediately. It reconciles the SPIRE StatefulSet to the new replica count and provisions per-replica PVCs from the configured StorageClass.
Reload Behavior
Section titled “Reload Behavior”- ConfigMap changes: Detected within a few seconds via the Kubernetes watch API. All settings are reloaded atomically.
- Secret changes: Detected on the same watch loop as the ConfigMap. The Secret overlay is re-applied on every reload.
- No restart required: The manager pod does not need to be restarted for any ConfigMap or Secret change to take effect.
- Reconciliation: After a reload, the manager re-reconciles all
QHxClusterPolicyandQHxPolicyresources. Changes to SPIRE server configuration (replica count, storage, image) cause the affectedStatefulSetto be updated, which Kubernetes applies as a rolling update.