Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating SOPS to 3.7.1 #241

Merged
merged 3 commits into from
May 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 0 additions & 46 deletions examples/contrib/sops/README.md

This file was deleted.

34 changes: 34 additions & 0 deletions examples/contrib/sops/age/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# sops: AGE example

### Overview

The `sops` KRM config function encrypts and decrypts resources. Learn more on the [sops website].

This example demonstrates invocation of `sops` for encryption the resouce called `toEncrypt` and decryption of the resource called `toDecrypt` using the already existing AGE keys.

## Function invocation

Get this example and try it out by running the following commands:

```sh
# download this example
kpt pkg get https://github.com/GoogleContainerTools/kpt-functions-catalog.git/examples/contrib/sops/age .

# copy example AGE key from sops project
curl -fsSL -o age_keys.txt https://raw.githubusercontent.com/mozilla/sops/master/age/keys.txt

# run the function to work with AGE
SOPS_IMPORT_AGE="$(cat age_keys.txt)" kpt fn run age
```

## Expected result

Verify the updated configuration:

```sh
kpt cfg cat age
```

The resource called `toDecrypt` must be decrypted and the resource called `toEncrypt` must be encrypted.

[sops website]: https://github.com/mozilla/sops#encrypting-using-age
30 changes: 30 additions & 0 deletions examples/contrib/sops/age/function.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: my-decrypt-config
annotations:
config.k8s.io/function: |
container:
image: gcr.io/kpt-fn-contrib/sops:unstable
envs:
- SOPS_IMPORT_AGE
config.kubernetes.io/local-config: "true"
data:
cmd: 'decrypt'
cmd-json-path-filter: '$[?(@.metadata.name=="toDecrypt")]'
---
apiVersion: v1
kind: ConfigMap
metadata:
name: my-encrypt-config
annotations:
config.k8s.io/function: |
container:
image: gcr.io/kpt-fn-contrib/sops:unstable
config.kubernetes.io/local-config: "true"
data:
cmd: 'encrypt'
cmd-json-path-filter: '$[?(@.metadata.name=="toEncrypt")]'
age: 'age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw'
unencrypted-regex: '^(kind|apiVersion|group|metadata)$'

