Skip to content
This repository has been archived by the owner on Nov 17, 2021. It is now read-only.

Changes to be able to use 1Password to store values from secrets and retrieve them from 1Password #279

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

thomasmhofmann
Copy link

@thomasmhofmann thomasmhofmann commented Dec 18, 2019

These changes integrate kubecfg with 1Password.

The rational behind these changes is the following:

  • Passwords for different environments (dev, test, prod) should be different and it should be possible to generate good passwords automatically.
  • These generated passwords need to be stored somewhere so that a user can look them up.
  • They should not be stored in SCM.
  • Passwords / secrets need to be shared among team members.

The proposed solution add some basic / general new native functions to kubecfg.libsonnet. Using these primitives a Jsonnet library (1password.libsonnet) is built that provides 1Password-specific functionality.

To use the integration one would create a 'OnePasswordSecret' instead of a 'Secret' (from kube.libsonnet).
This special secret will determine the name of the vault to use in 1Password and will also determine a name for the new item where the values from the secret should be stored.
It will then try to read that item from 1Password and incorporate the information found into the stringData field of the kubernetes secret resource.
If the item does not exist, it will create a new item and store the information in this new item to the 1Password vault. Incremental changes are not supported. So when the secret definition in Jsonnet is changed (a new field is added) it will not be stored to 1Password.

The PR includes a sample secret kubernetes resource in Jsonnet and the 1Password library.

Some of the things that is included in the 1Password library could have also been added directly in kubecfg but I did not want too speciifc things to kubecfg. Unfortunately, I still needed to add four new functions to kubecfg.libsonnet (actually one is not really needed for the integration).

This is my first PR and I hope that I did not do too many mistakes. I used different commits for changes to vendor.

In order to add a generatePassword native function to kubcfg.libsonnet add
the required module to vendor/
The new function is added to kubecfg.libsonnet. It can be used to
generate a password with specific properties.
In order to add an exec native function to kubcfg.libsonnet add
the required module to vendor/
As some symbols can cause trouble (e.g. when these are part of
a JSON string an passed on the command line to some other
tool) the symbols that the password generator will use can be
customized.
The 'exec' native function is added to kubecfg.libsonnet.
It can be used to execute external programs from inside
the jsonnet VM.
This is useful for example to interact with the CLI for
1password to store and retrieve credentials.
In order to implement a native function to create
NT(LM) hashes for passwords update vendor with
new dependency.
The 'ntHashFromPassword' native function is added to kubecfg.libsonnet.
It can be used to calculate the NT(LM) hash for a password.
This is useful when these kinds of hashes need to be created in order
to add them to some initial configurations for applications that
expect this format (e.g. Alfresco DMS).
The jsonnet std library does not include such a function.
It is needed for applications that expect URL encoding style
for base64-encoding.
This commit includes '1password.libsonnet' that builds on the
new features commited before to kubecfg like:
- generatePassword
- execProgram
- ntHashFromPassword
- encodeBase64Url

This library can be used to generate password for secrets.
These password are then stored in a vault in 1Password.
Once the new item containing the secrets is stored in the
1Password vault kubecfg will use these when 'rendering'
the secret resource.

In addition to the library 'secrets.jsonnet' is provided as an
example on how to use the library.
This function will return the plan JSON representation
for an item stored in 1Password.
In contrast the existing method 'getPasswordFrom1Password'
expects an item of type / category 'Password'.
The JSON returned can be processed in any way needed.
This is mainly useful for item created in manually in 1Password.
@thomasmhofmann thomasmhofmann marked this pull request as ready for review December 18, 2019 16:46
Adds a new field 'fallback' to generatedPasswords_ field in
OnePasswordSecret that is used when the useFallbackValues
parameter to OnePasswordSecret is set to true.

This is useful for example for local development clusters
like minikube that do not require generated passwords
and storage in 1Password.

Also fixes a comment and changes some formatting.

Run with:
kubecfg show examples/1password/secrets.jsonnet --tla-code=useFallbackValues=true

and

kubecfg show examples/1password/secrets.jsonnet --tla-code=useFallbackValues=false
or
kubecfg show examples/1password/secrets.jsonnet
Add more detail to messages traced in 1password.libsonnet
and use std.format for concatinating strings.
The getItemFrom1Password function now also supports passing
a fallback value in form of an JSON object.

Examples in 'secrets.jsonnet' have been adjustes to showcase this
feature.

Trace messages have been improved.
Error out of execution in case an item cannot be read from 1Password
and useFallbackValue is set to false.
@thomasmhofmann
Copy link
Author

Hi there, any chance to get this merged? Or should I take another approach? Can we discuss what would be an acceptable change?

@mkmik
Copy link
Contributor

mkmik commented Jan 31, 2020

I'll review soon, sorry you caught me in a busy moment (paternity)

@thomasmhofmann
Copy link
Author

Congratulations, I just did not see any reaction that's why I decided to ask now. Take your time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants