progfiguration.sitehelpers.agesecrets¶
Age secret file store.
Store progfiguration secrets as files. Each secret is encrypted by an Age key.
Wrap the age binary to encrypt and decrypt secret values
Exceptions¶
Common base class for all non-exit exceptions. |
|
Common base class for all non-exit exceptions. |
Classes¶
An age keypair |
|
An age-encrypted secret value |
|
A reference to a secret by name |
|
Age secret file store for progfiguration inventories. |
Functions¶
Module Contents¶
- exception progfiguration.sitehelpers.agesecrets.AgeParseException¶
Bases:
Exception
Common base class for all non-exit exceptions.
- exception progfiguration.sitehelpers.agesecrets.MissingAgeKeyException¶
Bases:
Exception
Common base class for all non-exit exceptions.
- class progfiguration.sitehelpers.agesecrets.AgeKey(secret: str, public: str, created: datetime.datetime)¶
An age keypair
- Attributes:
secret: The secret key public: The public key created: The datetime the key was created
- classmethod from_output(output: str) AgeKey ¶
Parse the output of age-keygen into an AgeKey
Here’s example output from age-keygen -y:
# created: 2022-09-28T16:01:22-05:00 # public key: age14e42u048nehghjj3ch9mmnkdh4nsujn774klqxn02mznppx3gflsuj6y5m AGE-SECRET-KEY-1ASKGXED4DVGUH7SA50DHE2UHAYQ00PV87N2RQ5J5S6AUN9MLNSGQ3TKFGJ
This function parses that output and returns an AgeKey object.
- classmethod generate(path: pathlib.Path | None = None) AgeKey ¶
Generate a new age keypair using the age-keygen binary
- class progfiguration.sitehelpers.agesecrets.AgeSecret¶
Bases:
progfiguration.inventory.invstores.Secret
An age-encrypted secret value
- class progfiguration.sitehelpers.agesecrets.AgeSecretReference¶
Bases:
progfiguration.inventory.invstores.SecretReference
A reference to a secret by name
This is a wrapper type that allows us to pass around a reference to a secret without having to know the secret’s value.
- dereference(nodename: str, hoststore: progfiguration.inventory.invstores.HostStore, secretstore: progfiguration.inventory.invstores.SecretStore) Any ¶
Get the final value of a role argument for a node.
Arguments to this method:
nodename: The name of the node that the argument is being applied to
hoststore: The inventory object
This function must retrieve or calculate the final value from its internal data and these arguments.
- progfiguration.sitehelpers.agesecrets.encrypt(value: str | bytes, pubkeys: List[str])¶
Encrypt a value to a list of public age keys
- progfiguration.sitehelpers.agesecrets.decrypt(value: str, privkey_path: str | None) str ¶
Decrypt an encrypted age value
- class progfiguration.sitehelpers.agesecrets.AgeSecretStore(controller_age_pubkey: str, decryption_age_privkey_path_list: List[str] | None = None)¶
Bases:
progfiguration.inventory.invstores.SecretStore
Age secret file store for progfiguration inventories.
Store progfiguration secrets as files in the site’s nodes/ and groups/ submodules. Each secret is encrypted by an Age key.
Look for a decryption key in the list passed to the initializer.
The CLI arguments it accepts:
age_key
The path to an age private key to decrypt secrets.
The InventoryNode sitedata it looks for:
age_key_path
The path on the node to an age private key to decrypt secrets. If this is not set, we try to use the
decryption_age_privkey_path
. If this is set, but the key does not exist, we raise FileNotFoundError.age_pubkey
The string of an age public key to encrypt secrets. If this is not set, encrypting secrets for the node (or any of its groups) will fail.
- _cache: Dict[str, Dict[str, Dict[str, progfiguration.inventory.invstores.Secret]]]¶
An in-memory cache.
self._cache[collection][name] = {secretname: Secret}
- decryption_age_privkey_path: str = ''¶
If this is not empty, use this path to an age private key to decrypt secrets.
During initialization, this is set to the first item in decryption_age_privkey_path_list that exists. Can be (re-)set after initialization.
TODO: how will the cli code in core allow setting this at runtime?
- _get_secrets_file(collection: Literal['node', 'group', 'special'], name: str) pathlib.Path ¶
- _load_secrets(collection: Literal['node', 'group', 'special'], name: str) Dict[str, progfiguration.inventory.invstores.Secret] ¶
Load a secrets from a secret store.
Cache them in memory for future use.
- _append_secret(collection: Literal['node', 'group', 'special'], name: str, secret_name: str, encrypted_value: str)¶
Append a secret to the cache.
This is used when a secret is encrypted and stored
- get_secret(collection: Literal['node', 'group', 'special'], name: str, secret_name: str) progfiguration.inventory.invstores.Secret ¶
Retrieve a secret from the secret store.
This operation returns an opaque Secret type. The secret does not have to be decrypted yet, but can be, depending on the Secret implementation.
- encrypt_secret(hoststore: progfiguration.inventory.invstores.HostStore, name: str, value: str, nodes: List[str], groups: List[str], controller_key: bool, store: bool = False) str ¶
Encrypt a secret for some list of nodes and groups.
Always encrypt for the controller so that it can decrypt too.
We assume this only ever happens on the controller.
- apply_cli_arguments(args: Dict[str, str]) None ¶
Apply arguments from the command line
Arguments are passed as comma-separated key/value pairs, like
--secret-store-arguments key1=value1,key2=value2
.
- find_node_key(node: progfiguration.inventory.nodes.InventoryNode)¶
If called, this function should find the decryption key for a node.
It may be called by the progfigsite command-line program if the user specifies a node. The implementation may look up the key in the node’s sitedata.