27 changes: 27 additions & 0 deletions examples/contrib/sops/age/to-decrypt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apiVersion: v1
kind: somekind
metadata:
name: toDecrypt
nnn-password: ENC[AES256_GCM,data:G2i53KNBoAEycMHD5w==,iv:PjywQXtBGZDgn5zNgI/0BsKiov7drduyyXSt8gNtdDs=,tag:slGGtNbvT01rtgDb1pCkFw==,type:str]
user-password: ENC[AES256_GCM,data:iM5w/l6egeDlvkjc2tpk,iv:kBtgkTNuNuUL6FvYGa+NA0U0jkcmm0IIRZ8j5PicSMs=,tag:lACKq9kbf4n72xFmZb1Ymw==,type:str]
k8s-password: ENC[AES256_GCM,data:uZb3qTvx3Ucq,iv:VQTP3fimb3uitY/0LuJMhvdjd2s9bq8xguWgTOkCqG4=,tag:4JT50F72xL5Gyy5mqGjkrg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsR2ZvT21Bd2NuWnBXaFZa
OG9YUzg2b1g1VDQ3bHlaSGdMQW10UE9jYjEwCndSbWpDdis4S1IyOFdxL2U4eDVL
cG00RUxpcE1IRnR3cVk0dDJtK3Zwc00KLS0tIHhuNlVTakF1a3dyZFF4ZWg3TXFE
QzFjYmR1MVh3bVhydURmZ25ORmQxNGsKkcHUujLrlwycauIr1nJ9O9KG4T6NkmMv
8szwCF4AuqHzhSKhqGzYUnRQB1Igfpw85XjdR5O1aCf0mux/+E6Ihg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-04-27T04:12:50Z"
mac: ENC[AES256_GCM,data:darUiOLASNLXAMucmoQsaMvAk6KmMkb5owGfv38vsaF8JDXhxom0B6MTp2KRyiliv2KICEWv8BRofNXWQpgKGwvS8CPmZic7JgqdJhNpNVrt5NipisMcCigUVdk7WtQ73l7tTuqI5vBg9FnrnDgndnTr4CoqjxwThlbTtNy7+30=,iv:WmiLyZMMtsyL3KOTaki6EClKAyJ2KcVxanxcVJZGalo=,tag:ZJOBM+1NiyDN0a+OSndG6Q==,type:str]
pgp: []
unencrypted_regex: ^(kind|apiVersion|group|metadata)$
version: 3.7.1
34 changes: 34 additions & 0 deletions examples/contrib/sops/gpg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# sops: PGP example

### Overview

The `sops` KRM config function encrypts and decrypts resources. Learn more on the [sops website].

This example demonstrates invocation of `sops` for encryption the resouce called `toEncrypt` and decryption of the resource called `toDecrypt` using the already existing PGP keys.

## Function invocation

Get this example and try it out by running the following commands:

```sh
# download this example
kpt pkg get https://github.com/GoogleContainerTools/kpt-functions-catalog.git/examples/contrib/sops/gpg .

# copy example GPG key from sops project
curl -fsSL -o gpg_keys.asc https://raw.githubusercontent.com/mozilla/sops/master/pgp/sops_functional_tests_key.asc

# run the function to work with GPG
SOPS_IMPORT_PGP="$(cat gpg_keys.asc)" kpt fn run gpg
```

## Expected result

Verify the updated configuration:

```sh
kpt cfg cat gpg
```

The resource called `toDecrypt` must be decrypted and the resource called `toEncrypt` must be encrypted.

[sops website]: https://github.com/mozilla/sops#test-with-the-dev-pgp-key
7 changes: 7 additions & 0 deletions examples/contrib/sops/gpg/to-encrypt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: somekind
metadata:
name: toEncrypt
nnn-password: password1
user-password: password2
k8s-password: password3
63 changes: 63 additions & 0 deletions functions/contrib/ts/sops/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# SOPS

### Overview

Use [sops] to encrypt/decrypt KRM resources.

### Synopsis

The function configuration must be a ConfigMap.

The following keys can be used in the `data` field of the ConfigMap, and all of
them are optional:

- `cmd`: The operation that sops perform: `encrypt` or `decrypt`. The default
is `decrypt`.
- `cmd-json-path-filter`: Operation will be performed only to the resources that match
to the filter, e.g. `$[?(@.metadata.name=="somename" && @.kind=="somekind")]` will
process only resources with name `somename` and kine `somekind`. The default is empty.
- `cmd-tolerate-failures`: Ignore sops error and keep KRM resource unchanged rather than
exit the function with error. The default is `false`.
- `verbose`: Sops verbose logging output is enabled. The default is `false`.
- `ignore-mac`: Sops will ignore Message Authentication Code during decryption. The default
is `false`.
- `override-preexec-cmd`: The command that will be executed prior to sops exectution. The default is
`[ "$SOPS_IMPORT_PGP" == "" ] || (echo "$SOPS_IMPORT_PGP" | gpg --import 2>/dev/null); [ "$XDG_CONFIG_HOME" == "" ] || [ "$SOPS_IMPORT_AGE" == "" ] || (mkdir -p $XDG_CONFIG_HOME/sops/age/ && echo "$SOPS_IMPORT_AGE" > $XDG_CONFIG_HOME/sops/age/keys.txt`.
This command allows to import encryption keys via ENV variables.
- `override-detached-annotations`: List of comma-separated annotations that will be removed from the KRM resource
if exist prior to sops execution and added back after execution. That helps to avoid decryption issues
in cases the composer (e.g. kpt) adds its internal annotations. The default is
`config.kubernetes.io/index,config.kubernetes.io/path,config.k8s.io/id,kustomize.config.k8s.io/id`.
- all other provided keys will be converted to the sops command arguments using pattern `--<key name> <value>`, e.g.
`unencrypted-regex: '^(kind|apiVersion|group|metadata)$'` will add sops parameter `--unencrypted-regex: '^(kind|apiVersion|group|metadata)$'`.

In order to encrypt or decrypt yaml, `sops` may accept a variety of ENV variables, e.g. to work
with Hashicorp Vault it will be necessary to set: `VAULT_ADDR` and
`VAULT_TOKEN`. This option can be used to set different encryption parameters that shouldn't be stored
in version control system repository, e.g. private keys, external services credentials.
This function introduces 2 additional ENV variables: `SOPS_IMPORT_PGP` and `SOPS_IMPORT_AGE` that must contain the PGP or AGE keys and that
make possible to work with PGP and AGE encryption.

For `pgp` if you have a file with keys it's possible to run:

```sh
SOPS_IMPORT_PGP="$(cat <file with exported key>.asc)" kpt fn run <folder>
```

or if your keys are already presented in `gpg`-storage, it's possible to run:

```sh
SOPS_IMPORT_PGP="$(gpg --armor --export-secret-keys)" kpt fn run <folder>
```

To make `sops` decrypt `age` it's necessary to keep all keys in the single file `~/.config/sops/age/keys.txt`. If that file exists, it's possible to invoke sops function and provide it with that keys by the command:

```sh
SOPS_IMPORT_AGE="$(cat ~/.config/sops/age/keys.txt)" kpt fn run <folder>
```

Please refer to [gpg] and [age] examples to get more details.

[age]:/examples/contrib/sops/age/
[gpg]:/examples/contrib/sops/gpg/
[sops]:https://github.com/mozilla/sops
3 changes: 2 additions & 1 deletion functions/contrib/ts/sops/build/sops.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ FROM node:14.15-alpine3.12 as builder

RUN apk add bash curl git && apk update

ARG SOPS_VERSION="v3.6.1"
ARG SOPS_VERSION="v3.7.1"
RUN curl -fsSL -o /usr/local/bin/sops https://github.com/mozilla/sops/releases/download/${SOPS_VERSION}/sops-${SOPS_VERSION}.linux && \
chmod +x /usr/local/bin/sops

Expand Down Expand Up @@ -50,5 +50,6 @@ COPY --from=builder /usr/local/bin /usr/local/bin

ENV PATH /usr/local/bin:$PATH
ENV GNUPGHOME /tmp
ENV XDG_CONFIG_HOME /tmp

ENTRYPOINT ["node", "/home/node/app/dist/sops_run.js"]
4 changes: 3 additions & 1 deletion functions/contrib/ts/sops/src/sops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ let cmdTolerateFailures = false;

// pre-exec command may be overriden from config
let preExecCmd =
'[ "$SOPS_IMPORT_PGP" == "" ] || (echo "$SOPS_IMPORT_PGP" | gpg --import)';
'[ "$SOPS_IMPORT_PGP" == "" ] || (echo "$SOPS_IMPORT_PGP" | gpg --import 2>/dev/null); \
[ "$XDG_CONFIG_HOME" == "" ] || [ "$SOPS_IMPORT_AGE" == "" ] || \
(mkdir -p $XDG_CONFIG_HOME/sops/age/ && echo "$SOPS_IMPORT_AGE" > $XDG_CONFIG_HOME/sops/age/keys.txt);';

// list of annotations that will be detached before decryption
// this is needed, because tools like kpt add some annotations
Expand Down
18 changes: 13 additions & 5 deletions tests/sops.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,21 @@ kpt fn source example-configs |
kpt fn run --env SOPS_IMPORT_PGP="$(cat key.asc)" --image gcr.io/kpt-fn-contrib/sops:"${TAG}" -- verbose=true >out.yaml
assert_contains_string out.yaml "t00m4nys3cr3tzupdated"

testcase "kpt_sops_declarative_example"
testcase "kpt_sops_declarative_example_gpg"
# get examples from the current version of repo
cp -r "$REPODIR"/examples/contrib/sops .
cp -r "$REPODIR"/examples/contrib/sops/gpg .
curl -fsSL -o key.asc https://raw.githubusercontent.com/mozilla/sops/master/pgp/sops_functional_tests_key.asc
SOPS_IMPORT_PGP="$(cat key.asc)" kpt fn run sops
assert_contains_string sops/to-decrypt.yaml "nnn-password: k8spassphrase"
assert_contains_string sops/to-encrypt.yaml "nnn-password: 'ENC"
SOPS_IMPORT_PGP="$(cat key.asc)" kpt fn run gpg
assert_contains_string gpg/to-decrypt.yaml "nnn-password: k8spassphrase"
assert_contains_string gpg/to-encrypt.yaml "nnn-password: 'ENC"

testcase "kpt_sops_declarative_example_age"
# get examples from the current version of repo
cp -r "$REPODIR"/examples/contrib/sops/age .
curl -fsSL -o keys.txt https://raw.githubusercontent.com/mozilla/sops/master/age/keys.txt
SOPS_IMPORT_AGE="$(cat keys.txt)" kpt fn run age
assert_contains_string age/to-decrypt.yaml "nnn-password: k8spassphrase"
assert_contains_string age/to-encrypt.yaml "nnn-password: 'ENC"

testcase "kpt_sops_declarative_fn_path"
cat >fc.yaml <<EOF
Expand Down