[[_vault-administration]] == Using a vault to obtain secrets To obtain a secret from a vault rather than entering it directly, enter the following specially crafted string into the appropriate field: [source] ---- ${vault.key} ---- where the `key` is the name of the secret recognized by the vault. To prevent secrets from leaking across realms, {project_name} combines the realm name with the `key` obtained from the vault expression. This method means that the `key` does not directly map to an entry in the vault but creates the final entry name according to the algorithm used to combine the `key` with the realm name. You can obtain the secret from the vault in the following fields: SMTP password:: In the realm <<_email,SMTP settings>> LDAP bind credential:: In the <<_ldap,LDAP settings>> of LDAP-based user federation. OIDC identity provider secret:: In the _Client Secret_ inside identity provider <<_identity_broker_oidc,OpenID Connect Config>> === Key resolvers All built-in providers support the configuration of key resolvers. A key resolver implements the algorithm or strategy for combining the realm name with the key, obtained from the `${vault.key}` expression, into the final entry name used to retrieve the secret from the vault. {project_name} uses the `keyResolvers` property to configure the resolvers that the provider uses. The value is a comma-separated list of resolver names. An example of the configuration for the `files-plaintext` provider follows: [source,bash] ---- kc.[sh.bat] start --spi-vault-file-key-resolvers=REALM_UNDERSCORE_KEY,KEY_ONLY ---- The resolvers run in the same order you declare them in the configuration. For each resolver, {project_name} uses the last entry name the resolver produces, which combines the realm with the vault key to search for the vault's secret. If {project_name} finds a secret, it returns the secret. If not, {project_name} uses the next resolver. This search continues until {project_name} finds a non-empty secret or runs out of resolvers. If {project_name} finds no secret, {project_name} returns an empty secret. In the previous example, {project_name} uses the `REALM_UNDERSCORE_KEY` resolver first. If {project_name} finds an entry in the vault that using that resolver, {project_name} returns that entry. If not, {project_name} searches again using the `KEY_ONLY` resolver. If {project_name} finds an entry by using the `KEY_ONLY` resolver, {project_name} returns that entry. If {project_name} uses all resolvers, {project_name} returns an empty secret. A list of the currently available resolvers follows: |=== |Name |Description | KEY_ONLY | {project_name} ignores the realm name and uses the key from the vault expression. | REALM_UNDERSCORE_KEY | {project_name} combines the realm and key by using an underscore character. {project_name} escapes occurrences of underscores in the realm or key with another underscore character. For example, if the realm is called `master_realm` and the key is `smtp_key`, the combined key is `master+++__+++realm_smtp+++__+++key`. | REALM_FILESEPARATOR_KEY | {project_name} combines the realm and key by using the platform file separator character. ifeval::[{project_community}==true] | FACTORY_PROVIDED | {project_name} combines the realm and key by using the vault provider factory's `VaultKeyResolver`, allowing the creation of a custom key resolver by extending an existing factory and implementing the `getFactoryResolver` method. endif::[] |=== If you have not configured a resolver for the built-in providers, {project_name} selects the `REALM_UNDERSCORE_KEY`.