Compare commits

..

46 Commits

Author SHA1 Message Date
Hoan To 70ab8667af fixed mgmt public key 1 month ago
KyrakerzNetgo 5ca02f56a2 new gpg key for tax 2 months ago
jan.jantzen 2170376e81 moved Dustin Bleschke's public key to archive 2 months ago
jan.jantzen 7721dfe117 Update jan.jantzen public key 2 months ago
Michael Haehnel 9dbdde4b36
ADP-3780: Corrects adp-staging environment
Changelog: Updated
5 months ago
Michael Haehnel 665f39c1d5
ADP-3780: Adds gpg pub keys for adp-mgmt and adp-staging environment
Changelog: Updated
5 months ago
jan.jantzen 5d12cc6d54 add comment 5 months ago
Andreas.Rother 47a30ad1f2 added key for tobias p 5 months ago
Andreas.Rother 426cc6d943 changed public keys for ulf and thi and added andreas to sops.yaml 5 months ago
jan.jantzen 5891b61259 add thi nguyen and ulf fischer public keys verify sops.yml 5 months ago
jan.jantzen 187a8a6337 add thi nguyen and ulf fischer public keys 5 months ago
daniel.risse c3cc147ed2 fix key 6 months ago
daniel.risse d1ce01a9d6 add Daniel Risse Public Key 6 months ago
Claus Paetow cc64355eed gpg key from claus.paetow changed 7 months ago
Dustin Bleschke a165d1a6c3 GPG key for Dustin(me) :) 7 months ago
Michael Haehnel 85d1da2795
NOTICKET: Readds Kevins gpg key
Changelog: Updated
8 months ago
Kyra Kerz ae2666dc61 add gpg key 8 months ago
Andreas Rother 715148b91b added pub key andreas.rother@netgo.de.gpg.pub 9 months ago
Michael Haehnel 23b0ab4f0f
fix[DEV-1368]: Remove obsolete user pubkeys
Changelog: removed
9 months ago
Christos Adalis f10a6a794d create user and pgp key - Christos Adalis 9 months ago
Daryl Sauer-Neumann 78cff885d8 added daryl.sauer-neumann@netgo.de.gpg.pub 9 months ago
Lee Watson 75a3c94f6e ADP-231 adds group for argocd-os-nso-adp-dev 9 months ago
Lee Watson aff320d809 ADP-216 simplifies test control flow 9 months ago
Lee Watson 9877df6455 Merge branch 'ADP-216-uat-sops-step2_003' into 'master'
ADP-216 uat sops step2 003

See merge request smardigo-hetzner/communication-keys!21
10 months ago
Lee Watson 0164502ef0 ADP-216 uat sops step2 003 10 months ago
Lee Watson f607db9b97 Merge branch 'ADP-216-uat-sops-step2_002' into 'master'
ADP-216 uat sops step2 002

See merge request smardigo-hetzner/communication-keys!20
10 months ago
Lee Watson 0300b3d944 ADP-216 uat sops step2 002
* make instructions procedural
* clarify several steps
10 months ago
Lee Watson c9b987fe58 Merge branch 'ADP-216-uat-sops-step1' into 'master'
ADP-216: updates README from UAT feedback

See merge request smardigo-hetzner/communication-keys!19
10 months ago
Lee Watson 84ce66fdd7 ADP-216: updates README from UAT feedback for step1 10 months ago
Lee Watson 8a035c2fd3 Merge branch 'ADP-216-uat-sops-step2' into 'master'
ADP-216: sops automation UAT

