unverbuggt / mkdocs-encryptcontent-plugin

A MkDocs plugin that encrypt/decrypt markdown content with AES
https://unverbuggt.github.io/mkdocs-encryptcontent-plugin/
MIT License
123 stars 15 forks source link

Encrypt single pages with password from Environment variable #43

Closed odin568 closed 1 year ago

odin568 commented 1 year ago

Hi, I saw it is possible to protect single pages by specifying password directly. That is nice. Then I also saw I could set password in config from environment variable like: use_secret: !ENV [ENCRYPTCONTENT_PASSWORD, '']

My use case:

How can I do this? What do I need to add as meta to the page header?

Thanks for your efforts!

unverbuggt commented 1 year ago

I must admit that I never tested the use_secret feature myself.

One way of doing what you are trying to achieve is in fact to set use_secret in plugin configuration to an environment variable and thus activation global_password.
But as you only want to encrypt specific pages, you'll need to set password: (nothing/new line after ":") meta tag on all pages that shouldn't be encrypted.

But I'll also check if there is an easy solution to define an environment variable as meta tag, f.ex. by introducing a meta tag named use_seceret.

I'll also think about the suggested fallback password if the environment variable is not found (or in other words, env variable is preferred over password). But we'll probably need to at least display a warning message in that case...

unverbuggt commented 1 year ago

Please try the latest development version. use_secret now also works as meta tag in markdown.

But the default behavior when an environment variable should be used but is empty or undefined is still: Error message and failed build. This is because one could have forgotten to set the environment variable, or it could have gotten missing due to configuration changes on the system - this could lead to unprotected pages, and we don't want that.

If, like in your use case, you want to use an environment variable on one system and the password in the config on another you can now use ignore_missing_secret: true to modify the behavior to: if environment variable undefined, then fall back to password from config (it this is also missing, then the build will still fail).

I was unaware that one could use use_secret: !ENV [ENCRYPTCONTENT_PASSWORD, ''] notation. I though use_secret expects just the environment variable. On which OS can this be used?

CoinK0in commented 1 year ago

The idea of using tags (jinja?) as a meta tag for the plugin is very good and if it is possible/works is much better than my idea.

But juste another idea (I have not tested/try anything). Maybe users want to use multiple methods (env/tags) for page encryption. And with this logic, the priority of one method over another should be removed in favor of a password inventory. Inventory could (potentially) be an extra key to add to the global "mkdocs.config" navigation menu (nav:). It would allow to have a list of passwords per page, to be used (always with the 3 basic cases, global/specific/absent) and for each of this password to use the env method OR the tag method. From a management point of view, it allows you to centralize passwords. From a security point of view, there is no real loss since currently if the source repository is accessible the passwords too. From a code point of view, you have to change a lot of things ^^'

Thank you for the continuous improvements of this plugin !

odin568 commented 1 year ago

Please try the latest development version. use_secret now also works as meta tag in markdown.

But the default behavior when an environment variable should be used but is empty or undefined is still: Error message and failed build. This is because one could have forgotten to set the environment variable, or it could have gotten missing due to configuration changes on the system - this could lead to unprotected pages, and we don't want that.

If, like in your use case, you want to use an environment variable on one system and the password in the config on another you can now use ignore_missing_secret: true to modify the behavior to: if environment variable undefined, then fall back to password from config (it this is also missing, then the build will still fail).

I was unaware that one could use use_secret: !ENV [ENCRYPTCONTENT_PASSWORD, ''] notation. I though use_secret expects just the environment variable. On which OS can this be used?

Cannot try it out right now but will next week. Sounds promising and should cover my use case. Well that syncax comes directly from mkdocs documentation, so should be available everywhere AFAIK Thanks for your efforts!

unverbuggt commented 1 year ago

I was unaware of that !ENV feature. It should work with mkdocs.yaml file, but most likely won't within markdown meta tag.

use_secret expects an environment variable's name. We can't change this behavior, or it'll break compatibility. However, !ENV could be used at global_password. Please try if the workaround ignore_missing_secret: true works for you.

I'll open another issue to discuss the password inventory idea.

odin568 commented 1 year ago

So I see that use_secret on page level works. Also the new option ignore_missing_secret: true has an effect but not as much as expected. Those options only work when I set a global_password too which leads to every page being protected and not only the desired one.

My meta tag: use_secret: TEST_ENV My Config:

  - encryptcontent:
      ignore_missing_secret: true
      global_password: !ENV [TEST_ENV, 'abc']

Did I missunderstand something?

unverbuggt commented 1 year ago

Did you install the development version from this repo?

git clone https://github.com/unverbuggt/mkdocs-encryptcontent-plugin.git
cd mkdocs-encryptcontent-plugin
python setup.py sdist bdist_wheel
pip install dist/mkdocs_encryptcontent_plugin-2.4.5-py3-none-any.whl

Comment/delete global_password and ignore_missing_secret from the config for now. Just set use_secret meta tag of a markdown page to an ENV variable. If the variable is not found, it'll output something like this.

ERROR    -  Cannot get password for "Site name" from environment variable: ENV_VARIABLE. Abort !

You can test this by unsetting the variable or setting it to an empty string. If the Variable is found, then there should be no error and the page should encrypt with the password from the ENV variable.

If it still doesn't work, please set up a minimal mkdocs.yml plus some pages and upload the example in a zip file as attachment here. Thanks.

odin568 commented 1 year ago

Okay, got it. Yes followed this. This works now. Only having use_secret on page and no configuration in my config (beside specifying plugin) It is perfectly encrypting when the variable exists. If not, it fails. with error as you state above.

The behavior I would expect now: If I set ignore_missing_secret: true then it should not fail and thereby not secure the page. Of course this is risky but I explicitly configured this behavior, which is not the default one, thereby fine in my opinion.

unverbuggt commented 1 year ago

Thanks for testing. I just published a new release