Crates.io | xand-secrets |
lib.rs | xand-secrets |
version | 0.4.2 |
source | src |
created_at | 2023-02-13 23:12:58.844736 |
updated_at | 2023-02-14 21:45:27.804083 |
description | A simple interface for reading secrets from — and checking the health of — a centralized secret store. |
homepage | |
repository | |
max_upload_size | |
id | 784384 |
size | 18,755 |
This repo houses a core trait, SecretKeyValueStore
, which provides a simple
interface for reading secrets from — and checking the health of — a centralized
secret store. The exposed API is intended to focus on the commonality between
various implementations; secrets are indexed by a single string key.
This interface does not facilitate populating or updating secrets within the store; its administration is left up to external tooling.
The secret store is intended to securely hold API tokens, client certificates, or other similar keys which are intended to be kept private. The typical use-case is interaction with a 3rd-party, although this concept could also be applied to interactions between two TPFS applications.
A consumer is expected to have available any authentication needed to make
requests to their secret store of choice, along with the relevant connection
details. They first use a client (implementing SecretKeyValueStore
) to
retrieve secrets from the store, and then make a request to the external
service with the secrets that were returned. The intent is that the hosting
application does not store or cache the returned secrets after making the
upstream request.
The below diagram illustrates this process, including a hypothetical Kubernetes deployment and its role in the secret store request. This deployment pattern is not required for use of the crate, but almost any instance of a host app will need secret store credentials made available by some means.
All adapters are in their own isolated crates, and there is no central API for creating them. Typically, an application will expose the secret store choice to the user and/or application administrator as a configuration parameter.
For example, a deserialized configuration input could look like this:
pub enum SecretStoreConfig {
Vault(VaultConfiguration),
KeyVault(KeyVaultConfiguration),
LocalFile(LocalFileSecretStoreConfiguration),
}
As of writing, existing adapters all declare a *Configuration
struct to be
passed as an argument upon creation, but this is not inherently required.
Once a SecretStoreConfig
is loaded, the application can create the appropriate
store using each crate's individual API:
match &configuration.secret_store {
SecretStoreConfig::Vault(config) => Ok(Arc::new(
VaultSecretKeyValueStore::create_from_config(config.clone())?,
)),
SecretStoreConfig::KeyVault(config) => Ok(Arc::new(
KeyVaultSecretKeyValueStore::create_from_config(config.clone()),
)),
SecretStoreConfig::LocalFile(config) => Ok(Arc::new(
LocalFileSecretKeyValueStore::create_from_config(config.clone()),
)),
}