diff options
author | Vincent Ambo <mail@tazj.in> | 2019-09-03T15·26+0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-03T15·26+0100 |
commit | 628cec34331ea7ef94a71f562a0dc1f8d49e9ecf (patch) | |
tree | fe6be2f9756627ac09c3207f876430921789baec | |
parent | be28462a8a29403128b39696cc632f70363efa6e (diff) | |
parent | 283951388c96e871c9c4a835eee6594fc27e08c0 (diff) |
Merge pull request #5 from tazjin/feat/cloud-kms-secrets r/80
Introduce secrets management via Google Cloud KMS
-rw-r--r-- | .envrc | 1 | ||||
-rw-r--r-- | default.nix | 13 | ||||
-rw-r--r-- | infra/gcp/default.tf | 37 | ||||
-rw-r--r-- | infra/kubernetes/nixery/config.yaml | 4 | ||||
-rw-r--r-- | infra/kubernetes/nixery/id_nixery.pub | 1 | ||||
-rw-r--r-- | infra/kubernetes/nixery/known_hosts | 1 | ||||
-rw-r--r-- | infra/kubernetes/nixery/secrets.yaml | 19 | ||||
-rw-r--r-- | infra/kubernetes/nixery/ssh_config | 4 | ||||
-rw-r--r-- | secrets/nixery-gcs-json | bin | 0 -> 2416 bytes | |||
-rw-r--r-- | secrets/nixery-gcs-pem | bin | 0 -> 3214 bytes | |||
-rw-r--r-- | secrets/nixery-ssh-private | bin | 0 -> 1906 bytes | |||
-rwxr-xr-x | tools/bin/__dispatch.sh | 3 | ||||
l--------- | tools/bin/pass | 1 | ||||
-rw-r--r-- | tools/kms_pass/default.nix | 60 |
14 files changed, 129 insertions, 15 deletions
diff --git a/.envrc b/.envrc index d89bcd9d66f2..6b3ce7ebbb1e 100644 --- a/.envrc +++ b/.envrc @@ -4,3 +4,4 @@ export PATH="${PWD}/tools/bin:${PATH}" export NIX_PATH="nixpkgs=${PWD}/default.nix" export REPO_ROOT="${PWD}" +export SECRETS_DIR="${PWD}/secrets" diff --git a/default.nix b/default.nix index ed6258108d5b..3b5736a19261 100644 --- a/default.nix +++ b/default.nix @@ -28,6 +28,13 @@ let blog = self.callPackage ./services/tazblog {}; blog_cli = self.callPackage ./tools/blog_cli {}; gemma = self.callPackage ./services/gemma {}; + + kms_pass = self.callPackage ./tools/kms_pass { + project = "tazjins-infrastructure"; + region = "europe-north1"; + keyring = "tazjins-keys"; + key = "kontemplate-key"; + }; }; # Third-party projects (either vendored or modified from nixpkgs) go here: @@ -49,6 +56,12 @@ let sha256 = "1wn7nmb1cqfk2j91l3rwc6yhimfkzxprb8wknw5wi57yhq9m6lv1"; }) {}).elmPackages; + # Wrap kontemplate to inject the Cloud KMS version of 'pass' + kontemplate = self.writeShellScriptBin "kontemplate" '' + export PATH="${self.tazjin.kms_pass}/bin:$PATH" + exec ${super.kontemplate}/bin/kontemplate $@ + ''; + # One of Gemma's dependencies is missing in nixpkgs' Quicklisp # package set, it is overlaid locally here. lispPackages = import ./third_party/common_lisp/quicklisp.nix { diff --git a/infra/gcp/default.tf b/infra/gcp/default.tf index 677e737a242e..d13345393bd4 100644 --- a/infra/gcp/default.tf +++ b/infra/gcp/default.tf @@ -27,24 +27,25 @@ resource "google_project_services" "primary" { "bigquerystorage.googleapis.com", "cloudapis.googleapis.com", "clouddebugger.googleapis.com", + "cloudkms.googleapis.com", "cloudtrace.googleapis.com", + "compute.googleapis.com", + "container.googleapis.com", + "containerregistry.googleapis.com", "datastore.googleapis.com", "dns.googleapis.com", + "iam.googleapis.com", + "iamcredentials.googleapis.com", "logging.googleapis.com", "monitoring.googleapis.com", + "oslogin.googleapis.com", + "pubsub.googleapis.com", "servicemanagement.googleapis.com", "serviceusage.googleapis.com", + "sourcerepo.googleapis.com", "sql-component.googleapis.com", "storage-api.googleapis.com", "storage-component.googleapis.com", - "container.googleapis.com", - "iam.googleapis.com", - "compute.googleapis.com", - "iamcredentials.googleapis.com", - "oslogin.googleapis.com", - "pubsub.googleapis.com", - "containerregistry.googleapis.com", - "sourcerepo.googleapis.com", ] } @@ -82,7 +83,21 @@ resource "google_service_account" "nixery" { display_name = "Nixery service account" } -# Configure a git repository in which to store my monorepo -resource "google_sourcerepo_repository" "monorepo" { - name = "monorepo" +# Configure Cloud KMS for secret encryption +resource "google_kms_key_ring" "tazjins_keys" { + name = "tazjins-keys" + location = "europe-north1" + + lifecycle { + prevent_destroy = true + } +} + +resource "google_kms_crypto_key" "kontemplate_key" { + name = "kontemplate-key" + key_ring = google_kms_key_ring.tazjins_keys.id + + lifecycle { + prevent_destroy = true + } } diff --git a/infra/kubernetes/nixery/config.yaml b/infra/kubernetes/nixery/config.yaml index 1bd95536ac17..796e21a7273c 100644 --- a/infra/kubernetes/nixery/config.yaml +++ b/infra/kubernetes/nixery/config.yaml @@ -3,10 +3,6 @@ # The service via which Nixery is exposed has a private DNS entry # pointing to it, which makes it possible to resolve `nixery.local` # in-cluster without things getting nasty. -# -# The 'nixery-keys' secret was configured manually using a created -# service account key. This does not use metadata-based authentication -# due to the requirement for having an actual PEM-key to sign with. --- apiVersion: apps/v1 kind: Deployment diff --git a/infra/kubernetes/nixery/id_nixery.pub b/infra/kubernetes/nixery/id_nixery.pub new file mode 100644 index 000000000000..dc3fd617d0a1 --- /dev/null +++ b/infra/kubernetes/nixery/id_nixery.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzBM6ydst77jDHNcTFWKD9Fw4SReqyNEEp2MtQBk2wt94U4yLp8MQIuNeOEn1GaDEX4RGCxqai/2UVF1w9ZNdU+v2fXcKWfkKuGQH2XcNfXor2cVNObd40H78++iZiv3nmM/NaEdkTbTBbi925cRy9u5FgItDgsJlyKNRglCb0fr6KlgpvWjL20dp/eeZ8a/gLniHK8PnEsgERQSvJnsyFpxxVhxtoUiyLWpXDl4npf/rQr0eRDf4Q5sN/nbTwksapPHfze8dKcaoA7A2NqT3bJ6DPGrwVCzGRtGw/SXJwFwmmtAl9O6BklpeReyiknSxc+KOtrjDW6O0r6yvymD5Z nixery diff --git a/infra/kubernetes/nixery/known_hosts b/infra/kubernetes/nixery/known_hosts new file mode 100644 index 000000000000..1bae52b8991a --- /dev/null +++ b/infra/kubernetes/nixery/known_hosts @@ -0,0 +1 @@ +github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== diff --git a/infra/kubernetes/nixery/secrets.yaml b/infra/kubernetes/nixery/secrets.yaml new file mode 100644 index 000000000000..ec97a29d362a --- /dev/null +++ b/infra/kubernetes/nixery/secrets.yaml @@ -0,0 +1,19 @@ +# The secrets below are encrypted using keys stored in Cloud KMS and +# templated in by kontemplate when deploying. +# +# Not all of the values are actually secret (see the matching) +--- +apiVersion: v1 +data: + gcs-key.json: {{ passLookup "nixery-gcs-json" | b64enc }} + gcs-key.pem: {{ passLookup "nixery-gcs-pem" | b64enc }} + id_nixery: {{ passLookup "nixery-ssh-private" | b64enc }} + id_nixery.pub: {{ insertFile "id_nixery.pub" | b64enc }} + known_hosts: {{ insertFile "known_hosts" | b64enc }} + ssh_config: {{ insertFile "ssh_config" | b64enc }} +kind: Secret +metadata: + creationTimestamp: null + name: nixery-secrets + selfLink: /api/v1/namespaces/kube-public/secrets/nixery-secrets +type: Opaque diff --git a/infra/kubernetes/nixery/ssh_config b/infra/kubernetes/nixery/ssh_config new file mode 100644 index 000000000000..78afbb0b039d --- /dev/null +++ b/infra/kubernetes/nixery/ssh_config @@ -0,0 +1,4 @@ +Match host * + User tazjin@google.com + IdentityFile /var/nixery/id_nixery + UserKnownHostsFile /var/nixery/known_hosts diff --git a/secrets/nixery-gcs-json b/secrets/nixery-gcs-json new file mode 100644 index 000000000000..b8b544511685 --- /dev/null +++ b/secrets/nixery-gcs-json Binary files differdiff --git a/secrets/nixery-gcs-pem b/secrets/nixery-gcs-pem new file mode 100644 index 000000000000..798a1e5a66f8 --- /dev/null +++ b/secrets/nixery-gcs-pem Binary files differdiff --git a/secrets/nixery-ssh-private b/secrets/nixery-ssh-private new file mode 100644 index 000000000000..5c4ff2023350 --- /dev/null +++ b/secrets/nixery-ssh-private Binary files differdiff --git a/tools/bin/__dispatch.sh b/tools/bin/__dispatch.sh index 09b404f3b33d..20848bd5118c 100755 --- a/tools/bin/__dispatch.sh +++ b/tools/bin/__dispatch.sh @@ -22,6 +22,9 @@ case "${TARGET_TOOL}" in stern) attr="stern" ;; + pass) + attr="tazjin.kms_pass" + ;; *) echo "The tool '${TARGET_TOOL}' is currently not installed in this repository." exit 1 diff --git a/tools/bin/pass b/tools/bin/pass new file mode 120000 index 000000000000..8390ec9c9652 --- /dev/null +++ b/tools/bin/pass @@ -0,0 +1 @@ +__dispatch.sh \ No newline at end of file diff --git a/tools/kms_pass/default.nix b/tools/kms_pass/default.nix new file mode 100644 index 000000000000..fbc17650a948 --- /dev/null +++ b/tools/kms_pass/default.nix @@ -0,0 +1,60 @@ +# This tool mimics a subset of the interface of 'pass', but uses +# Google Cloud KMS for encryption. +# +# It is intended to be compatible with how 'kontemplate' invokes +# 'pass.' +# +# Only the 'show' and 'insert' commands are supported. + +{ google-cloud-sdk, tree, writeShellScriptBin +, project, region, keyring, key }: + +writeShellScriptBin "pass" '' + set -eo pipefail + + CMD="$1" + readonly SECRET=$2 + readonly SECRET_PATH="$SECRETS_DIR/$SECRET" + + function secret_check { + if [[ -z $SECRET ]]; then + echo 'Secret must be specified' + exit 1 + fi + } + + if [[ -z $CMD ]]; then + CMD="ls" + fi + + case "$CMD" in + ls) + ${tree}/bin/tree $SECRETS_DIR + ;; + show) + secret_check + ${google-cloud-sdk}/bin/gcloud kms decrypt \ + --project ${project} \ + --location ${region} \ + --keyring ${keyring} \ + --key ${key} \ + --ciphertext-file $SECRET_PATH \ + --plaintext-file - + ;; + insert) + secret_check + ${google-cloud-sdk}/bin/gcloud kms encrypt \ + --project ${project} \ + --location ${region} \ + --keyring ${keyring} \ + --key ${key} \ + --ciphertext-file $SECRET_PATH \ + --plaintext-file - + echo "Inserted secret '$SECRET'" + ;; + *) + echo "Usage: pass show/insert <secret>" + exit 1 + ;; + esac +'' |