baseplate.lib.secrets

Application integration with the secret fetcher daemon.

Fetcher Daemon

The secret fetcher is a sidecar that is run as a single daemon on each server. It can authenticate to Vault either as the server itself (through an AWS-signed instance identity document) or through a mounted JWT when running within a Kubernetes pod. It then gets access to secrets based upon the policies mapped to the role it authenticated as. Once authenticated, it fetches a given list of secrets from Vault and stores all of the data in a local file. It will automatically re-fetch secrets as their leases expire, ensuring that key rotation happens on schedule.

Because this is a sidecar, individual application processes don’t need to talk directly to Vault for simple secret tokens (but can do so if needed for more complex operations like using the Transit backend). This reduces the load on Vault and adds a safety net if Vault becomes unavailable.

Secret Store

The secret store is the in-application integration with the file output of the fetcher daemon.

baseplate.lib.secrets.secrets_store_from_config(app_config, timeout=None, prefix='secrets.')[source]

Configure and return a secrets store.

The keys useful to secrets_store_from_config() should be prefixed, e.g. secrets.url, etc.

Supported keys:

path: the path to the secrets file generated by the secrets fetcher daemon.

Parameters:
  • app_config (Dict[str, str]) – The application configuration which should have settings for the secrets store.
  • timeout (Optional[int]) – How long, in seconds, to block instantiation waiting for the secrets data to become available (defaults to not blocking).
  • prefix (str) – Specifies the prefix used to filter keys. Defaults to “secrets.”
  • backoff – retry backoff time for secrets file watcher. Defaults to None, which is mapped to DEFAULT_FILEWATCHER_BACKOFF.
Return type:

SecretsStore

class baseplate.lib.secrets.SecretsStore(path, timeout=None, backoff=None)[source]

Access to secret tokens with automatic refresh when changed.

This local vault allows access to the secrets cached on disk by the fetcher daemon. It will automatically reload the cache when it is changed. Do not cache or store the values returned by this class’s methods but rather get them from this class each time you need them. The secrets are served from memory so there’s little performance impact to doing so and you will be sure to always have the current version in the face of key rotation etc.

get_raw(path)[source]

Return a dictionary of key/value pairs for the given secret path.

This is the raw representation of the secret in the underlying store.

Return type:Dict[str, str]
get_credentials(path)[source]

Decode and return a credential secret.

Credential secrets are a convention of username/password pairs stored as separate values in the raw secret payload.

The following keys are significant:

type
This must always be credential for this method.
encoding
This must be unset or set to identity.
username
This contains the raw username.
password
This contains the raw password.
Return type:CredentialSecret
get_simple(path)[source]

Decode and return a simple secret.

Simple secrets are a convention of key/value pairs in the raw secret payload. The following keys are significant:

type
This must always be simple for this method.
value
This contains the raw value of the secret token.
encoding
(Optional) If present, how to decode the value from how it’s encoded at rest (only base64 currently supported).
Return type:bytes
get_versioned(path)[source]

Decode and return a versioned secret.

Versioned secrets are a convention of key/value pairs in the raw secret payload. The following keys are significant:

type
This must always be versioned for this method.
current, next, and previous
The raw secret value’s versions. current is the “active” version, which is used for new creation/signing operations. previous and next are only used for validation (e.g. checking signatures) to ensure continuity when keys rotate. Both previous and next are optional.
encoding
(Optional) If present, how to decode the values from how they are encoded at rest (only base64 currently supported).
Return type:VersionedSecret
get_vault_url()[source]

Return the URL for accessing Vault directly.

See also

The baseplate.clients.hvac module provides integration with HVAC, a Vault client.

Return type:str
get_vault_token()[source]

Return a Vault authentication token.

The token will have policies attached based on the current EC2 server’s Vault role. This is only necessary if talking directly to Vault.

See also

The baseplate.clients.hvac module provides integration with HVAC, a Vault client.

Return type:str
make_object_for_context(name, span)[source]

Return an object that can be added to the context object.

This allows the secret store to be used with add_to_context():

secrets = SecretsStore("/var/local/secrets.json")
baseplate.add_to_context("secrets", secrets)
Return type:SecretsStore
class baseplate.lib.secrets.VersionedSecret[source]

A versioned secret.

Versioned secrets allow for seamless rotation of keys. When using the secret to generate tokens (e.g. signing a message) always use the current value. When validating tokens, check against all the versions in all_versions. This will allow keys to rotate smoothly even if not done instantly across all users of the secret.

previous

Alias for field number 0

current

Alias for field number 1

next

Alias for field number 2

all_versions

Return an iterator over the available versions of this secret.

Return type:Iterator[bytes]
classmethod from_simple_secret(value)[source]

Make a fake versioned secret from a single value.

This is a backwards compatibility shim for use with APIs that take versioned secrets. Try to use proper versioned secrets fetched from the secrets store instead.

Return type:VersionedSecret
class baseplate.lib.secrets.CredentialSecret[source]

A secret for storing username/password pairs.

Credential secrets allow us to store usernames and passwords together in a single secret. Note that they are not versioned since the general pattern for rotating credentials like this would be to generate a new username/password pair. This object has two properties:

username

Alias for field number 0

password

Alias for field number 1

Exceptions

exception baseplate.lib.secrets.CorruptSecretError(path, message)[source]

Raised when the requested secret does not match the expected format.

exception baseplate.lib.secrets.SecretNotFoundError(name)[source]

Raised when the requested secret is not in the local vault.

exception baseplate.lib.secrets.SecretsNotAvailableError(inner)[source]

Raised when the secrets store was not accessible.