Managing Secrets
Relevant source files
The following files were used as context for generating this wiki page:- charts/agh3/values.yaml
- charts/agh2/values.yaml
- charts/agh3/templates/captain/captain-superadmin-secret.yml
- charts/agh3/templates/minio/agh-minio-users-secret.yml
- charts/agh3/templates/base/rabbitmq-secret.yml
- charts/agh3/templates/captain/captain-deployment.yml
- charts/agh2/templates/db/postgres-init-configmap.yml
- charts/agh3/templates/captain/captain-db-secret.yml
- charts/agh3/templates/validations/index.yaml
- charts/agh3/templates/controller/controller-minio-secret.yml
- charts/agh3/templates/captain/captain-oidc-secret.yml
Secrets management within the helm-charts repository is handled through the creation of Kubernetes Secret objects, which are dynamically generated by Helm templates. This system provides a flexible mechanism for handling sensitive information such as passwords, API tokens, and connection strings for various application components and their dependencies like PostgreSQL, Minio, and RabbitMQ.
The primary method of configuration is through the values.yaml file for each chart (e.g., agh2, agh3). Administrators can enable or disable secret generation for each component, provide explicit credential values, or rely on a built-in dynamic password generation mechanism. This approach centralizes secret configuration while leveraging Kubernetes-native secret management for runtime consumption.
Core Concepts
Configuration via values.yaml
All secrets are controlled by settings within the values.yaml file. Each component that requires secrets has a dedicated section, typically under <component>.secret. This allows for granular control over each secret's creation and content.
Key configuration parameters include:
| Parameter | Description | Example Path |
|---|---|---|
enabled | A boolean to enable or disable the creation of a specific secret or group of secrets. | captain.secret.enabled |
secretName | The name of the Kubernetes Secret object to be created. | captain.secret.db.secretName |
user | The username for a service credential. | captain.secret.db.user |
password | The password for a service credential. If left empty, a password may be dynamically generated. | captain.secret.db.password |
Sources: charts/agh3/values.yaml:400-435, charts/agh2/values.yaml:260-290
Dynamic Password Generation
A key feature of the secret management system is the ability to dynamically generate passwords if they are not explicitly provided in values.yaml. This is accomplished using a Helm template helper named specify-password.
The logic is as follows:
- Check if a password value is provided (e.g.,
.Values.captain.secret.superadmin.password). - If it is, use the provided value.
- If it is not, call the
specify-passwordhelper. This helper uses thekeygen.apiToken, the ingress host (domain), and a uniqueprefix(often the secret name) to generate a deterministic password.
The following diagram illustrates this password generation flow.
This pattern is used consistently across numerous secret templates, such as for the superadmin password, database connections, and Minio credentials. For Minio passwords, the generated value is also truncated to 40 characters.
Sources: charts/agh3/templates/captain/captain-superadmin-secret.yml:9-20, charts/agh3/templates/controller/controller-minio-secret.yml:10-21
Secret Types and Examples
The charts define several categories of secrets, each tailored to a specific service or component.
Database Secrets
Database secrets are created for each application component that requires a database connection (e.g., Captain, Core, Exploit-Manager). These secrets typically contain a single key, DB_CONN_STR, which holds the full PostgreSQL connection string.
A helper template (db-connection-string or connection-string) assembles this string using values for the driver, user, host, port, and database name. The password component of the string is resolved using the dynamic generation logic described above.
# Example from charts/agh3/templates/captain/captain-db-secret.yml
apiVersion: v1
kind: Secret
metadata:
name: capt-db-secret
stringData:
DB_CONN_STR: "postgresql://agh-captain:<password>@db.default.svc.cluster.local:5432/captain-db?sslmode=disable"
These credentials are also used during database initialization. The postgres-init-configmap.yml script reads these values to create the necessary roles and databases within the PostgreSQL instance.
Sources: charts/agh3/templates/captain/captain-db-secret.yml:1-24, charts/agh2/templates/db/postgres-init-configmap.yml:45-78
Minio Secrets
The system uses two patterns for managing Minio credentials:
- Individual Secrets: Each component can have its own secret (e.g.,
capt-minio-secret) containing its user and password. - Shared User Secret: In
agh3, a single secret namedagh-minio-users-secretis created to provision multiple users at once for the internal Minio instance.
The agh-minio-users-secret is particularly notable. It contains data keys for each Minio user (captain, controller, parser, packet), where each key's value is a multi-line string defining the username, password, and associated policies.
The diagram below shows how values.yaml contributes to the creation of the shared Minio user secret.
RabbitMQ Secrets
The RabbitMQ secret (agh-rabbitmq-secret) is a multi-purpose secret generated when rabbitmq.secret.enabled is true. It contains:
usernameandpasswordfor authentication.uriandmanager-urifor client and management connections.- A
load_definition.jsonblock, which is used by the RabbitMQ chart to automatically provision users, vhosts, queues, and permissions on startup.
Additionally, a second secret (<secretName>-connection) is created containing just the RABBITMQ_CONN_STR, which is consumed by application pods.
Sources: charts/agh3/templates/base/rabbitmq-secret.yml:1-85
Application-Specific Secrets
Other secrets are created for application-level configuration:
- Superadmin Password: (
capt-superadmin-password) Holds theSUPERADMIN_PASSWORDfor the Captain service. - JWT Secret: (
capt-jwt-secret) Holds thejwt-secretused for signing JSON Web Tokens. - OIDC Secret: (
capt-oidc-secret) Stores OIDC provider details likeurl,client-id,client-secret, andrealmwhen OIDC authentication is enabled.
Sources: charts/agh3/templates/captain/captain-superadmin-secret.yml:1-22, charts/agh3/templates/captain/captain-oidc-secret.yml:1-11, charts/agh3/values.yaml:423-435
Secret Consumption
Secrets are primarily consumed by application containers as environment variables. The captain-deployment.yml file provides a clear example of this pattern. Secret values are mapped to environment variables using valueFrom.secretKeyRef.
The following table details how the Captain deployment consumes various secrets:
| Environment Variable | Secret Name | Secret Key |
|---|---|---|
SUPERADMIN_PASSWORD | {{ .Values.captain.secret.superadmin.secretName }} | SUPERADMIN_PASSWORD |
DB_Conn | {{ .Values.captain.secret.db.secretName }} | DB_CONN_STR |
SECRET_JWT | {{ .Values.captain.secret.jwt.secretName }} | jwt-secret |
MINIO_USER | {{ .Values.captain.secret.minio.secretName }} | capt-minio-user |
MINIO_PASSWORD | {{ .Values.captain.secret.minio.secretName }} | capt-minio-password |
RABBITMQ_Conn | {{ .Values.rabbitmq.secret.secretName }}-connection | RABBITMQ_CONN_STR |
OIDC_LOGIN_URL | {{ .Values.captain.secret.oidc.secretName }} | url |
This sequence diagram illustrates how a pod uses these environment variables to connect to dependent services.
Validation
To prevent deployment failures due to missing configuration, the charts include a validation step. The validations/index.yaml template checks for the existence of required values when certain features are enabled. For example, if keygen.enabled is set to true, the template verifies that keygen.accountID and keygen.apiToken are also provided. If any validation fails, the Helm installation will be aborted with a descriptive error message.