See merge request smardigo-hetzner/communication-keys!18
10 months ago
Lee Watson 76e26d7f77 ADP-216: sops automation UAT
* clarifies README
* disables error when operating on unencrypted "dummy" secrets files (some workflows have strict requirement for a file named 'secrets.yaml' even if it's empty,unencrypted)
* avoids printing secrets by default after sops update, moves the "for verification" dump back into the verify script (it had wandered out of quarantine at some point)
* improves cross-platform operation (s/realpath/readlink), although not strictly necessary, it is the result of troubleshooting and not a bad idea to just keep the change.
10 months ago
LeeW cf80808240 Add BC to .sops.yaml: Step 2: Configure sops config 10 months ago
Bas Cancrinus 240c1f37da Add BC to .sops.yaml 10 months ago
Bas Cancrinus d3881fbff4 Fix chapter numbers in readme 10 months ago
Bas Cancrinus 7b86143ddb Merge branch 'add_pubkey_bas-cancrinus' into 'master'
On-boarding step 1a and 1b

See merge request smardigo-hetzner/communication-keys!17
10 months ago
Bas Cancrinus 0ea01e3b96 On-boarding step 1a and 1b 10 months ago
Frederik Marticke 1fc08259af Bugfix: Added missing "!" 10 months ago
Bas Cancrinus e8ab7f159c Merge branch 'ADP-216-uat-sops-onboarding' into 'master'
Adp 216 uat sops onboarding

See merge request smardigo-hetzner/communication-keys!16
10 months ago
Lee Watson 8c881e18eb Adp 216 uat sops onboarding 10 months ago
Lee Watson 258e53bbec https://issues.arxes-tolina.de/browse/ADP-216
* adds script for generating SOPS config based on keyfiles
  * adds "groups" concept for managing access
  * adds methodology for verifying correct sops configuration
  * adds tests for script
* overhauls instructions with comprehensive steps
10 months ago
Lee Watson 37a2ad9ea9 ADP-216 sops automation 10 months ago
Lee Watson 7a09a4f179 Merge branch 'ADP-179_sops_manage_keys' into 'master'
ADP-179 sops manage keys

See merge request smardigo-hetzner/communication-keys!15
10 months ago
Lee Watson 8df5b8e084 ADP-179 sops manage keys
archives old keys, updates doc
10 months ago
Michael Hähnel 5ba3bc542b Merge branch 'ADP-179_doc_sops' into 'master'
ADP-179 doc sops

See merge request smardigo-hetzner/communication-keys!13
10 months ago
Lee Watson 9b0fad9172 ADP-179 doc sops 10 months ago
Hoan To 22124e6d99 added ssp prod key 10 months ago

@ -5,31 +5,177 @@ Purpose: Manage gpg keys for:
# Key Management # Key Management
## howto create and add a gpg key * Role: New User: new key to be added; can be a new employee being added for first time, existing employee getting access to a new repo, key rotation, etc
- please follow instruction on following link: https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key * Role: Existing User: user who already has access to the appropriate project
- add ONLY the _PUBLIC_ part of your gpg key!!! * Definition: List of all users: [verify/.sops.yaml](verify/.sops.yaml)
- checkin via MergeRequest/PullRequest * Keys Repository: This Git Repository (`communication-keys`), manages public keys and configuration in Project Repositories
* Project Repository: Git Repository for each Project which contains SOPS-Encrypted secrets, e.g. for GitOps Deployments using Helm Files
### import gpg keys
# Playbook for Configuring Access for New Users
## Overview:
1. In the Keys Repo (`communication-keys`):
1. New User creates,adds GPG Key
1. Existing User configures groups
1. Existing User configures verification SOPS Config
1. New User installs SOPS
1. New User verifies SOPS installation using verification SOPS Config
1. **Status**: New User has working key, working sops installation. Caveat: No access to secrets in other repos yet
1. In the Project Repo
1. Existing User adds New User Key to SOPS Config, Secrets Files
1. New User verifies access
1. **Status**: New User has access to SOPS-encrypted secrets within Project Repo
## 1a. Onboarding: [New User]: create and add a gpg key
1. Clone this repository
1. Create a branch titled `add_pubkey_[firstname]-[lastname]`. <!-- NOTE: Validation Hack: User will not be able to mistakenly create this literal branch, as the unpermitted chars '[' will prevent the branch from being created: "Branch name cannot contain '['" as per https://git-scm.com/docs/git-check-ref-format. I.e. it's a dirty hack to get some server-side(?) validation ;-) --> <!-- - Web: e.g. The following link can be used to create a branch: [https://git.dev-at.de/smardigo-hetzner/communication-keys/-/branches/new?branch_name=add_pubkey_[firstname]-[lastname]](https://git.dev-at.de/smardigo-hetzner/communication-keys/-/branches/new?branch_name=add_pubkey_[firstname]-[lastname]) -->
- CLI: e.g. `git branch add_pubkey_Max-Musterman`
- Note: no strict naming convention for the branch, it's strictly a Human-in-the-Loop process
1. Follow steps 1-13 at the following link: https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key
- CAVEAT: step 14 is not necessary, as it is specific to a GitHub account
1. add ONLY the _PUBLIC_ part of your gpg key!!! to your branch
- file format: `<email>@netgo.de.gpg.pub`
- **Example**: `max.musterman@netgo.de.gpg.pub`
1. git: commit the new file, push
1. gitlab: open a MergeRequest
1. **Hand-Off**: Assign the MR to an Existing User in your Team to have your key added.
- Hint: Look up all Existing Users in the comments at: [verify/.sops.yaml](verify/.sops.yaml)
## 1b. Onboarding: [Existing User|New User]: Add new user to groups
**Prerequisite**: Determine the groups to which access is needed, e.g. a specific repository. If uncertain, ask a Team Member for help!
**Technical Instructions** - please forgive the complexity
Create a symlink from the group-directory back to the keyfile
1. `cd groups/<project_name>`
- **Example**: `cd groups/devnso-adp-argocd`
- Explanation: Access for each repo is tracked using the `./groups/` directory; each sub-directory represents a "group" (Note: some "groups" are also "roles", e.g. `admin`)
- Explanation: Most of the groups correspond directly to git repository names, aka "project name"
1. `ln -s ../../<path_to_key.gpg.pub>`
- **Example**: `ln -s ../../max.musterman@netgo.de.gpg.pub`
## 2. Onboarding: [Existing User]: Configure sops config
Context: This repo stores the keys used to encrypt secrets in other repos; these "consumer" repos each contain a sops config `.sops.yaml` which manages access to the encrypted files (e.g. `secrets.yaml`)
For verification purposes, this repo also contains a _sample_ `.sops.yaml` to which every key in the repo is added. This allows both Existing Users to instantly verify the new key, and New Users to verify that their sops installation works correctly.
### Update Verification SOPS Config
1. Checkout the New User's branch titled `add_pubkey_[firstname]-[lastname]`.
- CLI: e.g. `git branch add_pubkey_Max-Musterman`
1. Run `./verify/usr_confirm_keycfg.sh`
1. git: commit the new file, push
1. **Status**: New User has working SOPS Configuration
1. **Hand-Off**: Proceed to next steps; Instruct New User to verify access to secrets
### Update Project SOPS Config
The following commands explain how to update the `.sops.yaml` for a repository.
Note: For a worked-through example, see next section.
1. **Prerequisite**
1. Obtain Project Repo
- CLI:: `git clone <repo_url>`
1. **Create Branch**
- CLI: `git checkout -b add_pubkey_[firstname]-[lastname] origin/main`
1. **Configure Project Repo for New User**
1. List available groups:
- CLI: `${PATH_TO_COMMUNICATION_KEYS_REPO}/bin/update_sops.sh --list_groups`
- Reminder: Group Name usually corresponds to Repository Name
1. Update sops config AND all secrets files:
- CLI: `${PATH_TO_COMMUNICATION_KEYS_REPO}/bin/update_sops.sh --group <group_name> --find_secrets
1. **Commit the changes, Create Change Request (PR/MR)**
1. git: commit the changes to `.sops.yaml` and secrets files (`secrets.yaml`) files
- CLI: `git add .sops.yaml $(find . -name secrets.yaml)`
- **CAVEAT**: check for other changes with `git status` ! The files do not always follow consistent conventions.
- CLI: `git commit -m "adds <firstname>.<lastname> to sops config"`
1. git: push branch
- CLI: `git push -u origin add_pubkey_[firstname]-[lastname]`
1. gitlab: open a MergeRequest, Review, Merge
1. **Status**: New User has access to SOPS-Encrypted Secrets within Project Repo
1. **Hand-Off**: Proceed to next steps; Instruct New User to verify access to secrets
#### Example
**Prerequisite**
Obtain Repo
```shell ```shell
gpg --import /path/to/keys/*.gpg.pub # E.g. update sops config for DevNSO
% git clone git@git.dev-at.de:cloud-solutions/nso/devnso-adp-argocd.git
% cd devnso-adp-argocd/
``` ```
**Create Branch**
### list imported gpg keys
```shell ```shell
gpg --list-keys --keyid-format=long ## OPINIONATED GIT - use preferred method
git checkout -b add_pubkey_max-musterman origin/main
```
**Configure Project Repo for New User**
<!-- TODO: auto-determine group with git remote show origin -->
<!-- TODO: auto-determine secrets files by integrating the 'find . -name secrets.yaml' in the script -->
```shell
# List available groups
# Output:
% ${PATH_TO_COMMUNICATION_KEYS_REPO}/bin/update_sops.sh --list_groups
# INFO: listing groups
admin
automation
devnso-adp-argocd
# For a given group, update sops config AND all secrets files - New Users cannot add themselves!
# Output:
% ${PATH_TO_COMMUNICATION_KEYS_REPO}/bin/update_sops.sh --group devnso-adp-argocd --find_secrets
# RUN: generate SOPS config
# RUN: gpg --import *.gpg.pub
# RUN: sops updatekeys ./loki/loki/secrets.yaml
...
# SUCCESS: all users with keys in this dir should have functional keys
```
**Commit the changes, Create Change Request (PR/MR)**
```shell
# git: commit the changes to `.sops.yaml` and secrets files (`secrets.yaml`) files
% git add .sops.yaml $(find . -name secrets.yaml)
# **CAVEAT**: check for other changes with `git status` ! The files do not always follow consistent conventions.
# output:
% git status
...
no changes added to commit (use "git add" and/or "git commit -a")
% git commit -m "adds max.musterman to sops config"
git push -u origin add_pubkey_max-musterman
``` ```
# Configure SOPS Now proceed to with the remaining steps, i.e. gitlab: open a MergeRequest, Review, Merge
## 3. Onboarding: [New User] Configure SOPS
SOPS is used for encrypting secrets, e.g. credentials for various systems SOPS is used for encrypting secrets, e.g. credentials for various systems
## Install
https://github.com/getsops/sops ## Install
Note: 1. **Install Sops**
* MacOS: If desired, one can also use brew to install sops: `brew install sops`; although this is not officially maintained, [the formula is essentially the same as the official installation instructions](https://github.com/Homebrew/homebrew-core/blob/4496ce5131bc09e7065fa0aa8fb96366a3df6477/Formula/s/sops.rb) 1. https://github.com/getsops/sops
- Note:
* MacOS: If desired, one can also use brew to install sops: `brew install sops`; although this is not officially maintained, [the formula is essentially the same as the official installation instructions](https://github.com/Homebrew/homebrew-core/blob/4496ce5131bc09e7065fa0aa8fb96366a3df6477/Formula/s/sops.rb)
1. **Configure Sops**
* Add the following to your `~/.bashrc` or `~/.zshrc` - but _not_ to your `~/.profile` as it must be set per session:
```shell
# Enable interactive passphrase prompt for SOPS
export GPG_TTY=$(tty)
```
1. **Verify SOPS Installation and Key Configuration**
1. `./verify/usr_confirm_keycfg.sh`
## Usage ## Usage
@ -38,29 +184,88 @@ Decrypt and Display Secrets in Terminal:
```bash ```bash
GPG_TTY=$(tty) sops secrets.yaml GPG_TTY=$(tty) sops secrets.yaml
``` ```
<!-- CAVEAT: if GPG_TTY is set in environment, no need to specify it again. Leaving it inline for this command to be explicit about requirement for correct functiuonality -->
Note: The `GPG_TTY` is necessary to have the password prompt appear. src: https://www.varokas.com/secrets-in-code-with-mozilla-sops/ Note: The `GPG_TTY` is necessary to have the password prompt appear. src: https://www.varokas.com/secrets-in-code-with-mozilla-sops/
Note: `secrets.yaml` is just an example; the file can have any name Note: `secrets.yaml` is just an example; the file can have any name
## Example # Playbook for Removing Expired Keys
## Offboarding: [Existing User]: Archive Expired Keys (EOL)
To mark a key as expired:
1. move it to the `archive/` dir
2. for each group, update the project repo
3. remove the key from the group
### 1. This repo: archive
```shell
# archive key - DO NOT delete - need this for auditing
git mv ${keyname} "archive/${keyname}_$(date '+%Y-%m-%d').archive"
# remove from verification sops
./verify/usr_confirm_keycfg.sh
```
### 2. For each group / repo:
**Prerequisite**: Local copy of each repo corresponding to a group
```shell
# list all groups to which the key is registered
find groups/ -name ${keyname}
# For each group, update sops config in that repo
# Example:
% cd devnso-adp-argocd
% ${PATH_TO_COMMUNICATION_KEYS_REPO}/bin/update_sops.sh --group devnso-adp-argocd --find_secrets
# now git commit, push, etc
```
### 3. This repo: update groups
```shell
# remove from groups
find groups -name ${keyname} | xargs git rm
```
# Advanced
# Reference: Commands for gpg keys
## import gpg keys
```shell
gpg --import /path/to/keys/*.gpg.pub
```
## list imported gpg keys
```shell
gpg --list-keys --keyid-format=long
```
## SOPS Example - Manual
The steps in the following example can be run locally in order to: The steps in the following example can be run locally in order to:
* create a sample secrets file * create a sample secrets file
* encrypt the file * encrypt the file
* decrypt the file * decrypt the file
If these steps work, sops is configured correctly - on your machine ;-) If these steps work, sops is configured correctly - on your machine ;-)
```bash ```bash
#!/usr/bin/env bash #!/usr/bin/env bash
set -ueo pipefail set -ueo pipefail
# demo: create a file with a mock secret, src: https://bash-org-archive.com/?244321 # demo: create a file with a mock secret, src: https://bash-org-archive.com/?244321
# PREREQUISITE: valid sops config, i.e. .sops.yaml # PREREQUISITE: valid sops config, i.e. .sops.yaml - Note: most repos already have one
# further reading: https://github.com/getsops/sops?tab=readme-ov-file#using-sops-yaml-conf-to-select-kms-pgp-and-age-for-new-files
yq -n '.demo.credentials.secret = "hunter2"' > secrets.yaml yq -n '.demo.credentials.secret = "hunter2"' > secrets.yaml
# encrypt # encrypt
sops -e -i secrets.yaml sops -e -i secrets.yaml
# decript, print to console # decript, print to console
sops -d secrets.yaml sops -d secrets.yaml
``` ```
# Contributing
Tests: `./verify/test.sh`
Caveat: requires working SOPS config,pgp key, etc

@ -0,0 +1,42 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
tPQpHpp5OcriKFWxiZSM41Wm5yHn5Yc=
=BUTZ
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEaD2xXRYJKwYBBAHaRw8BAQdAKL1LP1gP7t3R41tNdVH5cUu7OksuY7FDwoq0
EX/IznG0KkR1c3RpbiBCbGVzY2hrZSA8ZHVzdGluLmJsZXNjaGtlQG5ldGdvLmRl
PoiTBBMWCgA7FiEEjWAJEv1C71NS043SL9cfRX73u4sFAmg9sV0CGwMFCwkIBwIC
IgIGFQoJCAsCBBYCAwECHgcCF4AACgkQL9cfRX73u4trEAD/Z/e5IU9+PyU0oSFT
tu9i2t2muFwrNdxsrkgATNJoJqEBAPGRo5apeOwH/8rqfOnK89AMUPPD9DS5Giqg
RPOT4/UOuDgEaD2xXRIKKwYBBAGXVQEFAQEHQKI0sArCldO4QoHZZNUDpk2e92WC
aJSpEpqaQ1ODqGVwAwEIB4h4BBgWCgAgFiEEjWAJEv1C71NS043SL9cfRX73u4sF
Amg9sV0CGwwACgkQL9cfRX73u4tnzQEA5+wX3G6uInM8rkMCGxaZ4/0gV30Kc2ye
1YqWNjZBgKUBAKLeSWj7VzdV/nZ/rgmrZx44pQxbsv5IYaZbYKxanuwD
=vPAd
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ8csoBYJKwYBBAHaRw8BAQdA4XDYoQCpDYRQVMdhXWaQ8R+DJWfDUZKLGp0L
CDKQkLG0JkJhcyBDYW5jcmludXMgPGJhcy5jYW5jcmludXNAbmV0Z28uZGU+iJME
ExYKADsWIQSfU0FojS+QJKFVQcngKUnQ93aeLAUCZ8csoAIbAwULCQgHAgIiAgYV
CgkICwIEFgIDAQIeBwIXgAAKCRDgKUnQ93aeLCLFAP0XM8gj8Dj6/j+CudjOemlZ
YtMeWKgzoQavq5MjvqpC5gD/SfhHrENFxqIauGyLhX3YOlYTu77nFjFD9Ue4eiXe
gAi4OARnxyygEgorBgEEAZdVAQUBAQdANCBJmJchzCLLpCje17NJp4xn5gKXMLQ5
eEonhmkAdUMDAQgHiHgEGBYKACAWIQSfU0FojS+QJKFVQcngKUnQ93aeLAUCZ8cs
oAIbDAAKCRDgKUnQ93aeLC07AP4jKmcbtyZGhV2efFbmempjylr231bG/3s5xust
+csUTwEAwu1QQPRX/OYpecVo0xIDiynnk4jeJDsRyOuFMkYpTw0=
=t/YD
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,244 @@
#!/usr/bin/env bash
# Purpose: manage .sops.yaml based on gpg keys in the same dir _and_ verify correct configuration
set -euo pipefail
function fn_gpg_extract_fpr(){
# PURPOSE: get fingerprint from gpg keyfile
gpgkeyfile=$1;shift;
# fingerprint
# caveat: restrict to netgo.de email, use-case:
# uid ... <...@mehrwerk.net>
# uid ... <...@netgo.de>
# fancy gpg src: https://unix.stackexchange.com/a/731872
fpr="$(gpg --show-keys --list-options show-only-fpr-mbox "$(readlink -f "${gpgkeyfile}")" | grep '@netgo.de' | awk "{print \$1}")"
echo "${fpr}"
}
function fn_gpg_extract_uid(){
# PURPOSE: get user-id from gpg keyfile
gpgkeyfile=$1;shift;
# user id
# caveat: restrict to netgo.de email, use-case:
# uid ... <...@mehrwerk.net>
# uid ... <...@netgo.de>
# fancy gpg src: https://unix.stackexchange.com/a/731872
uid="$(gpg --show-keys --with-colons "$(readlink -f "${gpgkeyfile}")" | awk -F':' '$1=="uid" {print $10}' | grep '@netgo.de')"
echo "${uid}"
}
function fn_sops_locate_config_in_git_repo(){
# PURPOSE: locate sops config
# Returns path sops config to be updated; defaults to returning "$(git rev-parse --show-toplevel)/.sops.yaml"
# sops locates config by recursively walking _up_ the tree from the execeution dir context,
# + _but_ does not have a mechanism to update the sops config
# This function does the same in order to locate the correct sops config to update
# starting dir, default: PWD. Note: 'realpath' to normalise the dir
start_dir="$(realpath "${1:-"${PWD}"}")";
stop_dir="$(git rev-parse --show-toplevel)"
>&2 echo "# ---"
>&2 echo "# start_dir: "${start_dir}""
>&2 echo "# stop_dir: "${stop_dir}""
# BEGIN
search_dir="${start_dir}"
contender="${search_dir}/.sops.yaml"
# base case - located the file OR stopping condition - at top of repo
if [[ -e "${contender}" ]]; then
>&2 echo "# BASE CASE: found ${contender}"
echo "${contender}"
elif [[ "${search_dir}" == "${stop_dir}" ]]; then
>&2 echo "# STOPPING CONDITION: no sops config found, suggesting: ${contender}"
echo "${contender}"
else
>&2 echo "# walk up one dir..."
fn_sops_locate_config_in_git_repo "$(dirname "${search_dir}")"
fi
}
function fn_sops_generate_config(){
# PURPOSE: generate sops config based on keyfiles
# sops.yaml doc: https://github.com/getsops/sops?tab=readme-ov-file#using-sops-yaml-conf-to-select-kms-pgp-and-age-for-new-files
# CAVEAT: dirty hacks, as DRY as feasible within bash
>&2 echo "# RUN: generate SOPS config"
# hack: 2D list workaround, i.e. difficult to have list-of-lists
fpr_list=()
uid_list=()
type_list=()
for gpgkeyfile in *automation*gpg.pub; do
type_list+=( "autom" )
fpr_list+=( "$(fn_gpg_extract_fpr "${gpgkeyfile}")" )
uid_list+=( "$(fn_gpg_extract_uid "${gpgkeyfile}")" )
done
for gpgkeyfile in $(ls *gpg.pub | grep -v automation); do
type_list+=( "human" )
fpr_list+=( "$(fn_gpg_extract_fpr "${gpgkeyfile}")" )
uid_list+=( "$(fn_gpg_extract_uid "${gpgkeyfile}")" )
done
# header
echo "# Fingerprint | User Type | User ID"
# entries/rows
for ind in "${!fpr_list[@]}"; do
printf "# %s | %s | %s\n" \
"${fpr_list[${ind}]}" \
"${type_list[${ind}]}" \
"${uid_list[${ind}]}"
done
echo "# keys in https://git.dev-at.de/smardigo-hetzner/communication-keys"
cat <<EOM
creation_rules:
# list of keys for encryption in stage
- pgp: >-
EOM
# all but last line get comma
ind_2nd_last=$((${#fpr_list[@]} - 1))
for fpr in ${fpr_list[@]:0:${ind_2nd_last}}; do
echo " ${fpr},"
done
# last line no comma
# echo " ${fpr_list[-1]}," # requires bash v4.1
echo " ${fpr_list[${ind_2nd_last}]}"
}
fn_sops_updatekeys_and_verify(){
# PURPOSE: call 'sops updatekeys' and dump contents of file so end user can visually verify functionality
sops_enc_file="${1}";shift;
# update keys in secrets file
test -e "${sops_enc_file}" || exit 1
# "update the keys of SOPS files using the config file"
>&2 echo "# RUN: sops updatekeys ${sops_enc_file}"
# HAAAACK: loop through all passed-in files, ignore any errors, always say "yes" -> rely on git diff to verify!
sops updatekeys -y "${sops_enc_file}" || echo "SKIPPING"
}
function main(){
if [[ ! -n "${@}" ]]; then
# if empty args, remove
shift
fi
# "anchor" for actions relevant to this script
repo_root="$(realpath $(dirname "${BASH_SOURCE[0]}")/..)"
# OPTIONS: ARGPARSING and VALIDATION
# assume location of script as running directly from repo with keys (instead of as a standalone packaged tool)
keyfiles_dir="${repo_root}"
# dir containing .sops.yaml
sops_config_dir=""
# path to group definitions
groups_def_dir="${repo_root}/groups"
opt_list_groups=0
groups_list=()
opt_find_secrets=0
secrets_file_list=()
while (( $# >= 1 ));do
cur="${1}";
case $cur in
# ARGS: print this help
-h|--help) echo "# ARGUMENTS:"; grep -A 1 '# ARGS:' "${BASH_SOURCE[0]}"; exit 0 ;;
# ARGS: [optional] dir containing gpg keyfiles. defaults to git repo root, var: ${repo_root}
-k|--key|--keyfiles) keyfiles_dir="${2}"; shift ;;
# ARGS: [optional] defines dir for sops config file (.sops.yaml), create if needed. defaults to git repo root, var: ${repo_root}
-c|--config_dir) sops_config_dir="${2}"; shift ;;
# ARGS: [optional] show list of groups and exit
-lg|--list_groups) opt_list_groups=1 ;;
# ARGS: [optional] [list] specify "groups" which correspond to e.g. job groups, projects, etc
-g|--group) groups_list+=( "${2}" ); shift ;;
# ARGS: [optional] update all "secrets.yaml" files found below .sops.yaml location
-f|--find_secrets) opt_find_secrets=1;;
# ARGS: [optional] [list] specify files containing sops-encrypted secrets
-s|--secrets_file|-f|--file) secrets_file_list+=( "${2}" ); shift ;;
# ARGS: [optional] [list] specify files containing sops-encrypted secrets
*) secrets_file_list+=( "${cur}" )
esac
shift;
done
# Resolve Parameters
# ... i.e. combine,override,etc options which interact
if [[ "${#groups_list[@]}" -eq 1 ]]; then
# simply change keyfiles_dir to the "groups" dir
keyfiles_dir="${groups_def_dir}/${groups_list[0]}"
elif [[ "${#groups_list[@]}" -gt 1 ]]; then
>&2 echo "# ERROR: only specify one group"
exit 1
fi
# VALIDATE INPUTS
keyfiles_dir="$(realpath "${keyfiles_dir}")"
test -d "${keyfiles_dir}" || (echo "E: specify dir containing keyfiles; invalid dir: '${keyfiles_dir}'" && exit 1)
# define sops config location
sops_config=""
if [[ -n "${sops_config_dir:-}" ]]; then
# user-specified
sops_config_dir="$(realpath "${sops_config_dir}")"
# vvv possibly redundant, since the 'realpath' will fail if dir not valid
test -d "${sops_config_dir}" || (echo "E: specify dir containing .sops.yaml, invalid dir: '${sops_config_dir}'" && exit 1)
sops_config="${sops_config_dir}/.sops.yaml"
else
# locate appropriate sops config if default assumption not found
# dev note: '2> /dev/null' to disable debug output
sops_config="$(fn_sops_locate_config_in_git_repo 2> /dev/null)"
sops_config_dir="$(dirname "${sops_config}")"
fi
# Paths to Secrets Files
if [[ "${#secrets_file_list[@]}" != "0" ]]; then
for secrets_file in "${secrets_file_list[@]}"; do
test -e "${secrets_file}" || (echo "E: could not locate file with secrets, tried: ${secrets_file}" && exit 1)
done
fi
if [[ "${opt_find_secrets}" -eq 1 ]]; then
# DEV NOTE: this is far too complicated
# loop through find, src: https://stackoverflow.com/questions/9612090/how-to-loop-through-file-names-returned-by-find
while IFS= read -r -d $'\0'; do
secrets_file_list+=("${REPLY}")
done < <( find "${sops_config_dir}" -name secrets.yaml -print0 )
fi
# /VALIDATE INPUTS
# /OPTIONS: ARGPARSING and VALIDATION
# BEGIN
if [[ "${opt_list_groups}" -eq 1 ]]; then
# list available groups and exit
pushd "${groups_def_dir}" > /dev/null 2>&1
>&2 echo "# INFO: listing groups"
ls -1d *
exit 0
popd > /dev/null 2>&1
fi
# UPDATE SOPS CONFIG
# update sops config
# TODO: remove the 'pushd;popd' workaround and make the functions aware of the dir being read
pushd "${keyfiles_dir}" > /dev/null 2>&1
(fn_sops_generate_config) > "${sops_config}"
popd > /dev/null 2>&1
# VERIFY
if [[ "${#secrets_file_list[@]}" != "0" ]]; then
# import keys
pushd "${keyfiles_dir}" > /dev/null 2>&1
>&2 echo "# RUN: gpg --import *.gpg.pub"
gpg_out="$(gpg --import *.gpg.pub 2>&1)"
popd > /dev/null 2>&1
# update
for secrets_file in "${secrets_file_list[@]}"; do
fn_sops_updatekeys_and_verify "${secrets_file}"
done
echo "# SUCCESS: all users with keys in this dir should have functional keys"
else
echo "# WARN: no secrets file passed in, make sure to call 'sops updatekeys' on secrets files"
fi
}
# pass-through, set default value
main "${@-}"
exit

@ -0,0 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ9LiixYJKwYBBAHaRw8BAQdAo9TZ7FbNytrM9Odrm1fg4SV3AurPr6B4Z6wT
bYmc0Iu0NUNocmlzdG9zIEFkYWxpcyAoR1BHIEtleXMpIDxjaHJpc3Rvcy5hZGFs
aXNAbmV0Z28uZGU+iJMEExYKADsWIQT38yjw5JWOTHhZd+I7iqC6q62v5AUCZ9Li
iwIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgAAKCRA7iqC6q62v5JTTAP0R
ME/a4n1TkA7QtUc06KEhdYPld8T3udBusk67jWLGMQEA/niJGzcmoSbNDGvC6hLi
fw9ZlohBFItF8Dur/mLPWgS4OARn0uKLEgorBgEEAZdVAQUBAQdArq2uimWJutt0
DsCEPAwlirHZI476ks1eNr8n3RTzbhEDAQgHiHgEGBYKACAWIQT38yjw5JWOTHhZ
d+I7iqC6q62v5AUCZ9LiiwIbDAAKCRA7iqC6q62v5KgjAP9Q/dfkGy0/9cKJsmPD
emKfbZbQ8FrNX70+oYMGxjV3WwEAyol9yD1pJSt1g3R9/oHo7/KW5ZsXbVIx/Vqc
uskiLgA=
=sg0j
-----END PGP PUBLIC KEY BLOCK-----

@ -1,52 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGJWv54BEADYY6n9rrteddJ99h3erlB3pgJV+ixR7Qb/sCRFiMGcEV9PLiZr mDMEaEBF9xYJKwYBBAHaRw8BAQdA6syYUNOSScarxQGom8QcmY/yaK+OWhAQ68IY
8vkRlrRORaIxFXa/xnYrQ12oPbXjWDajp389W7pRHTgw3gCKRVk8eb1rwT9ZbE/U dj7KxzW0JENsYXVzIFBhZXRvdyA8Y2xhdXMucGFldG93QG5ldGdvLmRlPoiQBBMW
trAL7ug7C+hPPkqiByHBbJ9mSfU1SrnLCAO8QFP0SXn6BVB6qSpouuorgZKwwjMm CgA4FiEEZZ/e1D3hVft3KjObNDzxIYpmTTEFAmhARfcCGwMFCwkIBwIGFQoJCAsC
Bef5Qgb9RfcrCoGQV/ks8za/aPUOuqxhyEm6bmys0jy5UhkYEvvT/RIZFD/mpv/P BBYCAwECHgECF4AACgkQNDzxIYpmTTHvVQEAi2IabzcpNK6ZBmsP2NL52oXhY4iM
hSOZNhQ2Job1PQgaIsM5KH7HpxOjZSjaPeA/buhyFTKCkAd474BHUWIAVxD65Kx3 bzDEtJul0E/hcvEA/3cPIZ9lIB8WeA6SK8nAgV5AlxGXsCdHsv55A2F/vDEIuDgE
n8pWIgbdd6kPgEOCycVx1SyNfdwz7WRINKZlTc3lJYLFy72xzhs0w4W85ssxB8mQ aEBF9xIKKwYBBAGXVQEFAQEHQNGjADOks0AjX4qlQ3xgSOP0RBIELjqYBH/Ihiwf
jwjoauMTGV+dqgsnqBIbDpYE16avUvS988vLicXhZb+dz8jmwxqBojwxGi/IvhLv eQ9ZAwEIB4h4BBgWCgAgFiEEZZ/e1D3hVft3KjObNDzxIYpmTTEFAmhARfcCGwwA
8x+2RD4ZZt3BpEnGI7JRN4FBpAK/kFGWbLKFgJZa+7cGfmC40zfTDqNdegukjtt0 CgkQNDzxIYpmTTFyOQEArR4vKYPP9cD6Plsn0pK4hONApCEHRKGC0d3JtUkZvJAB
puz5X64kJMGQ8ZucmG5x8fgW9qZv7bDZUXVDWIz2QynUxmDuGjzXyTIYlp9DJyQL ALaWq4tjsPm4wF6D9RMN9tCuPPVtt/FbGzVBlm3OP2sL
bRCv4PaNkp0CBELteswuIafKncnSfBsb6fIHjXexpt9ujztqGn6sIket2jmfCdOn =PsTc
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
1vC99G5EtuXL1U37Qp8Kug==
=vm8K
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,51 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=++7P
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ9Lk+hYJKwYBBAHaRw8BAQdAAImByKSkf+XTHj9o6BareP+aIhkTz1KV+4ZI
AsSgv/u0OURhcnlsIFNhdWVyLU5ldW1hbm4gKFNPUFMpIDxkYXJ5bC5zYXVlci1u
ZXVtYW5uQG5ldGdvLmRlPoiTBBMWCgA7FiEEAUMBn2JGntWmoBbCGcp2TTdZD58F
AmfS5PoCGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AACgkQGcp2TTdZD5/T
6gEAkVq5UnUPs6poLj2Tdqzlj13wToRpP3WFmDaa4mB9uM0A/1Yfde+hFFKIWPFR
hnfXeBH7HLHLC6EC7U58B8P8/aELuDgEZ9Lk+hIKKwYBBAGXVQEFAQEHQJZ2QRYW
XQ6N/wtLePHyafLb+D4wW4Di5SwoO2P/RwVZAwEIB4h4BBgWCgAgFiEEAUMBn2JG
ntWmoBbCGcp2TTdZD58FAmfS5PoCGwwACgkQGcp2TTdZD5939AD/U1HH5hOyo5n7
660ZFL5PoZpm9yxPwAUPa+Mp63QR/IQA/RNlBVGaCRlgWsPa7COo6n7yc0XfB6bi
on9JkIJgK0oB
=PxAk
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1 @@
../../claus.paetow@netgo.de.gpg.pub

@ -0,0 +1 @@
../../hoan.to@netgo.de.gpg.pub

@ -0,0 +1 @@
../../michael.haehnel@netgo.de.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_buildinfra.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_demompmx.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_dev.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_devnso-adp.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_devnso.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_prodnso.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_sot.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_sot_test.gpg.pub

@ -0,0 +1 @@
../../bas.cancrinus@netgo.de.gpg.pub

@ -0,0 +1 @@
../../christos.adalis@netgo.de.gpg.pub

@ -0,0 +1 @@
../../daryl.sauer-neumann@netgo.de.gpg.pub

@ -0,0 +1 @@
../../frederik.marticke@netgo.de.gpg.pub

@ -0,0 +1 @@
../../hoan.to@netgo.de.gpg.pub

@ -0,0 +1 @@
../../kleanthis.damianidis@netgo.de.gpg.pub

@ -0,0 +1 @@
../../michael.haehnel@netgo.de.gpg.pub

@ -0,0 +1 @@
../../smardigo_automation_devnso-adp.gpg.pub

@ -1,41 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGUf5j4BDADSd88HFIDGQseOiuJ2TXkqGZE//VDJFcXLQrbwTQaZXSLPkVc9 mDMEaPiOmBYJKwYBBAHaRw8BAQdAgwGFW1hsK88TTcY4Iw8GZSVAknR0iRKnOZL3
mZeTKbaEup4H0TYIR6cIUGEuBKRNXvxFJeriurC6jiy/ThNwW2tfRdSGxjyfjRro J+cp2fu0KUphbiBKYW50emVuIChzb3BzKSA8amFuLmphbnR6ZW5AbmV0Z28uZGU+
xcUWIogg24dOikoCb7QS3lCt/cAU4qEwmjFKX5Oqjg/ZdN+ODUlxl2pbLeDez93r iJkEExYKAEEWIQS5LdybkIvzkXdY0ihEbFHgSa44ygUCaPiOmAIbAwUJA8JnAAUL
X/eBEFLFxPIZIRn36GNL1M6b/nSNkhMUfV/Z+O8NUP3NoU/bNsiFyJy07zlPLap6 CQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgAAKCRBEbFHgSa44yphwAQDIKCvEYJ2x
xBRyBnn7zCAnuMGtvUcPVr9IpSc1AOHmMVBvhV8UpYhAX3+Mz+0WuaFRABMmkXOm gd8QClL31SGpD2/5fJ4x/9cXa2pwmcPo4AD/dWYsVwX6iisiE46U2IIsL7ojDa2J
XoO++6jVYwXh6b4ugsF3OtAJ+NYnbF4jWEqiGjVNbGEX1ikRMxlgFwM28VMNXc04 IYJPrb/HrL8w2Ay4OARo+I6YEgorBgEEAZdVAQUBAQdA9qvcdBmc2TvcReuAu3YA
FduQAArBRmsC5IFL6OoO9Ybx6y8eJ7/NVo/3ry6adnCUizzQTwSFn/iguvFs8xKG ePpddYljq1L7ihWZDUWrtRMDAQgHiH4EGBYKACYWIQS5LdybkIvzkXdY0ihEbFHg
NBYHlKZLAuqvYYJdLE9Jvs8Hy/ERGNwphl741CEcWHWrLVRljIh2b343uAGIRdoT Sa44ygUCaPiOmAIbDAUJA8JnAAAKCRBEbFHgSa44yi14AQDPHLsJLjE7csjNPVGi
otCGA4wJMK4ePZcAEQEAAbQiSmFuIEphbnR6ZW4gPGphbi5qYW50emVuQG5ldGdv 9XUcfq54ScEc698xyuk8LFMSKAEA0dzeY7tnfGNr7m2jq3odopRmMo99Xaw5h4YA
LmRlPokB1wQTAQgAQRYhBLpjKJSNUBdfGWqrURHzJGA9Et1WBQJlH+Y+AhsDBQkD cQD/yQo=
wmcABQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEBHzJGA9Et1WL0UL/1si =rCLM
cI0FMbC+H/zF2WRqNz4LcjV8SG9oTzwdeMV1CWdL1DTkbrWxHlIPVlwYmegAlzo9
9lOJEKcNUwhfyui43cLVBMmL7LULPwCOu2r+DGtQhbqI6tjKz5gNYLiBsc718M8Y
V/V//EcWTtG2uJFQ/Axq79r/HZXZ0/J8P9UXN5aVJXkhhJxZZn8QtcUblnKAyykz
QFac3m0b3SayPRSEVfDszOzrc2bFZiwav6dVBIyBpf9qrCChEAIpzqLzf7pxvWz9
VO7MzQaYYX3g4clkId1sCGPhYQuzdyCSVVyLFeGtFFnk/JeA7Bg3xaKC/aYSpaSZ
qFaXhDv2+pQ9MzYnSZ+i8IhBi7k3lLJbzDWTV0SJLvxoUIpyNL9ezwV7xweWRjQV
9XLCearZPoWxaAOqC8+YOG6FYtIW5pbVQ4j59FZz0UexD+kZHFV5TrZX0EYLkzrh
n/ZXEsMhCtok6eqyNe9DgRYnIH0QMHOSZf807D35R/zUzBwnOOtnmfxRwtksrbkB
jQRlH+Y+AQwArPtb+qWExEMBtUcsfq0P6+BDaJHcdP+PPb3Oa8plmDjRjTf7Exsm
KwQTGRZbYRlNFfh8072TSiu5rhNLyCfY0a79DPk2r1r3i4czx2x+m2m7ao0ZsOzE
tkdejlqxi9TIjWhxdSJHHcizeh1tOJU7TZhG04CW8bRtS02L4hCO7JKq+KTZm4Qk
IE0xaO0qDxnpmosK1jQmiURFHprOl2ozJ9HqeUjfSi93baxcVzrbbBbd+OM7JU4d
+cokhvTQdPPRhaUz5i6wJm2mFkjwr308SgzLsohF7Q0tP+wY7rsSeOscxo8sRuXc
DRpx1aJ6gLZmB2bPjqR0p9kpJy448x4KOBBXkKVFNzvRuG4oZ8SPO1DnP9CroHoO
0l+4NWCrHj7EWaj7mgLyNbJjkKULjwpjTsg3nWJj8QrISQa7ejZxVU96Kyk5WGEK
gvZz3/Eocrn+D2vFd0GOEN1qSxEaBLkynsTLaj4+7cm3V/QUZyrIuUjtYyhL5U/+
HeiZSaM5Mk99ABEBAAGJAbwEGAEIACYWIQS6YyiUjVAXXxlqq1ER8yRgPRLdVgUC
ZR/mPgIbDAUJA8JnAAAKCRAR8yRgPRLdVmnxC/9IntQx0YGcLlIXNEIsTE6Q99Gz
TWuTGq5dZCKxuRoT1V5Tmj9zJ7hS3qS+jK+gQKucecMWHogyHJmJjr9OY5A2E3yg
fL4qr1ZrN4i5ozTKd6r19CkU8YupjexKQ4pwSwaj6ovtjr42XmMXTyZhRx02XNvB
cj6Yavr/+586+MKINSfTEFoat74cyUM/SnORkQB+Z+XEPVnqN+gk5nbq1v72mdWV
ooEKvlXu4samcaJaGSYHGH2WXWwsJ0mnA00AhshwC9i+6RCcJTieHIngtTfQRQ+1
joR8eMvLQTj09Nt5PodcjfQ2jxBKtnQTcyssV1V/Jf/tsAa1pP1unTDHfOOphAXf
MZyhszMs7816JcAwtulz+LAq3QO2Ogp4oVE0dKk7vyIJ0hCtRtDDl6t94DjDSzUl
U91KMpm3KZiXSTuBEVuZuU/GCKmQ5OyVKWMTzLlBHvp96oj8+WsJzTkuJwBHWFmZ
uiK1kd08gp9i56uy5tkQtYJGpcsRNJNSnyAbEcM=
=4tfB
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEaBTWbhYJKwYBBAHaRw8BAQdAkvaY0BFbzEITBsCR3A8JnjrWZ/4orlFY7Ixe
aUSE/de0Hkt5cmEgS2VyeiA8a3lyYS5rZXJ6QG5ldGdvLmRlPoiTBBMWCgA7FiEE
u6DCZkei2Hq6GG1vPShOpyX5VS4FAmgU1m4CGwMFCwkIBwICIgIGFQoJCAsCBBYC
AwECHgcCF4AACgkQPShOpyX5VS5KCAEA5Fc+i9r1+xVRKqlf+XqX6PT1uhWKyrR4
+p6D0Q8/aCcA+wSuUcrwSNTcxfKF65wKyuOiNw5lWTTYq8vcwjIDYgUIuDgEaBTW
bhIKKwYBBAGXVQEFAQEHQBddu45Nfx+u3scccplH1OBLxSeOn6nKiSyVrrd8ySII
AwEIB4h4BBgWCgAgFiEEu6DCZkei2Hq6GG1vPShOpyX5VS4FAmgU1m4CGwwACgkQ
PShOpyX5VS4XpQD+JFrljM9ywUV17RjxZQEWpvviHGnWXYiayy/LbULb0M0A/iba
nN8E8ow17zqpng5Jqm7a/IYy8yQsNB0FYf6ddMMC
=FqJe
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ/fhOxYJKwYBBAHaRw8BAQdAu8VIhoCmqQSnlln72LVE2sW5cE5GS84pxwyh
HMbdeUm0Pm5zby1hZHAtbWdtdCAobnNvLWFkcC1tZ210IGdwZyBrZXkpIDxOU08t
VGVhbS1EZXZPcHNAbmV0Z28uZGU+iJMEExYKADsWIQSStkvV+zaOVwy5b4nKfQzD
RUpClAUCZ/fhOwIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgAAKCRDKfQzD
RUpClLG8AQCv3LTFvw+SzZWa0sLnvahtSR8wIpNw52+qelWDwaMYmwD+N7KhqarI
V6+TWJu9uxpc+RWk/vjlTGDchPeDoCs+xQ24OARn9+E7EgorBgEEAZdVAQUBAQdA
g8dAmTCmmnYBBqPlZDS+FMUpWMhAvCVUfmYai+ZHDQoDAQgHiHgEGBYKACAWIQSS
tkvV+zaOVwy5b4nKfQzDRUpClAUCZ/fhOwIbDAAKCRDKfQzDRUpClDChAQDI0wF7
PGDmqbGOXVKv0uPbTTLhu7oXiBq//blhkhCrjwD8Du/aEdCYoz9m6tobA01sKU+4
Gt1e4njTYlntGDL2kwo=
=hFQO
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,14 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEaJMgXRYJKwYBBAHaRw8BAQdAE6GbHO8yvEW3377zNntvGCj5lJJ1l0h5Bk/6
+cKgWJ20RG5zby1hZHAtc3RhZ2luZyAobnNvLWFkcC1zdGFnaW5nIGdwZyBrZXkp
IDxOU08tVGVhbS1EZXZPcHNAbmV0Z28uZGU+iJMEExYKADsWIQTJA8BGoGPfv49B
xldrJs9JaBKwCgUCaJMgXQIbAwULCQgHAgIiAgYVCgkICwIEFgIDAQIeBwIXgAAK
CRBrJs9JaBKwCvYpAQDWvMMhe+v3nIttUfEpln+8YQ8KSezLiCpJLQB4o5zt5QD9
Eo/ZIFriX11Y5yxnEjoFkH1LXEj66oGpMTjTojLpaA24OARokyBdEgorBgEEAZdV
AQUBAQdAuvufjrlZjxi5bpQ4MrR/Mk6qxPqU8MFQUc2Df+/alUwDAQgHiHgEGBYK
ACAWIQTJA8BGoGPfv49BxldrJs9JaBKwCgUCaJMgXQIbDAAKCRBrJs9JaBKwCloU
AP4vOcXLiHQ2nkbSm6CeP//0GX0WpsxMniOlqVxkZM5J+gEAu+IulrGA6fNrKNiv
cHh/X5eSsexomJXmxZ8dUOOhFw4=
=sfF9
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEaPtbMxYJKwYBBAHaRw8BAQdArKya+q6E/VlCAURWAj3Ggnia56yVrWSE7Jdp
cefGole0HW5zby1hZHAtdGF4IDxkZXZvcHNAbmV0Z28uZGU+iJMEExYKADsWIQSR
K9ShLWb5kxw/39GTy+xZ+yN5eQUCaPtbMwIbAwULCQgHAgIiAgYVCgkICwIEFgID
AQIeBwIXgAAKCRCTy+xZ+yN5eS4hAPsG/JbybnexMPfb7gsIiqSheeTvrGQnU1bO
2Ouz6e0FcwEAgQKoO2dbkM3/webS1F7zX0p0o1XZMW1ecHesTvQF6AW4OARo+1sz
EgorBgEEAZdVAQUBAQdA70MTcqVm07fe5cZGkR3evSc0yVRM/7WlVmS3N1JRER0D
AQgHiHgEGBYKACAWIQSRK9ShLWb5kxw/39GTy+xZ+yN5eQUCaPtbMwIbDAAKCRCT
y+xZ+yN5eRveAP49bhetFkuylYLcgEPKIWZom/0clG96YVUIvsCi42SeBQEA4CrN
JEoxwAR/oN1gcCbN2g2fqmirO1PbEQ4yPTLYVwk=
=yjPi
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZ63x7xYJKwYBBAHaRw8BAQdAxVEnJjkN/0RE6FlxNJVqUyzJUm4uXaCTjJ0d
6eFSI9+0I3NzcC1wcm9kIDxOU08tVGVhbS1EZXZPcHNAbmV0Z28uZGU+iJAEExYI
ADgWIQSsmw21kPSuIBfCrYNhE662bFEMPwUCZ63x7wIbAwULCQgHAgYVCgkICwIE
FgIDAQIeAQIXgAAKCRBhE662bFEMP4IXAQCl/C/HZ0WWmSv31GNlcBsIYdvys8Ny
c7qciu6ZAfuJ5wD/X6gsPohLVKZYT01pkiMRjehgBCeAIdYV7++1MnEloQa4OARn
rfHvEgorBgEEAZdVAQUBAQdAD9ikD606qN9oSWmebuqW2VXldozDndn34K6QnXfX
xHMDAQgHiHgEGBYIACAWIQSsmw21kPSuIBfCrYNhE662bFEMPwUCZ63x7wIbDAAK
CRBhE662bFEMP1zaAP94FZkb3Fm0P4fYSuuBLDUZK2dw1qt4lK2MNnFYUTAeBAD7
BTW3mExgOqq6IXXf0IDvGO1sa6We0Frkm1JZKNR2QwQ=
=4I3G
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,41 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
4hXDgcudtCquYStf
=oxRT
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,42 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
omEOA9Ja52BBiAbwxNXX5zJr5wq9xAc=
=vKTw
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,41 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQGNBGhvkGABDADZ1gDFCQmh2EZ7PC9l4wyQcZuzgaeWJS0Fn18pkieSYJJOGxmL
4p9oz9lKnIKog8mvCR3bNxAUtj4G59EJcL0fiPvWLKnWGvrN6lkIRThj0StV/nYd
hjHC2AM2tfdNe2G/EDLfqglrO/wi+i8j1LobxMeYn5v0pC5Mx0JT1wcdObAz4xMm
YlxSrYrNzcwt+95mhnwTxn5eqrh+99x/uvbZiSfzzR9/wRc/XAuSGUFCZlLqiNuU
1w6Je9nbN0M6yI2CWn3vUasrdMpWhn1Y+V3jTQDXTs8z4fXVCH+VhH/QyidczHKw
XKLkwdkx2MIOzGcDj/0JwIBUtgnuTNqTVmz60t02yU7Roj5yJIJyhhlFmdxXhfgk
q5KW6Es7bkuUzHhax2a9mHLn13s+Lyv3t/iZQp0vVYZIt5tVyokdCgrWLrZMdaZj
V7gvBmDhwhfTO/JLvpHOomsbhwN2bNXaKOsLP8yrJvUYTjiQyojXC9nEMO0+uJKj
MoX4UGV63QFax4MAEQEAAbQiVWxmIEZpc2NoZXIgPHVsZi5maXNjaGVyQG5ldGdv
LmRlPokB0QQTAQgAOxYhBNZnNI8xDFdlX85dTqaJ/yMv1oHwBQJob5BgAhsDBQsJ
CAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAAoJEKaJ/yMv1oHwAaoMAJYXg2mXPkJk
HhnGNp2dMV0HPZdGauTO+CW7biKXvZDXqzioE8bEE3c6C9uUZVi6zePEgCQNPSl1
jICz5Kq5p/TaBhhXNdDbYCl/ACGZ0O7r9iWmzen1fAYpmteg9Awh42QU1wKAsYzj
JXfdctpjH5IBAXGPYRRKP80G+7PlCDW1TZGEOLdeS3wWpMQnQdUN90fmxrU0uzTJ
axIsAfxwirtwdmC6yqtm+/Y+YGm37/mTMJYHp5FTRFRsV70eFgV5D5DnAPKXk0OU
+L0FliRk5iJn8mjFmGoL+nxLKU3y/64e9hgTJfcCzt6jAG9Tj9cSc2Ocg87uB4ID
hL6I+eS+HjQwTNejVIYUFH6KW0kgBcp9cRU0FeO1i58XhKyoODSUH/4wCIhiMQ9p
cvw67txropm8GAtCdkt0qouO+VdVkXRCZ+s0JaCRSIjggzCsWEmdXlRoLZZmtryc
7o6dX/8iafGv80VI8zmnGRu49i5Tj4MGFE55Dx0OJFA5LkC5h5As2LkBjQRob5Bg
AQwAxOzF7zqPLflbSYPLdjfow6tyXJr3WqZKrobkFAXKrjZfNdZuFcib8hEmlvn3
F1b7jUV++7YUUluOvDPkqPEaPQjoGP6c9zLz7TSPaLKXPunVQkzkuesz1quiuRtR
6YEWsQR0KAYCbNeQd/B+/MnFeCHiMZEiMtpHtbAgvLmdz2/hV7VuqTMY67tW12d/
amDOi5AWEKRDM62/hljWtVOh9m7+u/eAXyf9WJSajwMfyiK8GI9PTFTIpDUrwPMa
jJApQfmsxFlIAvmeeQZlm8L9HgOA1fRS944Bz0vjUnzYzGrNQn+w0iZlUCaqcuVF
Dg/zdqrrAOOIwIHAadG17eAMaxnyd6FsPEmk+pvyn9O/Rn5MzDmUacc023NgW1Du
tkgFcCv8A4QyGv88RP5rN7Ow7lCQio8vpk7iDE+vfy9MVc8CNsv+wUUKkfzJklgW
e5ds6FSTczQWeH8HXVUALc3WclyigPQvlzgyrmfGT1M05yPmo8q1tb7uSGJLe2Az
ddjjABEBAAGJAbYEGAEIACAWIQTWZzSPMQxXZV/OXU6mif8jL9aB8AUCaG+QYAIb
DAAKCRCmif8jL9aB8BJXC/oDn2jZvnAHyOABix7DrOQjKQeTqnUgLHH7siwrn6Vz
u5q3YSWgusJo4jFDSnukRlHo5WYTpf9uPyApisnNzRFcxTcupvbltP4/q//NQNfn
Rb2wLYqfWKP6VeWcpK26SLSXTAlrYO2iODbdjRl3IM0rr+e7YViaCF/M1YUgG7Ed
NCpfyxG2auFWxMMNOO1cXLPkcZpBfozUtdjGHUwvSlWq8NHLDjfUL7xo5Cb3ZD7O
qR+ESDvWiuOsz+Hy68UJCkn5HoQdAKaJnCRSuNFtwzxToetgY+ZjPTdWDMRe765H
fjJJcN+UMft3sddoLffbY9nObagGGEAB9QD1yKRYDCZTvoMAU29uoFLB/OpMKBwB
ZRfZr5R1ntoeLAKEMiLgYckmCFmms0b4GwDWRlYLm9IraxFmhjoQXnaA3vew4QDc
0fopaBalwn5dLywzaNVu6CIuAf9msMlxRUrtxGsplKF3E7XMeRsAsKGhhCYrN/Fp
JhujuU9eIqCXYO4i3GW2OMo=
=cYe4
-----END PGP PUBLIC KEY BLOCK-----

@ -0,0 +1,69 @@
# PURPOSE: BLUEPRINT for .sops.yaml config
# CAVEAT: DO NOT USE THIS FILE AS-IS in another project; copy it and remove the unauthorised users
# Fingerprint | User Type | User ID
# 533A89DD49FBCDA2BF014A936C962DD77704154A | autom | build-infra <NSO-Team-DevOps@netgo.de>
# EFBBBB131CF1D863005C18868C8C09CA950B1DFF | autom | smardigo automation DEMOMPMX (smardigo automation DEMOMPMX) <NSO-Team-DevOps@netgo.de>
# A7A1D860AA45B6B5B29BC192C55BD9B4CD8DE439 | autom | smardigo automation DEV (smardigo automation DEV) <NSO-Team-DevOps@netgo.de>
# C674EFA56D3EDFDA404B1684090D46D8F1D0C0F8 | autom | devnso adp (devnso-adp gpg key) <NSO-Team-DevOps@netgo.de>
# 0E8955A79FF4687A3ACF78E50B5E444C75867E58 | autom | smardigo automation DEVNSO (smardigo automation DEVNSO) <NSO-Team-DevOps@netgo.de>
# C674EFA56D3EDFDA404B1684090D46D8F1D0C0F8 | autom | devnso adp (devnso-adp gpg key) <NSO-Team-DevOps@netgo.de>
# C903C046A063DFBF8F41C6576B26CF496812B00A | autom | nso-adp-staging (nso-adp-staging gpg key) <NSO-Team-DevOps@netgo.de>
# E5B4FE1E0209DFFE320D2A2E47087747D89B72EC | autom | smardigo automation PRODNSO (smardigo automation PRODNSO) <NSO-Team-DevOps@netgo.de>
# B4BAA59056DC362809388F3F2119881095EA7DED | autom | sot production (sot production gpg key) <NSO-Team-DevOps@netgo.de>
# DF977A1F65999F4CDD721A27516F64D5932B8AD9 | autom | sot integration (sot integration) <NSO-Team-DevOps@netgo.de>
# AC9B0DB590F4AE2017C2AD836113AEB66C510C3F | autom | ssp-prod <NSO-Team-DevOps@netgo.de>
# 43DE8A01ABD706717C36018C48C47C125C022F29 | human | andreas.rother <andreas.rother@netgo.de>
# 1EBAE111F6EAE0CF136358E8625C5A3B8DA21485 | human | Annika Biermann <annika.biermann@netgo.de>
# 9F5341688D2F9024A15541C9E02949D0F7769E2C | human | Bas Cancrinus <bas.cancrinus@netgo.de>
# F7F328F0E4958E4C785977E23B8AA0BAABADAFE4 | human | Christos Adalis (GPG Keys) <christos.adalis@netgo.de>
# 659FDED43DE155FB772A339B343CF1218A664D31 | human | Claus Paetow <claus.paetow@netgo.de>
# 93593B8B0B7B88EA2DCC99F9388B6A662C356822 | human | Daniel Risse <daniel.risse@netgo.de>
# 0143019F62469ED5A6A016C219CA764D37590F9F | human | Daryl Sauer-Neumann (SOPS) <daryl.sauer-neumann@netgo.de>
# 9E561083EACDE14694C73A323A2F6C1D153D753F | human | Frederik Marticke <frederik.marticke@netgo.de>
# 9F08DA9D42379AFE6610E9E615CCEC6801DBA02E | human | Hoan To (Hoan To GPG Key) <hoan.to@netgo.de>
# B92DDC9B908BF3917758D228446C51E049AE38CA | human | Jan Jantzen (sops) <jan.jantzen@netgo.de>
# B643A5D780A01F24E95AA100DE6F8E2C149C3748 | human | johannes.wicovsky <johannes.wicovsky@netgo.de>
# C19A7D807525CE24443CA9A49372E896B41FE700 | human | Kevin Bauske <kevin.bauske@netgo.de>
# 0DB51A7E90AC6418B7DB83724D38970874850C33 | human | Kleanthis Damianidis <kleanthis.damianidis@netgo.de>
# BBA0C26647A2D87ABA186D6F3D284EA725F9552E | human | Kyra Kerz <kyra.kerz@netgo.de>
# 73C2C9954D1BC94DC6682525D2FA233B52AEC75C | human | Michael Haehnel (NSO DevOps) <michael.haehnel@netgo.de>
# 3511D1A5B7B2AC97BAE8AF3EE758168C000375CE | human | Thi Nguyen <thi.nguyen@netgo.de>
# 0C136F7514100470AD3EC8D37BF1FAEDB2ACCA9A | human | Thomas Steube <thomas.steube@netgo.de>
# BB333E772B60EC8A29E8DE641D6B8CC68E09BCA5 | human | Tobias Plöger <tobias.ploeger@netgo.de>
# 57F93F2A6585CF2DF9A3B31F13B9F45E122698D5 | human | Tobias Stroehl <tobias.stroehl@netgo.de>
# D667348F310C57655FCE5D4EA689FF232FD681F0 | human | Ulf Fischer <ulf.fischer@netgo.de>
# keys in https://git.dev-at.de/smardigo-hetzner/communication-keys
creation_rules:
# list of keys for encryption in stage
- pgp: >-
533A89DD49FBCDA2BF014A936C962DD77704154A,
EFBBBB131CF1D863005C18868C8C09CA950B1DFF,
A7A1D860AA45B6B5B29BC192C55BD9B4CD8DE439,
C674EFA56D3EDFDA404B1684090D46D8F1D0C0F8,
0E8955A79FF4687A3ACF78E50B5E444C75867E58,
C674EFA56D3EDFDA404B1684090D46D8F1D0C0F8,
C903C046A063DFBF8F41C6576B26CF496812B00A,
E5B4FE1E0209DFFE320D2A2E47087747D89B72EC,
B4BAA59056DC362809388F3F2119881095EA7DED,
DF977A1F65999F4CDD721A27516F64D5932B8AD9,
AC9B0DB590F4AE2017C2AD836113AEB66C510C3F,
43DE8A01ABD706717C36018C48C47C125C022F29,
1EBAE111F6EAE0CF136358E8625C5A3B8DA21485,
9F5341688D2F9024A15541C9E02949D0F7769E2C,
F7F328F0E4958E4C785977E23B8AA0BAABADAFE4,
659FDED43DE155FB772A339B343CF1218A664D31,
93593B8B0B7B88EA2DCC99F9388B6A662C356822,
0143019F62469ED5A6A016C219CA764D37590F9F,
9E561083EACDE14694C73A323A2F6C1D153D753F,
9F08DA9D42379AFE6610E9E615CCEC6801DBA02E,
B92DDC9B908BF3917758D228446C51E049AE38CA,
B643A5D780A01F24E95AA100DE6F8E2C149C3748,
C19A7D807525CE24443CA9A49372E896B41FE700,
0DB51A7E90AC6418B7DB83724D38970874850C33,
BBA0C26647A2D87ABA186D6F3D284EA725F9552E,
73C2C9954D1BC94DC6682525D2FA233B52AEC75C,
3511D1A5B7B2AC97BAE8AF3EE758168C000375CE,
0C136F7514100470AD3EC8D37BF1FAEDB2ACCA9A,
BB333E772B60EC8A29E8DE641D6B8CC68E09BCA5,
57F93F2A6585CF2DF9A3B31F13B9F45E122698D5,
D667348F310C57655FCE5D4EA689FF232FD681F0

@ -0,0 +1,498 @@
demo:
credentials:
secret: ENC[AES256_GCM,data:B5h1+zKRxQ==,iv:tFdKcG+3U9cwR/f8ubs1wm5p369R5dMEnH77aWt/K5M=,tag:WxWwgE05rWUaB7EOxnoGbQ==,type:str]
sops:
lastmodified: "2025-10-22T08:32:25Z"
mac: ENC[AES256_GCM,data:ByW+jdHSeU3hRj5xvyujFoi38QQBNVUgMHvm4j1kC6XTYbBVRTWccr3boKaRzi7b8sdKE3SA7lz77MVRpYeJXn3ZIf4NvHBxDJv7btGg3c0Lq+bWRsHS9tNFRH8bc96GTWUldKv+tdyGOC8KQ6DwJASFuM3km0t0JuRqY4w0Dj8=,iv:ICVeB4s3Zqsz2uL3Cs/mhNwheK9G3nu5kPE+iQQT5ic=,tag:JZMMvnQtNHfasHDrJOAsvw==,type:str]
pgp:
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMA49EwzBHBfyRAQv7BsBjoNJanbWUWzFN1fTL6V8zfY2rS+LHqGbZlAMWt89K
qFutxRqjjo96Y1ESFTsr9Lqb5gO3WB2E4JTXqBsAMHdP1tGMj/MJpEjTsnY7Fugt
y1sxcBHCQUWGNZI/z714yNSDokp9S78OVvThS5C5RKn6dkIMfZ6/+FWiAQaR9Bhl
u2u8sDSsAAXBEduNNavBCUvl9WudLu7+j9gdgI6MgdD3W/I12EHDL6aMJdaLmcn6
ZxYSjojqqWfd85fxO9cGzz+mhfglhhRquSrM+nelTgLYNloLLFnol5qAnvCnr8+L
vM7jC+gj+Z5VqtRNmCm1JuGMQqQo4AficMgH6UlQ87k76sFKZN9b9pRNSCP1KQEp
b2OGAmIwSijdhXCPmOYodalwx8N2mt29myRnSWw21KJZ85Nr5xaaF5YUeiFSNnnP
xW5YaVFiGwA9JltOnwTiE3JEHtfox1VNLSbLDEQCMeMLhE6jsciH0SWgzMJm2Xu+
nZ/IqdAGgDvaBV6fNcG10l4BZ16ZAWv/+9NGQWJ0dhasBxSUrFOY5MMLkCYq+BXO
5FaJPSYCO662WSkoReUCFz2ZrhHG0RrREBp1hDJhnpcorSZoV8jWxyS2tY8MGb3f
LCOG771hk3zlqnpgDhxO
=VALa
-----END PGP MESSAGE-----
fp: 533A89DD49FBCDA2BF014A936C962DD77704154A
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA/3nDyRfgQqhARAAopdmS/yGWhA3AFEbiVQJgxDRPGR1dC3xUob7o4DF+Nl2
8ma6E8klwWnmigUP9RyIFFWHqrMcapECJSi4eWzNdcd8XuWFeyaorWUqZrQc3TQq
pNjh1B4snCuFwTuNNExH/ieW6YGPcNo/ykoHJTsWwGYwfHRQ996YbYHRtpOuxWVz
vWLkdPu1cSPDmZk5dAyNh6XyBNpQIF30O5gCPLLsZTQDvjroCAKeChAKdsh9Jj/X
zms+0wmRYd+KAm5oCReTtP2dRPYEa6MsmR+F9t+i2KuYBE6cm1/FsKjD3VvIONG5
cDV391FwOn1woU/oK/JTKMCgBk7ifIroMeVbLUFmln0HkJ4M4CV2WIKiui+XevXl
ja9lMRyuh8vYETT8mFKWaUZwlvRtsp2ZDv1YahaSLpOniP/So1LnQsiGs9/um3k8
1siC94WZ0H1KeFgwy2tIjsvJfG59Z3EqmElZlxvH7q90oicrs/OWvO26htkzk7YU
N2gwC3Hjqr0KReD/WniSidQsv1QYeEVQPv6z1WCPybEMviPPPyFRaJ3XmC+YiKhJ
k0C5jo5VAbm0kJYdNrml1LUtoN8PhEqyzOfRCOmr4cs4ndlIJLTz9j1Xvz73iXiD
0MNg8oFJSvYCmeqnGk4W8JdpCbNO0gqfFO2AMdecsejKcvN8I0ekgFrOSlgAKrvS
XgE8Jh/Xbg4PhggxdwDjU710wzfpoLOHJuSQemZainrnYaqeAKrHeK8NrwMx8fa2
q/NFG5ySZBDL8e+T1qEsLO3XkWwBeWlvo8A8sLRJEo07RjrVVT/TZwQa6OmeVEs=
=4p4A
-----END PGP MESSAGE-----
fp: A7A1D860AA45B6B5B29BC192C55BD9B4CD8DE439
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DuAaR73LFvScSAQdAxxYDXShwKh/6W4ibLuZt7csqihqYHQKV2bkuo8RH31gw
mP0wr6zffEUUUiYyrVx5f65WcKaI1a31nMCfJO+ttTMJ2kl2gVoEHx+7jSP+Tt1G
1GgBCQIQmmC11YaJGJxUFgwnrOTJeVu5mzXOVWjCZRhkyrsyH0hXRY05egXZzMBT
DisTqzIIan1hT+u/35JMeujHe/LrEPyQlhtyaThjz0tfMPXSbEuiUiuuiV7YpiYZ
sX30U6j9Dsm7dg==
=08Mf
-----END PGP MESSAGE-----
fp: C674EFA56D3EDFDA404B1684090D46D8F1D0C0F8
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA3LBDEB9lMmaAQ/6A6jPXX1l7J7dmAexDkvOuC2+8azrnM9u8smXbje/xESd
pwYupQa4RYrSu3BUaNNfglysJVNLbw6ntJ7JZYrt6tbQv5/JVcMGzlRPTkfAugVl
521Y5ohKmlYXN4jWb49d8/50JDxsmnZblqDv6qHKkvCmesveHRqif4gZGuBkXVdR
G/TaH8VKGfR6E+WJ8Utbfp1rBmvh0CZB9Mpnf+dKEF+cIPhUhCpQZttULLLwKVca
/C5obxQ3NBITqw1SzTHfmxn2oL/phGmwjXiDy0v6JQBMzDZ0C78YS3q4T4nkA30v
gD4GswOHkR+EfppkSn0k7f4HxLaAMTFzut9B2BdrtZl4UWBNz6CTCf7YuFDBs7eP
Da9ZLzLGiml8rhzY4UJbmJ77zZBvMET3IYkMSayff2IxoHJNRSI4RQ1SSLC+yy1y
C2lcaC5OO8s0gT62gmfi5X/Ebngx06A9X08f0GowP2+KaWZJ+3Q3Q14DjAOtdH0T
yrX2xoLNyXjhspYB9jFCuD9Ct9S23E4Mu00eoK3ABXmF3OqwwIV45HyWB3qbhdYJ
xTDJmP/s3krRTcgiQD5yuHoNgkvAzptmvO9sgGuFHlI5y2vuQ853XjJmOJBfUy9r
WONMbORPqvns4AqPce+UbU0Jib3olUU+BI19q8w2H46Xh1XmYHbMsNAXeKkyX9/U
aAEJAhCT1uQf5MbaPZRAQX4hTgW8mG/soN5wpOV9r1pqfgaZINtivwO9apOhr+CW
MgQBk/zwHinI0mU7x7CJTlTDX6culH0kiFWeZCVxxjh3l2M1NIORyyHMf2tFQu/G
L3WICmtOWf54
=NaqF
-----END PGP MESSAGE-----
fp: 0E8955A79FF4687A3ACF78E50B5E444C75867E58
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DuAaR73LFvScSAQdANY9s/4ZpJhJaCWVDPtlTo6Ob69MpP3ACFTFccOiIYk0w
1bSb7XRxjZ0YqWkBsmDattH9J/wg/isF3GJR8HIFRgHok+r0PscQR9xr8YlDxoZP
1GgBCQIQfdgQpU1ERezqyr0F7cqGEh6MwmhYz1hrnUEFWdB4c8iPhiR8mJZa9+j8
Ii8yEtmpZgAxvs4hR0JPdw4gDInIT6xre5ErJ3GSefvlug8WQ9cgSFMBf4DgelXQ
u+8VrFR/sV7fcg==
=HIJK
-----END PGP MESSAGE-----
fp: C674EFA56D3EDFDA404B1684090D46D8F1D0C0F8
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4Dq7ZJnmCAxTASAQdAcoI0EFmwEAnlOgW3vI3+CzjI6tuCuLZ/L5LOIwMK+38w
KRjRd5n9WqNTrxwvyYLMP1kM0VzLXppgM+t/Fr4ObkySYxWStdiN9++EkpaKEEhl
1GgBCQIQMAboN3IjFtuQnT98NOVkTaRbWeOfi7IFnLL50yg/BsGNMnMIrBOF3WmO
ny3u2Nzl0//G6NS5sGe3+xoCxAz4gvQaaTPMsbOPpmdP/vQyZNzMhidNOx1fHgt3
u2vrYfnv7cQO4w==
=LzLZ
-----END PGP MESSAGE-----
fp: C903C046A063DFBF8F41C6576B26CF496812B00A
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA911WKxzIy2nARAAqDjWKUlpAHXCE7XtvfDJJZ3MqhC5Dq0SrnSQ4Sv6Nk+k
pVz74k+vzPwQumi3MuOOQi8BH0IpiAd2ihWhcr+nu4GOUZ/Xo5OJv72t8qT3lFf0
Unp6Eg/UESilwQkHPhJQOOjHr0CIBxU4SkDBcLlVkOjfZMH/qXkSlOa9Wqi8Z7nw
P4XnUVCOqfRSoBe8sammriO2d9fjjbVy9m0VksR1R3TClpPv1uN3V8INvPhlC3Ml
nqo3zLnkg3lAu28nVXgNb2s4PvmTQAHwhTXF1/nPEPBP1ilrA3amGcR4VcC1Svr8
dp4YfgWnzqzNuOP/4U4R56RbmvxEOan85CwFbHWuFpfzf0fWPs2l4LYgxB33MggW
P+WF9rnSf+y8ph7HVwBnSG0WCmqyuQBnyImdUO/qi/0Zd4MpRMvDhtYNoDfHmph0
rWd77WQUsI9+r5dhLdtkBX6LluhO3FK/L4NnEVsc9M9Ve0nYtGpqunZb5T0VuPyW
7NA+oEXqo3ZZoPvphkuCUNQUljmrFUPhlkTDB3A716LZ3nr5tRHm+iRrTfflgo89
i3m3uXKwVcTw7wFHCwrPI8imc77PLW+H/FjBs+3YX9rOTffFerdPwKobaxB/Fc+P
Ep5nabvn9nzVfzgXh9dov8dajtPj1gkIE0heTkunXARcje8qNwsP6c6mYYAsDYXS
XgHh5C81WdFJVQXTvuuONx10XZk4O22SFI9YOTQ3dWMpZSk0qoN1xgiCO+mvYiPR
fvIMbjihzdTsfKmIJtaR2BS7KkM6hshraGHtGMid9ly3n11dok4+dNMgsrqvqQA=
=x41/
-----END PGP MESSAGE-----
fp: E5B4FE1E0209DFFE320D2A2E47087747D89B72EC
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMA5pTFdxsndstAQwAuvSwuGLSiTBmFA8rQbFiGYExh6x62ijw7pOaqOK3l4wd
CnEKDBzGK2VjoKoLe0Kp1epMZcgLQhzF1qe7eKLnT11dI5jcYUO6mDzhq/38yWdg
g7NtoZRP4gIC+Xfj3+bhZBfhPt6tTGGw599P7gkXuOnDzeTip9FVysGRjeYm3Q8y
fZNKuT/dhjEgMNZqh8RUFxcQExwiZ4UYWPQV3GsCXuJlvx7NRNhSbacFw+3+OQrX
cimpFzIZQfz3nmEc21kBigCmF9IxSJhFANkPAoiTr/Kszki69z9+oZ/e8aod3flF
ow6tVtjVDH26IiD/5FckBDJcibhw18ghrHh+XuMgzqBX+3pc3UHWRSag5FiA7QuC
cPhUTFdLVC/tb2R4ci0ropUZ3/7Rdd2Lrn7Ccvw0aTaAb3KWxtqN97UaAbkPQYy/
cNwwrVKGGfUGsZoTl7DGeZiP36tu38qLsEA3Wky7+zhwrqlDZPDePZyf4QHr1ZjM
sNZx6RDKfV8uhG8V/LRC0l4B8kXUYTmh8MVebNfEnINgzXyOkIjl+qe3SGAWl+sz
cD1kpLyhuquxwzpNxi28kP+LAv6yM14pVY3tJZn3ZbZhfkV8i4/VF0Fgsp3RPige
SmJHbw9iGMZLu/pbzapv
=frF2
-----END PGP MESSAGE-----
fp: B4BAA59056DC362809388F3F2119881095EA7DED
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DwvSwby3S138SAQdA0xD9js3d9JcZTJLGHuUZXtA3ot5LOjkqRd7u8/dfAE4w
Zq+vAb89/DHUuKlLC3vMfpSStvtrSUnMBX1jcGjpG25j8yQQMHj2o8CeUBHXv2l2
1GgBCQIQoKb+YHrlK9J77UMKq/05rO6GX8Ro/oG3WbtRw+Ap1roARUkQerjlxeS5
wD5jUhO6IaxTNnRf+zddSoLyD6BWWusDyvAmf2h4+YFKAyc8q+x6Chdik1bQnLyL
YQYEe62pU7JmMg==
=cyBZ
-----END PGP MESSAGE-----
fp: DF977A1F65999F4CDD721A27516F64D5932B8AD9
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4D3RW6IFeToCoSAQdAYzjUM4IJtNT8mTr2eavs7asD3hIesRGtaaM4NixrL3kw
DaMd4Lw+G2b0T3kVwmrur9e61zj+qgHwLmReij97JfW+5ceB3uzl9ILii4BZDWko
0l4BOqi2wZcXuG7nwdLySPn1MnZ7KuEm3KXX03q8kxtS5qhPkOOiG6ZJNuK6RP5c
dcxsESmU/0O4Fxn9MbLYKDJWuMv1tpxwsR2zw1TcV04q8owIFGJDrtCs/+VA9Mjr
=LmAl
-----END PGP MESSAGE-----
fp: AC9B0DB590F4AE2017C2AD836113AEB66C510C3F
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMA3n4x8uRQRGSAQwAwgeiNm/1ezo/ZZZHaBJytZjVBoy0NKwZ4n6pAVEzoU9a
Hf4lomaBc7bL9aYEWKoUTmsa4UCGvSDaJVzhKLetKodG7wnxGW5yXYfS6WISGq4v
Yc5bzDQrUbvIWibnTh1MyAhsac7gwq1Gnbh1opqNE0kgiFovcdwz2ab8/8foiwFF
d8ER8Zcyb0IeGt+2kRh/QjCanlyU92jwJOBzQVc+/nKIksWKUKYq6IcHOQgeoGKi
GgVHXXo19yukmykL6QeGAJi3lukH7+mqi6sgXp8Zh3E3wu03L8My1mXF3SJ1IpLs
ctp5JPHpQn3nVBsVvbkf9P+AvQsQOXKvaKgsZJ3O33wmz6AiiKY/FrUwlG4r8aEW
hhwAo/sLUYvcGzFJU92tDnskwsNAOPA8Pj0RB4E38JCsK9bwRiUqAKHRdfEeSefw
3mmML1Z6H7CCc76O6lCXjR8W79jMRwq/xE8BWMkB1XffFaRHOhllPBro8uR3Zol3
DYq9WSw8GoLGomwM+E7V1GgBCQIQz26PHsb5dysgZPrFwJqvcaFjMCcZKOOriFfj
14bMNJjAc8yHTkekSmblPuIJ3jwsSoFbTJQYTafIxZ4wrCk75rEGWEjIAaHjN9uw
VBSmK4pj1DliPK4D+OPBkMy15XZSA3yaXA==
=coc1
-----END PGP MESSAGE-----
fp: 43DE8A01ABD706717C36018C48C47C125C022F29
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMAx5drVN5V7yDAQv+P/6LKdpEL2yWkParQsGIIaqju5T5/iaAvecngHA4FBIo
zUduorElOKC+T92kYss0FDMl3zePMyYXuPReOOntoKOt/T+dlTTKOKhKzEZ7dZyC
Qd8NXPovBqx0Qiznf5hP9oVElrWmD9L8GuzT2c6M2VAclWPNaIjpDoY+ux9mAHqz
CUycoUYNEGFaysWanzXqw9pQiXxOmJ3n6rQ6P1CisCnQiMlgVRamYzaViO/ti4HN
I17Yfr92aarDwvQw3Gqpo5XlBDlZuaiToriOwvsRbynJ9iTaYzAYkDNgebScGWhL
Tl5f0AQaBVQbsuIoqt91NNDgI8ja4vYi3eXd+o9M8t+4FhT9dzoRDxBNH9dZHfFi
8vLNb5dUgz2wn5miLrwFTmbn6C9GofEj18IU/c7GEFGld0ajPjqxAo6AkzRP/ksk
5bCUneJUBg+1/wv5Lq6SkLalDMO+te4I8RDE2+MtJeIIzcLiQxzNl3YO40cU2K3J
c7JO98gACdx5AiwTg4Ze0l4BEvfJ3vTUoM2iZIYEZZ34qGBr4DJSPIRDtftKJ8iM
y4DstvqHtiuBBPogbQd7of9HfLEB/IeMxLX8WfWxrPMhMv+ksF8yblYMKhTcb2Rz
72gsQiAvIOElqeV6X5W9
=/qwi
-----END PGP MESSAGE-----
fp: 1EBAE111F6EAE0CF136358E8625C5A3B8DA21485
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DRPQAGSQLsJYSAQdAK06N4nEaBoHoqzisngt6Pjfw/j3+az9kkcLz7yuzEXQw
4c/WT258IUaMZw3APc/Cb3/5ckkeWY2iEWGq1CotE7sW1G1MxaisQjSNWVMCvhdB
1GgBCQIQeKyr52qjVGTwr3ul5eY84So8d2GBnF52544vkHmsKdmyE9pZKrbC0l3o
uTPT1oneWpXUguohi4YzLxeENdX8wumnlatck19ivmtDCFtKf2CYsQIFLTj2g9eP
E3nvfD74nt30ag==
=gmxN
-----END PGP MESSAGE-----
fp: 9F5341688D2F9024A15541C9E02949D0F7769E2C
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DqL0Ka4V5gcISAQdAuEiGMF0+O5sHyuNiUxFTBjClXPI5qZMYykvyne3pXkQw
MnFMOlgqovBanqI1cM3DVZElrMxsLzxseGTbL8UKd0mClzXnqNFkc9NLkDkNO6tF
1GgBCQIQDfe4S+Awl42he4BxG2Roh0KyRv9NqjgyVk9ytevFB4jLbRpcKaimCW55
n9jFLqfOQlbqje4d/b24/lJOkMmhibfpJ7YDQIt/vxoi7GvufiAciJgIW89owYcm
uEiaLNhXb5Kneg==
=fJqe
-----END PGP MESSAGE-----
fp: F7F328F0E4958E4C785977E23B8AA0BAABADAFE4
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DbFrAcOA5jGISAQdADz7JJxhJrzKxkQ35pdxuSycyV+2IS8/QZBcRBIXV2y0w
OYnbgVgIbCwSWz5XXxfiM5D8e03HkPrh6Cg4mXcMBqFoF5ktMcXnMi0dxyrYIKom
0l4BEjoQpriTjcyBcaoi0LRGRd9l9tuZjMoygeox+d72uEt2NU7ztlPAhCUWEjBT
xHE8Kwz57AF79f8d3/c7dUgyjdlL51OhVNi4pjggK8hskNCZR0Fco00wIKK7tFHT
=WKjm
-----END PGP MESSAGE-----
fp: 659FDED43DE155FB772A339B343CF1218A664D31
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA0JLr4yo8A4WAQ//TVI5urdUpi4RQgn2sst/1hF9NIFu9StHg0iGLP0SB+k9
XAKv6q1MUC+ykwU7vsP/scADO+GG/4swuRDR8d6y0wmStXEbAXTY8CzeseIAQA3h
spPP7F1gIanG9pgMBFAuPdudIbzz1H63nBkTAggKRvFz97LbX1ZJ/7cAGcr+ljor
pGfNdkZs2RNp+9D/WOgV022GEOGeqv1pv7RX1Z6rjTCd0FtKFjRTQRnZpFV2S5o7
Hcfp+ntLk0Cz9StCK+9CGzuAdfXLSXzAmafvC/7tqxHLSuExok7OyHxHd8CNAWzO
Wn/3NeT/RF97xL6zUE0ITCRoCjyT/AKxXA03zEForWypkHXSvj7wD6DKX1Vt8NmE
se1t2T7aJuvdxKwwwEgreKcpILPAoefT/JKTcjh0SfTbufhEcDnKjRmjB4wyiYse
wqMgXYA7s1OIkwriGPl0KKoZyc/dN6+2HXbDwDnO77MBRNA/KHd/03o6jM2+5ZxA
XG9nEeauWfB3e2BW6RrVZXHGpOtXIc9/xcISg8cNmqnxuoHeXqNON3QFNkZSpnsR
3bhD1ue9DmCpFKjpcONFU987ev7A60VG0av20R3pLHj472TI5DX5f1NkXxe6Yvf/
u3EF7ddWIkFWX21rRJWEBod51d9Vg5uQfaJVYAfmCtjgfEWtDlNeaGLBqrLyAsXS
XgHnFHa8vUNK2Kj3VfeNi4CNlJaKKSdxVhKnXLq9tVaIxE3l7NsFfKYEeqjZCFoE
QI6fiNp9Z4WCXY4MOTP3s5c+eoGFwzA1iQFJ0W9f8Xf28G3pfQTeU5LzjXg7kcI=
=Uje9
-----END PGP MESSAGE-----
fp: 93593B8B0B7B88EA2DCC99F9388B6A662C356822
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4D9oMBxyVlaokSAQdA9tHAO9kyV6aj0j6XWH7/VK/ML9EuLdz95Tq0mbss5VIw
DaDHuifWmKJ8LpAcxHVx46+/dpyhOozT0miyCmIym2bkVACGz6+redvkwuQE83pz
1GgBCQIQ0pf58HpQQmV7m/Men//N+xIqm135d970FwzxDgsVPpOsxmNpKI8tTMyB
4ovko73ionZ4eVMMEx9ivbyUw70fE17Yp0OZB5WpEYnQa+cbzyqZbyANavcIVWbd
IjZm4O0v4ELm0Q==
=pKAV
-----END PGP MESSAGE-----
fp: 0143019F62469ED5A6A016C219CA764D37590F9F
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4D4oFtgf6gcosSAQdA/ziAtNNZxwqL1CmVr8JeT2OLocQuHYf9SxnMBm6xl1Mw
pYvXfBTchT88Utt6+WOXDyUOAbrJREtJv8o0UA/YiZCVnt3rUJJCqgOiMdOe8EGg
1GgBCQIQWzeWtees9enj7kwxZ2XN5Hu4a/dF2f4XgbqEg34SWhwltb3BGgezS6co
cFh181dESMCzd/+RhcxdHT3HEZdG0DTZcvpn+8Cddc19SRaV46ly8Mo5umQa+hHB
onTCmWIYSibMqA==
=w0Os
-----END PGP MESSAGE-----
fp: 8D600912FD42EF5352D38DD22FD71F457EF7BB8B
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA/fyan/DNa3uAQ/9Gtba2jw6Rzb55Ug/tRrOcqbA/9kx12p2yucnHm49DdUl
7f2/bFO5B7LCncGQmno6vXFc3D6B5BxPrXXFOjzdCrTZkl4B/9sVIl0DdvhrszEm
e3qVykJpqj6rl+b2fpKrVjifdYb3/jG/02rIdGcaep0nU7iO3l8cSLhHs9jNRb6g
5gapzO6CG4vgAwfIhSaojtPMIXtkmB0RzGh7OXntonKsAXWnySHCPVOU6DWiVHEb
Obg6QZJycacuSG8ML0GNpTA36p8XRWDmeR1/FO9gzyItzXIfCf5pOnUp4v64vuC4
QqsY127RsS11drnr9NFAMdbNAN9FCT+yLINtDGDSZmh65oHxB1qIItnTW7aZ5Lq0
oGL9h0+uEDcF3HVihic1qs1N0dDCD17VYeiikikMgnyczjvMVHdeHaXKGoeumVlL
QzuBwXyAJ7E/pg8N1Ku8kq0+CmaLmDbYs+7HNRtRw9zpznmX1Z3EsrVGcO8YRq/r
JTBRbC9mr4L4KEDn3ymVAUeQHZAJZjwOM8shsoE6YC8zBmC74xWb4tu9c20gg+28
WLU//3rR+pFfRGK+OBJu2emnEkgm/5sHFXw67bzqru9dTiyLGAOWBsgmMwPjIds7
hO/PMvLX+u7S9qJ1p8DQZ+PJ3zA0saHMg07JeqRxBf87H6fFS9KWjl7dtczk2GzS
XgG6ZoEL5r0su8MIo82lsdDMWeMvs1H40W6d7zkfWI+qVXOLZjNeeotzgVop7YnM
db8zhgtXrMgHODG8519YP8zNaXfQN0pjX0A8rnFhNVPifcjYiOKUB6s/fWe9ovE=
=GLU+
-----END PGP MESSAGE-----
fp: 9E561083EACDE14694C73A323A2F6C1D153D753F
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMA+cOSmNXMUmKAQv9FJ487BOvGvaLZIGYwLqElDt3GGMvhpbwo+UgS0Po6Gyq
/DsAtMlpES1ieHmfMQcQfb2IWXm3UpgwwLMSbFXsB6OBbZhDpPM3MI33ZmYdLY56
oZdkJk5vf/VwpmSUvWANkFRhDxce2U/szWU+9XdRg3IgVprpu83a+DbYto2lENcu
8Eyuou8bTKcquKcuezUqIfZiuv5G09GUOx59cmVusJ3DRn7ozRadJQLiwd/m3z6v
TrkO0lIfiQT1lQnwtgixhlN1zICQ+ujJzQDNqHrjjxLWjmvVgWjXOyLCx+ivWySg
a58NF38vDQKsQvAv2f1WwW5/xeMGqHPyHPEipEEbDzEB+iwZ5K1YHTj2ocBHiOtt
DheDdmeC9IGNTDc/XrLmlW4grrUNsEl7hmlT75A9R7w5Sal094VNEh9L7bNj2dqg
nIQjU6AgyYm3vd/zcA2ew0gl3FimP4qQO/M+mTe/SNA4C3UvdbNOBwHjp5NiejXv
uFFbZOfgNlHgRlb6bnGh0l4B/jLdc/21pnGrx0MJdYUl8mn0u9A2lssmhXMXgPGm
J1loxnQ9ZskDbnA1g6gXP+vPGyXSzX/R64OM3EKaA+T/LBZ+f58Bo7QYGGDiAnSS
Yy+uj+x84lQGz1kdWjfA
=fOjJ
-----END PGP MESSAGE-----
fp: 9F08DA9D42379AFE6610E9E615CCEC6801DBA02E
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DrMuSzhFbHkQSAQdAM4iNYf1Kyv22rIy8PxVWrTmtRleonfVYeUCSWuXjx3ww
hRny7s7V/KA7nd5o/XYCZR9kJpD5UI94+DyqVxy7u8TqldDmiivxWks/JejKF0nG
1GgBCQIQzP20RqCgBpJio/WKvvsLd8iFSDiK7BnUJt+aKTVSK0k6I3hTUzTsSmOv
4H26OK2RbI0eqmlCwAiO5EW6SUpIr/4uwTZrUoIJkr4FziAfrqzTrPjxM8eAIPF7
lQ4w7IDFLJ0+qQ==
=0RD3
-----END PGP MESSAGE-----
fp: B92DDC9B908BF3917758D228446C51E049AE38CA
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA8YZutSkx0fiAQ//V+rV0GdG9Wl7gtwhOQidk5hFcGi+gWc2V2CX5KRGiNM+
Ej7UwpsozNenBKJPGCgW7A1TviWVN9u97e4a++6fPMQSb+BZ+7jKNHWSU5EHUqm/
TmymPa4HgonKNgI1Uh1T/Mlz/shtugCxS1oThQLIrDyvyzp/B7HWgvtqDKo0zUIQ
7zM/RN/qNdtXWd26pmzk9aH+yOLmtoB2Cepgdcy6yG7wIKge2EmejfM6+mLlRiNQ
WqAqetZVtJYfiy5EqnRNPQIzbr3+2dTsIORpQcFvGB/ULUbcSDt0HKXmWQ+c1hZo
nXDOt9Pz4Wly7M9wXWwWwSDNwM29WEsdZQokBpaN5Lt58CszV6MQRWn852xuOV8H
JfVQxPix8FWrcOOur9n7OrnKf4ANzoqjgbVZ7kTo+hTzClWCMs2hfXnzVhJviNVh
k9kzLeps5BIQ23qSsPBaMWMrXyyxsZd1b+1MUwCliw13zQX5hi6m07SGCJyLKfDG
C221sNKCoaE2hBQ0ZqGp4j0c/0R0AuI66xOyj5J+MOqJlQvK24I1uO/8n6UMNpnT
ZUOvA9umkWDmSHH68SzPjeXsoZcy+mFrdTvTqaiKuxjjlGKMdNPv50gWNylv+r7j
/VkS0h2tTZE7YKKHwo7T4AaPGg/uwxD+u3+i5QYdpJtrY1UPk+uTOmCFtBuur/XS
XgGphqprcxNQ+a8Fm6pgpNQn7F8QGJEbjTR0LdUhTScn8wK567d0Yk+mHszdzZJb
cWDXSe1BNSekAqSpJQDYF+qldkR2F/Mqe+tXiH95C2PCtPkoRak+JZuKoEqBxqc=
=KDxH
-----END PGP MESSAGE-----
fp: B643A5D780A01F24E95AA100DE6F8E2C149C3748
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMA9vEXLVODHp3AQv/QOoPcsrKBc0fzmPrUbyp7dApHFbwnSF5JSQRQfGzaqP5
Cq8PBKEoORT24eoX11Tr8fba0i+PJBB0w12EtfBOmOwGhqUgOYXw81lfJh/hY3J2
1okk8Sm+tOJ2sBMLYFEKyoOmLmhbhSfe2uloPhObnFiaBramMD6ViudTNAvSVVmG
7xORVno5LNzJ9DHBemeKvfJsoc0nLTDPK78hBoJ6Z/926pZJWGGbufIk9eJ7Ayh+
9WgQfxGwqKbAePydYPgj/HPB0UuZy98SFWVXaoyOL14yoWsDNDRl9cbBQk73IlOG
0MJZQLFs/voEFHtp2vmytEspQYnzoJWAbaYzuv1JuJ7p4lg+KMBCyHzY/C4PyBQ1
01Y1qKyojRUunjHLtOByWf6WoN8BowhaVlDTymjsZxGbbJ4gGPXBZzGwRQLJIJYm
3a+33exsOywTWmXK6eXCe4lT7R0WfUBxnL98uzEyd2MrZwLlrjL6t61yW2DPCQA5
DLNpzg1xDNFOKxrqOaAc0l4BbdMLoLTJyE+bQApW3z+kFWFXBgyIzwn3hhrVaqGF
uo6L2AWvUUvLeOR1APyQi4zM7lZ1TFDRd8j9147P/XyvEpH4KLpOsg6YEtBNL6tK
Gzr1NkPJSLY3m42NUAjy
=vkun
-----END PGP MESSAGE-----
fp: C19A7D807525CE24443CA9A49372E896B41FE700
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMAztV5cc72nziAQ//XAPd5zFKCAQJ/a483lBmHbF0619H7YnJaWkPyg12pQ/d
XgeZEN54TGW3ItCrw6DDhPM+HU0msRzk1lGqvMLY8ZrBIFQEQab/XAGFI3/LD01S
TWlP/G7xykD3M3DKR9du1VSgFq8VAgZXpxZYjZlFmdG0R2S566E4bRpLahQjc4Ky
IZs8uONA9NW7tXG/uYMqlrvLIsPXDvMCdp0g8tZ0jbzDe6JmjHO8F6X3C3PTj8CW
e1bColDBjFyGjkVjdm560zayt8iyplRV6HFSHJSbZM0aDvxD16woIgtTtcyNgSw5
/kcuUL0j35GHsuyp9MgD3R5aRo6K0hBMQ8BNO+8yMVK5SaUdx0YLfYldsIzCyjQA
bzDPgdVgzynZ4HAUesKm344O1t5yse8zVkXEZcnTaD6B2Peq8d7KebAWeYTdsoSV
D1tCBnDk2K1Z5hizQnpTKqnnxvrN6PBmlebukwBoO4sKbV1HbNLcHw6qPVnPdZwY
XsckI3DAr7N4tHvYPB+/VxGWTDG2YXt5F9uEF1UP2LG9EywKwlv7txVvOODZBdif
oLF3CnHjPwOe72QwMNAAT/NEkvj1zHq7Gbs8sw8wCPGYK8It1pP9S90Twd4wpN8+
GxLYUHviJ2OKeNCpnCScDlZbeSZ73tPCXt4AflHtmR4xm2WeYOGLpYf0qebcWE/S
XgHn+1dCTTZrTwg2a3/KxyZyWjJQlNpelFu01nZqRf+2sfhJ87RO+VC127j2fQ9m
OVQRo7SppJ1bGKePYPCxr3n2yX5OAg59Zosmpol6CmnA69+1XI/9WKO6DjQLhIE=
=T8yr
-----END PGP MESSAGE-----
fp: 0DB51A7E90AC6418B7DB83724D38970874850C33
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DE0EFwq0sN6cSAQdACZWKgv/UBGhkQYwzobY7i3bjIqf0h2/+tQ8a4Y3OhHUw
QLX6jxqf9v8mm+T6bbIw9dPBii2CcOQuX08snLZND4U2krCDmMje6dXv8vFqaG68
1GgBCQIQI4HHAYaBSQyNs5OzEdnlIQHITx5pHddPWAuRdZjV9HjZlTFAXt2OuyGo
mDJ8Q9IZ3uEryX9QHYj9xMI5EiWPEtG+F/dOZTdDFiaecFShFyT0dtjbKpq9/oLo
Asqs37LyfqxdXA==
=9o84
-----END PGP MESSAGE-----
fp: BBA0C26647A2D87ABA186D6F3D284EA725F9552E
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DZmNQj/lmIGsSAQdA49S+dmUCPFNLnmDhAxcJauiyU5WRDruQ4/qoUHAhlGww
a/MWR0oHxJ7rjnWORYnrjiL2ZroCpEBylIqFoITN8rJ3+15HdCheYNQUCtqDunux
1GgBCQIQ4tIsGLzPYuMieuk6rQQOxZrraO8kbVwT6CAKWjdHROWlw3tQInIFj+cq
inH1dMovK98BGeoxkTLH5gwyfct5fyopnph9E3fIt5WCXuRV8Ak45Bv0C381a3jQ
/0vMA/o/7+lX4Q==
=0Oor
-----END PGP MESSAGE-----
fp: 73C2C9954D1BC94DC6682525D2FA233B52AEC75C
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMA6r2J+JSOMNuAQwAmiOT0gsE4YTRfJY0Y6j5Niba4O717IHAPLS4ufvMTtRi
ea0092B1ocXy6ZIW9jxQ69dZ5hlBHo2XOc29XmxJdYNvYMQlF0CDvy/iIidnKk/V
FuoDH3KwHZRXWOdDoasbNdwemB+7b+mKE2QwEtxCMmXfPADjSJVkJshASzzKIqnJ
ezM/2JZi93RNk1kEEy26O5MgjLlx+Hw7MyV9TBvoGAsapIQ0F/8KqdL1TAyS9tZk
kBZK41KZ57OR9/7o9adUoYmQFEEiW7pKPjLsUinn/u1I0savVVUqnF4laZlD0gcN
Rcf614BAdlmatC9L5kyJ8y9MYyfALEAbduX9VCx9Ml53hUMcC2pZZyqrB9vRCc9a
/dMDSTsD3XvwMTufSflZqbqHUxVwZmxdj5XrL6eLtqwPJw3TieU90v8KBuWswbOH
bKU7bJlJTsB2Ybe46INm3hbplw7+6bcmRon94ApWM3BAcMEwHx31jcFdnuhsCj+C
eDdaTmMMhq+iYRFLUy1z0l4Bt456lbnPk53wVh2FTznOmcp+ifs/1un7lA3Hs0Q8
ZKr6tDF1U6VvQz2G5mKXAa3hfgvPMUyLwuaQX60xKeCxaJLyg8xjFuKF+/FVM5SG
1KEM4STkW0U5XTeTCZ3q
=0h3U
-----END PGP MESSAGE-----
fp: 3511D1A5B7B2AC97BAE8AF3EE758168C000375CE
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DAQRCY74qADkSAQdAvIowg8Xclb585kkv1RbnvQyw/IH3ilglRS8P4/6KrjYw
wDVdFJ1NGxYaZS8GwxABxWUxiPwX3icUpGdkC9V6/SDPt0rLLfrM/nF8bx9qn8m/
1GgBCQIQ2/4+OS0baD4CY+FQxXrrlN7yQwz6hbC2MOmh4UkTDqTPMRX4j6VJClVN
s1gm2K1H3/dwMCNDnShJR0SqFmL7MENClZx4pViLd4R85dirVc/4IK6cWV+wjd4f
NGLewEarDP4Nmg==
=HKnS
-----END PGP MESSAGE-----
fp: 0C136F7514100470AD3EC8D37BF1FAEDB2ACCA9A
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMA6N7K3Tfl3HGAQwAkX3y1cILzx7sPNoEHjRogEzDhEc20yTSIf9ezCYKaiJr
BxNSSnMqJHCPRYmJduz+BOiQrnDpGVnIJj5FW3cswp4Ua9ez7pVK7XGffyp8pNr6
pc5ONXuoWu6cxvB3J46V1dE5f6dTPANo50eOlhmYqI73R+3lQGal11eq4jiOiHpB
wA/bbrcuuvltam2TilpZgDyC5mpXu4mb37UB1Qmm+2pu6iriQhjgVtDgd9O7dOWQ
G9ow1j45B+P2gnbpew/piqaID3W6Ctv+A76iEUnlfmRt+elwdxoowUjXBYiBqvMA
gpc1rURhMwpFXDZ376LpOu+laqe249vuF8Fv0vpIXtB+ku0c/15Nih9UpMqHE/JI
I68pIH/Bo/PQiZH7R4AYbyzWZEOVyseMOnXxx+nabvSzLKX75OiFOgmFRRwN3SFn
LtiVvmDr29jRQl6jBWT+Hdx3KU269yWHRAs/IDCJ++ahLZcLPtoypUw6Qpzr+NM4
BlYglPvpW+4rIq70o3KN1GgBCQIQPv9A0Itmo4dXEwz9yIPBavcX0m9YHqkNxoxX
WBplWcRtGcLPiGvg84d7hhOkRvkinlns0DjP/74k1knI3Deyxsm64V5NsplyxlHx
tosS1LBdsA4fUxArXp/kzWD8317r3vzyow==
=7SZ5
-----END PGP MESSAGE-----
fp: BB333E772B60EC8A29E8DE641D6B8CC68E09BCA5
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA5KoiSc3R+FfARAAhcW4yy5yQAYAfmEqiMpQmwGZZDhHWzWBMO/dkJXke0kk
C6iYT0FNLAgCnG8ONurf/IXteRf00zEsjhel6wanpZnb5w9NlfI9m3KArI/e/zce
Jqea+SxGcTloGeWn1lpgu1Lg6ajP5w6Z8o29HNlMQ/8ikdrNQJrThRFRBaRRsgU0
BYWD6n4yB+SbczVZFjNvuijLerAuRTwEXsbSDuqUdn2YS3yfK5l6CJycEpJJnMrY
36vedeJ2SyiWFHY0W5BRhATkYjFf7FyNYLseWIHVDQ1pa1kItTJzEp9UY5BkjaUL
8LsVDutNCgxz1hgdpC0kwAYB43uhVC+zZTbSIrJstP0NDk7n5q5I5nIXw2O6LpG5
SAKFdAoOMhJanIr/KPGwWcMzbAPJjna8+DdkOPh+Sli4gwKJ1ta/PvPVemt0VraO
/xxj+gmdRQRbtl9bmraLwofOMy4egUNxGubDLIRNWtGIMyKaTsqeb/BoEBM2StBo
/EKeeanHREB36DJTyvUYcplpPivzNJVjsui2RQp9MfdVA2o4bGn4wtfrVJwFXzBQ
5x1eBhaVwdZIq8Eb+9F0eSHFZmz94PhYubb+Wf5YcuKy2cEc16yVgB7CIeReLgjV
PbiqcrB0r/UHAWUER9Urewl6bBmpzNccjGsPQQx7lkAgZqOjgl5bO3sqzriohtzS
XgFFm1ImeTVy5DdtowCYryA/fw9XvI4cG7np9FK6ZEhOjTuneJ8uOc2hyZsiKpkV
41Ia28jLCcl63zVNBbE6QdCzXa4Niy3q0JPRjDZo1y+DfmsPja7QRIlOCd92UJc=
=n3js
-----END PGP MESSAGE-----
fp: 57F93F2A6585CF2DF9A3B31F13B9F45E122698D5
- created_at: "2025-10-22T08:32:24Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQGMAwTtVaE3mgdcAQv/ZorP3XE4BVsGhz5m92Fch9W7ZeG3S45o1b5pgGR3/Aw4
323PWxqCuR22wtgHw1plfCnFH4O3/3j3bP2fWzYd4HAnxvjaFDdBqG8kC5klkDG0
hAeL2nT8UvpWUZhhqFOwgeYJrrUsWvHEtYyfomqLbwMSKpLUUONWw+lpWOpy8YhK
+VX3qBkZ/KI2mbv9R6wUYbLf81j5LrCcCrx2DJ8B9Q5EXcWn8KaFQAHNQvIlj2m2
kcDJnODx9iHNjMf9lRlJ+wN9vb7+RZlPshGMgXMsn9HipxDbqe0F8+H098heceVw
gPuush8/ZEKAyi6aj/s/bWHjQ2bZW1IMSzT0V6N2r/SpVU6GVDSrnLhyuiJvNypd
7TIDeGXj8eN3s7KY2rHfsMIo7EUI/w//ahFM/SNchfMhyLrD8t169e9xHXQZdgQS
wq4srLq2byM2VZgxMeC0mPjzsl2+GXWM40aFl6N8jQ781946KPUG3At0IsYtcP+1
0RSAUlybEO91cS81iZQY1GgBCQIQpylFCD/qJtg2Gns6Sg0RQIn5jXk6WtO95ZD0
gLimARayL5pocbeAgCW+rKLkW/NhcjjTSAOyeriU9O5vSCFiZ9O9Drr27zjK6o3G
NwHeOhPqwHt7UiCBcBSzxKjiY7VUJBYKWg==
=4BZs
-----END PGP MESSAGE-----
fp: D667348F310C57655FCE5D4EA689FF232FD681F0
unencrypted_suffix: _unencrypted
version: 3.10.2

@ -0,0 +1,147 @@
#!/usr/bin/env bash
# PURPOSE: Test to verify update_sops.sh script
set -ueo pipefail
test_dir="$(realpath $(dirname "${BASH_SOURCE[0]}"))"
cd "${test_dir}"
# opinionated: keys located in current repo, one level up
keys_dir="$(dirname "${test_dir}")"
# deliberate: just "dot" for current dir
sops_cfg_dir=.
secrets_file="mock_secrets.yaml"
# prerequisite: for verification of sops config, idempotent create file with a mock secret, src: https://bash-org-archive.com/?244321
test -e "${secrets_file}" || (yq -n '.demo.credentials.secret = "hunter2"' > "${secrets_file}" && sops -e -i "${secrets_file}" )
# Special Case: Add caveat header
cat <<EOM > .sops.yaml.tmp
# PURPOSE: BLUEPRINT for .sops.yaml config
# CAVEAT: DO NOT USE THIS FILE AS-IS in another project; copy it and remove the unauthorised users
$( cat .sops.yaml )
EOM
mv .sops.yaml.tmp .sops.yaml
# TESTCASES
# define "fixture"
repo_root="$(git rev-parse --show-toplevel)"
# ---
function fn_test_create_sops_cfg_default(){
>&2 echo -e "# ---\n# TEST: create sops cfg in default dir: ${repo_root}"
set -x
rm "${PWD}/.sops.yaml" || :
# note: fail if for any reason sops config defined at top level; this repo should not have this!
test ! -e "${repo_root}/.sops.yaml"
../bin/update_sops.sh -s "${secrets_file}" > /dev/null 2>&1
test ! -e "${PWD}/.sops.yaml"
test -e "${repo_root}/.sops.yaml"
set +x
# teardown
# enmesh: restore, since this particular one is checked in
git checkout "${PWD}/.sops.yaml" > /dev/null 2>&1
rm "${repo_root}/.sops.yaml"
}
# ---
function fn_test_create_sops_cfg_dir_cwd(){
>&2 echo -e "# ---\n# TEST: create sops cfg in curdir: ${PWD}"
set -x
# note: fail if for any reason sops config defined at top level; this repo should not have this!
test ! -e "${repo_root}/.sops.yaml"
rm "${PWD}/.sops.yaml" || :
# minimal operation: update .sops.yaml, update keys in encrypted file
../bin/update_sops.sh -c "${PWD}" "${secrets_file}" > /dev/null 2>&1
test -e "${PWD}/.sops.yaml"
test ! -e "${repo_root}/.sops.yaml"
set +x
# teardown
# not necessary, all tracked in git
# enmesh: restore, since this particular one is checked in
git checkout "${PWD}/.sops.yaml" > /dev/null 2>&1
}
# ---
function fn_test_create_sops_cfg_opts_complex_1(){
>&2 echo -e "# ---\n# TEST: Full Args: specify path to each, also for secrets, mix specified and positional params"
set -x
../bin/update_sops.sh -k "${keys_dir}" -c "${sops_cfg_dir}" -s "${secrets_file}" "${secrets_file}" > /dev/null 2>&1
set +x
# teardown
# not necessary, all tracked in git
# enmesh: restore, since this particular one is checked in
git checkout "${PWD}/.sops.yaml" > /dev/null 2>&1
}
# ---
function fn_test_auto_find_secrets_files(){
>&2 echo -e "# ---\n# TEST: auto-find secrets files"
# SETUP
_tmp_mock_secrets_dir='mock_hierarchy'
_tmp_mock_secrets_filepath_1="${_tmp_mock_secrets_dir}/one/secrets.yaml"
mkdir -p "$(dirname "${_tmp_mock_secrets_filepath_1}")"
touch "${_tmp_mock_secrets_filepath_1}"
_tmp_mock_secrets_filepath_2='mock_hierarchy/Tw o/secrets.yaml'
mkdir -p "$(dirname "${_tmp_mock_secrets_filepath_2}")"
touch "${_tmp_mock_secrets_filepath_2}"
# RUN
# set -x
# suspend strict: check output for errors
set +e
# move 'set -x' within the sub-shell, otherwise all output dumped to tty
# ... bug: stderr still gets printed, not sure why. E.g. '# RUN: sops updatekeys mock_secrets.yaml'
_out="$(set -x; ../bin/update_sops.sh --find_secrets -s "${secrets_file}" 2>&1 )"
echo "$_out}"
# re-enable strict
set -e
set +x
grep "${_tmp_mock_secrets_filepath_1}" <<< "${_out}"
grep "${_tmp_mock_secrets_filepath_2}" <<< "${_out}"
grep "${secrets_file}" <<< "${_out}"
set -e
# TEARDOWN
set -x
rm -rf "${_tmp_mock_secrets_dir}"
# enmesh: restore, since this particular one is checked in
git checkout "${PWD}/.sops.yaml" > /dev/null 2>&1
}
# ---
function fn_test_expect_error_invalid_file(){
>&2 echo -e "# ---\n# TEST: induce error: invalid file"
# dev note: ':' is a noop operator; could also just temporarily disable strict errors
set -x
../bin/update_sops.sh "${secrets_file}" -s non_existing_secrets.yaml > /dev/null 2>&1 || :
set +x
# teardown
# not necessary, all tracked in git
# enmesh: restore, since this particular one is checked in
git checkout "${PWD}/.sops.yaml" > /dev/null 2>&1
}
if [[ 1 -eq 1 ]]; then
fn_test_create_sops_cfg_default
else
>&2 echo "# INFO: skipping ...."
fi
if [[ 1 -eq 1 ]]; then
fn_test_create_sops_cfg_dir_cwd
else
>&2 echo "# INFO: skipping ...."
fi
if [[ 1 -eq 1 ]]; then
fn_test_create_sops_cfg_opts_complex_1
else
>&2 echo "# INFO: skipping ...."
fi
if [[ 1 -eq 1 ]]; then
fn_test_auto_find_secrets_files
else
>&2 echo "# INFO: skipping ...."
fi
if [[ 1 -eq 1 ]]; then
fn_test_expect_error_invalid_file
else
>&2 echo "# INFO: skipping ...."
fi
# ---
echo "TESTCASES PASSED"
exit 0

@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -ueo pipefail
# PURPOSE: Allows User to verify their local SOPS configuration using a sample SOPS config and SOPS-encrypted file
# Usage: 1. Existing User: upon adding key, run this script to update the SOPS Config and encrypted file
# 2. New User: 'Existing User' has added key, run this script to confirm correct local configuration
cd "$(dirname "${BASH_SOURCE[0]}")"
secrets_file="mock_secrets.yaml"
# prerequisite: for verification of sops config, idempotent create file with a mock secret, src: https://bash-org-archive.com/?244321
test -e "${secrets_file}" || (yq -n '.demo.credentials.secret = "hunter2"' > "${secrets_file}" && sops -e -i "${secrets_file}" )
set -x
# within current dir: update .sops.yaml, update keys in encrypted file
../bin/update_sops.sh -c "${PWD}" "${secrets_file}"
# verify: dump secrets, GPG_TTY src: https://www.varokas.com/secrets-in-code-with-mozilla-sops/
GPG_TTY=$(tty) sops -d "${secrets_file}"
# Special Case: Add caveat header
cat <<EOM > .sops.yaml.tmp
# PURPOSE: BLUEPRINT for .sops.yaml config
# CAVEAT: DO NOT USE THIS FILE AS-IS in another project; copy it and remove the unauthorised users
$( cat .sops.yaml )
EOM
mv .sops.yaml.tmp .sops.yaml
# if reached this far, is success, due to bash strict mode. I.e. script would have failed by now.
echo "SUCESS"
Loading…
Cancel
Save