Class AbstractVaultProviderFactory

All Implemented Interfaces:
ProviderFactory<VaultProvider>, VaultProviderFactory
Direct Known Subclasses:
FilesKeystoreVaultProviderFactory, FilesPlainTextVaultProviderFactory

public abstract class AbstractVaultProviderFactory extends Object implements VaultProviderFactory
Abstract class that is meant to be extended by implementations of VaultProviderFactory that want to offer support for the configuration of key resolvers.

It implements the init(Config.Scope) method, where is looks for the keyResolvers property. The value is a comma-separated list of key resolver names. It then verifies if the resolver names match one of the available key resolver implementations and then creates a list of VaultKeyResolver instances that subclasses can pass to VaultProvider instances on ProviderFactory.create(KeycloakSession).

The list of currently available resolvers follows:

  • KEY_ONLY: only the key name is used as is, realm is ignored;
  • REALM_UNDERSCORE_KEY: realm and key are combined using an underscore ('_') character. Any occurrences of underscore in both the realm and key are escaped by an additional underscore character;
  • REALM_FILESEPARATOR_KEY: realm and key are combined using the platform file separator character. It might not be suitable for every vault provider but it enables the grouping of secrets using a directory structure;
  • FACTORY_PROVIDED: the format of the constructed key is determined by the factory's getFactoryResolver() implementation. it allows for the customization of the final key format by extending the factory and overriding the getFactoryResolver() method.

Note: When extending the standard factories to use the FACTORY_PROVIDED resolver, it is important to also override the ProviderFactory.getId() method so that the custom factory has its own id and as such can be configured in the keycloak server.

If no resolver is explicitly configured for the factory, it defaults to using the REALM_UNDERSCORE_KEY resolver. When one or more resolvers are explicitly configured, this factory iterates through them in order and for each one attempts to obtain the respective VaultKeyResolver implementation. If it fails (for example, the name doesn't match one of the existing resolvers), it logs a message and ignores the resolver. If it fails to load all configured resolvers, it throws a VaultConfigurationException.

Concrete implementations must also make sure to call the super.init(config) in their own init(Config.Scope) implementations so tha the processing of the key resolvers is performed correctly.

Stefan Guilhen