Secret Store Plugin Development¶
This guide describes how to develop a custom secret store plugin for use by Barbican.
Barbican supports two storage modes for secrets: a secret store mode (detailed on this page), and a cryptographic mode. The secret store mode offloads both encryption/decryption and encrypted secret storage to the plugin implementation. Barbican includes plugin interfaces to a Red Hat Dogtag service and to a Key Management Interoperability Protocol (KMIP) compliant security appliance.
Since the secret store mode defers the storage of encrypted secrets to plugins, Barbican core does not need to store encrypted secrets into its data store, unlike the cryptographic mode. To accommodate the discrepancy between the two secret storage modes, a secret store to cryptographic plugin adapter has been included in Barbican core, as detailed in The Cryptographic Plugin Adapter section below.
secret_store
Module¶
The barbican.plugin.interface.secret_store
module contains the classes
needed to implement a custom plugin. These classes include the
SecretStoreBase
abstract base class which custom plugins should inherit
from, as well as several Data Transfer Object (DTO) classes used to transfer
data between Barbican and the plugin.
Data Transfer Objects¶
The DTO classes are used to wrap data that is passed from Barbican to the plugin as well as data that is returned from the plugin back to Barbican. They provide a level of isolation between the plugins and Barbican’s internal data models.
- class barbican.plugin.interface.secret_store.SecretDTO(type, secret, key_spec, content_type, transport_key=None)¶
This object is a secret data transfer object (DTO).
This object encapsulates a key and attributes about the key. The attributes include a KeySpec that contains the algorithm and bit length. The attributes also include information on the encoding of the key.
- class barbican.plugin.interface.secret_store.AsymmetricKeyMetadataDTO(private_key_meta=None, public_key_meta=None, passphrase_meta=None)¶
This DTO encapsulates metadata(s) for asymmetric key components.
These components are private_key_meta, public_key_meta and passphrase_meta.
Secret Parameter Objects¶
The secret parameter classes encapsulate information about secrets to be stored within Barbican and/or its plugins.
- class barbican.plugin.interface.secret_store.SecretType¶
Constant to define the symmetric key type.
Used by getSecret to retrieve a symmetric key.
- class barbican.plugin.interface.secret_store.KeyAlgorithm¶
Constant for the Diffie Hellman algorithm.
- class barbican.plugin.interface.secret_store.KeySpec(alg=None, bit_length=None, mode=None, passphrase=None)¶
This object specifies the algorithm and bit length for a key.
Plugin Base Class¶
Barbican secret store plugins should implement the abstract base class
SecretStoreBase
. Concrete implementations of this class should be exposed
to Barbican using stevedore
mechanisms explained in the configuration
portion of this guide.
- class barbican.plugin.interface.secret_store.SecretStoreBase¶
- abstract delete_secret(secret_metadata)¶
Deletes a secret from the secret store.
Deletes a secret from a secret store. It can no longer be referenced after this call.
- Parameters:
secret_metadata – secret_metadata
- abstract generate_asymmetric_key(key_spec)¶
Generate a new asymmetric key pair and store it.
Generates a new asymmetric key pair and stores it in the secret store. An object of type AsymmetricKeyMetadataDTO will be returned containing attributes of metadata for newly created key pairs. The metadata is stored by Barbican and passed into other methods to aid the plugins. This can be useful for plugins that generate a unique ID in the external data store and use it to retrieve the key pairs in the future.
- Parameters:
key_spec – KeySpec that contains details on the type of key to generate
- Returns:
An object of type AsymmetricKeyMetadataDTO containing metadata about the key pair.
- abstract generate_supports(key_spec)¶
Returns a boolean indicating if the secret type is supported.
This checks if the algorithm and bit length are supported by the generate methods. This is useful to call before calling generate_symmetric_key or generate_asymetric_key to see if the key type is supported before trying to generate it.
- Parameters:
key_spec – KeySpec that contains details on the algorithm and bit length
- Returns:
boolean indicating if the algorithm is supported
- abstract generate_symmetric_key(key_spec)¶
Generate a new symmetric key and store it.
Generates a new symmetric key and stores it in the secret store. A dictionary is returned that contains metadata about the newly created symmetric key. The dictionary of metadata is stored by Barbican and passed into other methods to aid the plugins. This can be useful for plugins that generate a unique ID in the external data store and use it to retrieve the key in the future. The returned dictionary may be empty if the SecretStore does not require it.
- Parameters:
key_spec – KeySpec that contains details on the type of key to generate
- Returns:
an optional dictionary containing metadata about the key
- abstract get_plugin_name()¶
Gets user friendly plugin name.
This plugin name is expected to be read from config file. There will be a default defined for plugin name which can be customized in specific deployment if needed.
This name needs to be unique across a deployment.
- abstract get_secret(secret_type, secret_metadata)¶
Retrieves a secret from the secret store.
Retrieves a secret from the secret store and returns a SecretDTO that contains the secret.
The secret_metadata parameter is the metadata returned from one of the generate or store methods. This data is used by the plugins to retrieve the key.
The secret_type parameter may be useful for secret stores to know the expected format of the secret. For instance if the type is SecretDTO.PRIVATE then a PKCS8 structure is returned. This way secret stores do not need to manage the secret type on their own.
- Parameters:
secret_type – secret type
secret_metadata – secret metadata
- Returns:
SecretDTO that contains secret
- get_transport_key()¶
Gets a transport key.
Returns the current valid transport key associated with this plugin. The transport key is expected to be a base64 encoded x509 certificate containing a public key. Admins are responsible for deleting old keys from the database using the DELETE method on the TransportKey resource.
By default, returns None. Plugins that support transport key wrapping should override this method.
- is_transport_key_current(transport_key)¶
Determines if the provided transport key is the current valid key
Returns true if the transport key is the current valid transport key. If the key is not valid, then barbican core will request a new transport key from the plugin.
Returns False by default. Plugins that support transport key wrapping should override this method.
- abstract store_secret(secret_dto)¶
Stores a key.
The SecretDTO contains the bytes of the secret and properties of the secret. The SecretStore retrieves the secret bytes, stores them, and returns a dictionary of metadata about the secret. This can be useful for plugins that generate a unique ID in the external data store and use it to retrieve the secret in the future. The returned dictionary may be empty if the SecretStore does not require it.
- Parameters:
secret_dto – SecretDTO for secret
- Returns:
an optional dictionary containing metadata about the secret
- abstract store_secret_supports(key_spec)¶
Returns a boolean indicating if the secret can be stored.
Checks if the secret store can store the secret, give the attributes of the secret in the KeySpec. For example, some plugins may need to know the attributes in order to store the secret, but other plugins may be able to store the secret as a blob if no attributes are given.
- Parameters:
key_spec – KeySpec for the secret
- Returns:
a boolean indicating if the secret can be stored
Barbican Core Plugin Sequence¶
The sequence that Barbican invokes methods on SecretStoreBase
depends on the requested action as detailed next. Note that these actions are
invoked via the barbican.plugin.resources
module, which in turn is invoked
via Barbican’s API and Worker processes.
For secret storage actions, Barbican core calls the following methods:
get_transport_key()
- If a transport key is requested to upload secrets for storage, this method asks the plugin to provide the transport key.store_secret_supports()
- Asks the plugin if it can support storing a secret based on theKeySpec
parameter information as described above.store_secret()
- Asks the plugin to perform encryption of an unencrypted secret payload as provided in theSecretDTO
above, and then to store that secret. The plugin then returns a dictionary of information about that secret (typically a unique reference to that stored secret that only makes sense to the plugin). Barbican core will then persist this dictionary as a JSON attribute within its data store, and also hand it back to the plugin for secret retrievals later. The name of the plugin used to perform this storage is also persisted by Barbican core, to ensure we retrieve this secret only with this plugin.
For secret retrievals, Barbican core will select the same plugin as was
used to store the secret, and then invoke its get_secret()
method to return the unencrypted secret.
For symmetric key generation, Barbican core calls the following methods:
generate_supports()
- Asks the plugin if it can support generating a symmetric key based on theKeySpec
parameter information as described above.generate_symmetric_key()
- Asks the plugin to both generate and store a symmetric key based on theKeySpec
parameter information. The plugin can then return a dictionary of information for the stored secret similar to the storage process above, which Barbican core will persist for later retrieval of this generated secret.
For asymmetric key generation, Barbican core calls the following methods:
generate_supports()
- Asks the plugin if it can support generating an asymmetric key based on theKeySpec
parameter information as described above.generate_asymmetric_key()
- Asks the plugin to both generate and store an asymmetric key based on theKeySpec
parameter information. The plugin can then return anAsymmetricKeyMetadataDTO
object as described above, which contains secret metadata for each of the three secrets generated and stored by this plugin: private key, public key and an optional passphrase. Barbican core will then persist information for these secrets, and also create a container to group them.
The Cryptographic Plugin Adapter¶
Barbican core includes a specialized secret store plugin used to adapt to
cryptographic plugins, called StoreCryptoAdapterPlugin
. This plugin
functions as a secret store plugin, but it directs secret related operations to
cryptographic plugins for
encryption/decryption/generation operations. Because cryptographic plugins do
not store encrypted secrets, this adapter plugin provides this storage
capability via Barbican’s data store.
This adapter plugin also uses stevedore
to access and utilize cryptographic
plugins that can support secret operations.