Generated applications keep several credentials in their configuration file (Configuracoes.xml): database logins, e-mail servers, SSRS, messaging, the machine key, OAuth2 client secrets, password-type extra properties, and so on. By default these values are stored inline in base64. Base64 is an encoding, not encryption, so anyone who can read the file can read every password, and its protection relies entirely on the file system permissions.
A Secrets Provider is an external service dedicated to storing secrets, with its own access control, auditing and rotation. Webadmin can be configured to keep the configuration secrets in a secrets provider instead of the configuration file. The configuration file then only keeps a reference to each secret, such as vault:QUIDVUE/datasystem/2024/password, and the real value is read from the provider when the application needs it.
There are three types of secrets providers: Legacy, HashiCorp Vault and Azure Key Vault. By default, the provider is Legacy, so installations that don't configure a provider keep working exactly as before.
The way administrators enter passwords does not change. Passwords entered anywhere in Webadmin (data systems, e-mail servers, Elasticsearch, messaging, extra properties, ...) are written to the selected provider when the configuration is saved.
The secrets provider is configured in System Setup > System, in the Secrets provider card.

Saving is all-or-nothing. The secrets are written to the provider before the configuration file, so if the provider is unreachable or rejects a write, the configuration file is left untouched and the error is shown with its details.
The credentials used to access the provider itself (tokens, AppRole secret ids, ...) are never kept in the configuration file. They are read from files, environment variables or the ambient identity of the server, as described for each provider below.
NOTE: Both the application and Webadmin read the same configuration file, so both need access to the provider. Make sure the environment variables, files or identity are available to every process that uses the configuration, including AdminCLI.
The default provider. The secrets are kept inline in the configuration file itself, encoded in base64. It has no options.
This is the behaviour of every installation that doesn't configure a provider.
HashiCorp Vault is a widely used tool to store and control access to secrets. Webadmin uses its KV version 2 secrets engine over its HTTP API.
Each secret is kept in a path of the engine, with the value in a single field (by default value). New secrets are created under a base path, by default the system acronym, for example QUIDVUE/datasystem/2024/password.
To prepare the vault:
secret mount of a Vault server is already KV version 2).
vault secrets enable -path=secret kv-v2read capability.
path "secret/data/QUIDVUE/*" {
capabilities = ["create", "read", "update"]
}VAULT_TOKEN environment variable or in a file set in the Token file option.VAULT_SECRET_ID environment variable or in a file set in the AppRole secret id file option. AppRole is recommended for production, since the application logs in again by itself when its token expires.WebAdmin configuration:
https://vault.example.com:8200. Defaults to the VAULT_ADDR environment variable. Either one is required.secret.value.VAULT_NAMESPACE environment variable.token (default) or approle.VAULT_TOKEN environment variable.VAULT_SECRET_ID environment variable.approle.References to this provider have the form vault:<path>, relative to the mount. A secret can be checked with the Vault CLI, for example:
vault kv get -mount=secret QUIDVUE/datasystem/2024/password
For testing it's recommended to use a Vault development server (vault server -dev), which already has a KV v2 engine mounted in secret and prints a root token on startup.
Azure Key Vault is the Microsoft Azure cloud service for storing secrets, keys and certificates.
Authentication uses the ambient Azure identity of the server (managed identity, environment variables, workload identity, Azure CLI, ...), through DefaultAzureCredential. No credentials are kept in the configuration.
Key Vault names only allow letters, digits and dashes, so the names of new secrets join a prefix and the parts of the identifier with -, for example QUIDVUE-datasystem-2024-password. The prefix defaults to the system acronym.
To prepare the vault:
AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET environment variables on the server.WebAdmin configuration:
https://myvault.vault.azure.net/References to this provider have the form akv:<name>, or akv:<name>/<version> to pin a specific version of the secret. Saving a new value always creates a new version and references the latest one.
NOTE: The Azure Key Vault provider is experimental.
When an external provider is selected, the option Migrate the secrets kept in the file when saving moves the passwords currently kept inline in the configuration file into the provider the next time the configuration is saved. This way an installation can adopt a vault without retyping every credential. After saving, the configuration file only holds references.
If the option is not checked, the old inline values and the new references coexist in the same file, and both keep working. Only the passwords changed from then on are written to the provider.
When the provider is changed from an external one to another (for example from HashiCorp Vault to Azure Key Vault, or back to Legacy), Webadmin shows the option Move the secrets of the previous provider to the new one, checked by default.
When saving, the secrets are read from the previous provider and written to the new one (or inline in the file, when switching to Legacy). The previous provider must be reachable while saving. If any read or write fails, the configuration file is left untouched.
If the option is unchecked, a warning explains that the secrets referenced in the previous provider will no longer be resolved after this change. Those passwords will then have to be entered again.
NOTE: Secrets are never deleted from a provider. Secrets that are no longer referenced, after switching provider or replacing a data system, stay in the vault and can be removed by its administrators.
Both external providers have a Read only option, so the application can use a vault identity without write permissions. This is useful when the operations team manages the secrets and the application must not change them.
In read-only mode Webadmin can't save a new password. The secrets must be created in the vault by its administrators, and the references written in the configuration file by hand. When a password is changed in Webadmin, the save fails and the error tells exactly which secret must be created and which reference is expected in the configuration.
The secrets are named after the following identifiers, under the base path (HashiCorp Vault) or with the prefix (Azure Key Vault):
| Identifier | Secret |
|---|---|
datasystem/<name>/login and datasystem/<name>/password |
Data system credentials |
datasystem/<name>/log/login and datasystem/<name>/log/password |
Log database credentials of a data system |
auxsystem/<name>/login and auxsystem/<name>/password |
Auxiliary system credentials |
ssrs/username and ssrs/password |
Reporting Services credentials |
security/<application>/machinekey |
Machine key of an application |
chatbot/<application>/jwtkey |
Chatbot JWT key of an application |
elasticsearch/<core>/password |
Elasticsearch password |
email/<id>/password |
E-mail server password |
email/<id>/oauth2/clientsecret and email/<id>/oauth2/thumbprint |
E-mail server OAuth2 credentials |
messaging/host/username and messaging/host/password |
Messaging credentials |
property/<name> |
Password-type extra property |
For example, the password of data system 2024 of system QUIDVUE is kept in QUIDVUE/datasystem/2024/password in HashiCorp Vault (reference vault:QUIDVUE/datasystem/2024/password), or in QUIDVUE-datasystem-2024-password in Azure Key Vault (reference akv:QUIDVUE-datasystem-2024-password).
Resolved secrets are kept in memory for the configured cache duration, so the provider isn't called on every request.
If the provider becomes unavailable when a cached secret expires, the last known value is served for up to 30 seconds while the vault recovers, and a warning is logged. A short outage of the vault therefore does not immediately take the application down. Longer outages make the operations that need a secret fail, for example the database connection, and the dashboard of Webadmin shows the error returned by the provider.
Stored passwords are not sent back to the browser. In the Elasticsearch and messaging settings, leaving the password field empty keeps the current password.
Creating a new data system, either for a new year or by copying the default one, gives it its own copy of the credentials in the provider, so changing the password of one data system doesn't affect the other.
The AdminCLI commands use the configured provider:
dbconfig-read shows the decoded login and password of the data systems, read from the provider.config get masks the value of password-type extra properties.config set stores the value of password-type extra properties in the provider.Manual code in client applications that decodes the configuration passwords by hand (for example with Convert.FromBase64String) keeps working with the Legacy provider, but fails once an external provider is configured, because a reference isn't base64. It must use the configuration accessors instead, such as PasswordDecode(), LoginDecode(), SetPassword() or GetPropertySecret(), which resolve both inline values and references.
More details about the design, the formats and how to add new secret fields or providers can be found in CSGenio.core/config/secrets/Design-secrets-provider.md, included in every generated application.