From e55e9e8139b0752f7a749dea4646ae9318cb18d5 Mon Sep 17 00:00:00 2001 From: newtonne Date: Wed, 17 Jan 2018 05:03:25 +0000 Subject: [PATCH] Add `encryption_passcommand` configuration option --- README.md | 6 ++++++ borgmatic/borg/create.py | 4 ++++ borgmatic/config/schema.yaml | 8 ++++++++ borgmatic/tests/unit/borg/test_create.py | 12 ++++++++++++ 4 files changed, 30 insertions(+) diff --git a/README.md b/README.md index 9da8e24b..2c71a784 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,12 @@ environment variable. See the [repository encryption section](https://borgbackup.readthedocs.io/en/latest/quickstart.html#repository-encryption) of the Quick Start for more info. +Alternatively, the passphrase can be specified programatically by setting +either the borgmatic `encryption_passcommand` configuration variable or the +`BORG_PASSCOMMAND` environment variable. See the [Borg Security +FAQ](http://borgbackup.readthedocs.io/en/stable/faq.html#how-can-i-specify-the-encryption-passphrase-programmatically) +for more info. + If the repository is on a remote host, make sure that your local root user has key-based ssh access to the desired user account on the remote host. diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 2fc53813..fd3593b5 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -12,6 +12,10 @@ logger = logging.getLogger(__name__) def initialize_environment(storage_config): + passcommand = storage_config.get('encryption_passcommand') + if passcommand: + os.environ['BORG_PASSCOMMAND'] = passcommand + passphrase = storage_config.get('encryption_passphrase') if passphrase: os.environ['BORG_PASSPHRASE'] = passphrase diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index de9a8056..781f5a54 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -103,6 +103,14 @@ map: https://borgbackup.readthedocs.io/en/stable/usage/general.html#environment-variables for details. map: + encryption_passcommand: + type: scalar + desc: | + The standard output of this command is used to unlock the encryption key. Only + use on repositories that were initialized with passcommand/repokey encryption. + Note that if both encryption_passcommand and encryption_passphrase are set, + then encryption_passphrase takes precedence. + example: "secret-tool lookup borg-repository repo-name" encryption_passphrase: type: scalar desc: | diff --git a/borgmatic/tests/unit/borg/test_create.py b/borgmatic/tests/unit/borg/test_create.py index 14b6c582..ad32d458 100644 --- a/borgmatic/tests/unit/borg/test_create.py +++ b/borgmatic/tests/unit/borg/test_create.py @@ -6,6 +6,17 @@ from borgmatic.borg import create as module from borgmatic.verbosity import VERBOSITY_SOME, VERBOSITY_LOTS +def test_initialize_environment_with_passcommand_should_set_environment(): + orig_environ = os.environ + + try: + os.environ = {} + module.initialize_environment({'encryption_passcommand': 'command'}) + assert os.environ.get('BORG_PASSCOMMAND') == 'command' + finally: + os.environ = orig_environ + + def test_initialize_environment_with_passphrase_should_set_environment(): orig_environ = os.environ @@ -34,6 +45,7 @@ def test_initialize_environment_without_configuration_should_not_set_environment try: os.environ = {} module.initialize_environment({}) + assert os.environ.get('BORG_PASSCOMMAND') == None assert os.environ.get('BORG_PASSPHRASE') == None assert os.environ.get('BORG_RSH') == None finally: