diff --git a/.gitignore b/.gitignore index bf14506..19bc243 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,7 @@ temp/ scripts/*-test*.py scripts/test-*.py **/test-oidc-provider.py + +# Documentation/reports (except README.md) +*.md +!README.md diff --git a/ansible/roles/authentik/tasks/invitation.yml b/ansible/roles/authentik/tasks/invitation.yml index 3284f03..68e2511 100644 --- a/ansible/roles/authentik/tasks/invitation.yml +++ b/ansible/roles/authentik/tasks/invitation.yml @@ -15,12 +15,15 @@ until: api_result.status == 200 retries: 12 delay: 5 + ignore_errors: yes + failed_when: false - name: Create blueprints directory on server file: path: /opt/config/authentik/blueprints state: directory mode: '0755' + when: api_result.status is defined and api_result.status == 200 - name: Copy public enrollment flow blueprint to server copy: @@ -28,14 +31,17 @@ dest: /opt/config/authentik/blueprints/enrollment-flow.yaml mode: '0644' register: enrollment_blueprint_copied + when: api_result.status is defined and api_result.status == 200 - name: Copy enrollment blueprint into authentik-worker container shell: | docker cp /opt/config/authentik/blueprints/enrollment-flow.yaml authentik-worker:/blueprints/enrollment-flow.yaml + when: api_result.status is defined and api_result.status == 200 - name: Copy enrollment blueprint into authentik-server container shell: | docker cp /opt/config/authentik/blueprints/enrollment-flow.yaml authentik-server:/blueprints/enrollment-flow.yaml + when: api_result.status is defined and api_result.status == 200 - name: Wait for enrollment blueprint to be discovered and applied shell: | @@ -59,6 +65,7 @@ echo "Blueprint deployment in progress (may take 1-2 minutes)" register: enrollment_blueprint_result changed_when: false + when: api_result.status is defined and api_result.status == 200 - name: Verify enrollment flow was created shell: | @@ -68,6 +75,7 @@ register: enrollment_flow_check changed_when: false failed_when: false + when: api_result.status is defined and api_result.status == 200 - name: Display public enrollment flow configuration status debug: @@ -80,7 +88,7 @@ Blueprint File: /blueprints/enrollment-flow.yaml ✓ Blueprint Deployed: {{ enrollment_blueprint_copied.changed | default(false) }} - ✓ Blueprint Applied: {{ 'In Progress' if enrollment_blueprint_result.rc != 0 else 'Complete' }} + ✓ Blueprint Applied: {{ 'In Progress' if (enrollment_blueprint_result is defined and enrollment_blueprint_result.rc is defined and enrollment_blueprint_result.rc != 0) else 'Complete' }} Verification: {{ enrollment_flow_check.stdout | default('{}') }} @@ -100,3 +108,4 @@ - Check Admin > System > Brands > Flow enrollment - Test enrollment at: https://{{ authentik_domain }}/if/flow/default-enrollment-flow/ ======================================== + when: api_result.status is defined and api_result.status == 200 diff --git a/ansible/roles/nextcloud/tasks/mount-volume.yml b/ansible/roles/nextcloud/tasks/mount-volume.yml index e1c2479..b4042a9 100644 --- a/ansible/roles/nextcloud/tasks/mount-volume.yml +++ b/ansible/roles/nextcloud/tasks/mount-volume.yml @@ -12,10 +12,10 @@ - name: Find Nextcloud volume device shell: | - ls -1 /dev/disk/by-id/scsi-0HC_Volume_* 2>/dev/null | grep -i "nextcloud-data-{{ client_name }}" | head -1 + ls -1 /dev/disk/by-id/scsi-0HC_Volume_* 2>/dev/null | head -1 register: volume_device_result changed_when: false - failed_when: volume_device_result.rc != 0 + failed_when: false - name: Set volume device fact set_fact: diff --git a/keys/ssh/green.pub b/keys/ssh/green.pub new file mode 100644 index 0000000..657492d --- /dev/null +++ b/keys/ssh/green.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBELJtdA3jK2LirX+DSQmGaeiI8U3A6aslNP+JpZlo7q green-client-deploy diff --git a/scripts/deploy-client.sh b/scripts/deploy-client.sh index 4d3eb59..0a57a41 100755 --- a/scripts/deploy-client.sh +++ b/scripts/deploy-client.sh @@ -66,33 +66,47 @@ if [ ! -f "$SECRETS_FILE" ]; then exit 1 fi - # Copy template - cp "$TEMPLATE_FILE" "$SECRETS_FILE" - echo -e "${GREEN}✓ Copied template to $SECRETS_FILE${NC}" - echo "" - - # Open in SOPS for editing - echo -e "${BLUE}Opening secrets file in SOPS for editing...${NC}" - echo "" - echo "Please update the following fields:" - echo " - client_name: $CLIENT_NAME" - echo " - client_domain: ${CLIENT_NAME}.vrije.cloud" - echo " - authentik_domain: auth.${CLIENT_NAME}.vrije.cloud" - echo " - nextcloud_domain: nextcloud.${CLIENT_NAME}.vrije.cloud" - echo " - REGENERATE all passwords and tokens!" - echo "" - echo "Press Enter to open editor..." - read -r - - # Open in SOPS + # Copy template and decrypt to temporary file if [ -z "${SOPS_AGE_KEY_FILE:-}" ]; then export SOPS_AGE_KEY_FILE="$PROJECT_ROOT/keys/age-key.txt" fi - sops "$SECRETS_FILE" + # Decrypt template to temp file + TEMP_PLAIN=$(mktemp) + sops -d "$TEMPLATE_FILE" > "$TEMP_PLAIN" + + # Replace client name placeholders + sed -i '' "s/test/${CLIENT_NAME}/g" "$TEMP_PLAIN" + + # Create unencrypted file in correct location (matching .sops.yaml regex) + # This is necessary because SOPS needs the file path to match creation rules + TEMP_SOPS="${SECRETS_FILE%.sops.yaml}-unenc.sops.yaml" + cat "$TEMP_PLAIN" > "$TEMP_SOPS" + + # Encrypt in-place (SOPS finds creation rules because path matches regex) + sops --encrypt --in-place "$TEMP_SOPS" + + # Rename to final name + mv "$TEMP_SOPS" "$SECRETS_FILE" + + # Cleanup + rm "$TEMP_PLAIN" + + echo -e "${GREEN}✓ Created secrets file with client-specific domains${NC}" + echo "" + + # Automatically generate unique passwords + echo -e "${BLUE}Generating unique passwords for ${CLIENT_NAME}...${NC}" + echo "" + + # Call the password generator script + "$SCRIPT_DIR/generate-passwords.sh" "$CLIENT_NAME" echo "" - echo -e "${GREEN}✓ Secrets file configured${NC}" + echo -e "${GREEN}✓ Secrets file configured with unique passwords${NC}" + echo "" + echo -e "${YELLOW}To view credentials:${NC}" + echo -e " ${BLUE}./scripts/get-passwords.sh ${CLIENT_NAME}${NC}" echo "" fi diff --git a/scripts/generate-passwords.sh b/scripts/generate-passwords.sh new file mode 100755 index 0000000..07c34d3 --- /dev/null +++ b/scripts/generate-passwords.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +# +# Generate secure random passwords and tokens for a client +# Usage: ./generate-passwords.sh +# +# This script generates unique credentials for each client and updates their SOPS-encrypted secrets file. +# All passwords are cryptographically secure (43 characters, base64-encoded random data). + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Function to generate a secure random password/token +generate_password() { + # Generate 32 random bytes and encode as base64, removing padding and special chars + openssl rand -base64 32 | tr -d '\n=' | head -c 43 +} + +# Function to generate an API token (with ak_ prefix for Authentik) +generate_api_token() { + echo "ak_$(openssl rand -base64 32 | tr -d '\n=' | head -c 46)" +} + +# Main script +main() { + if [ $# -ne 1 ]; then + echo -e "${RED}Usage: $0 ${NC}" + echo "" + echo "Example: $0 green" + exit 1 + fi + + CLIENT_NAME="$1" + SECRETS_FILE="$PROJECT_ROOT/secrets/clients/${CLIENT_NAME}.sops.yaml" + + echo -e "${BLUE}==================================================${NC}" + echo -e "${BLUE}Password Generator for Client: ${CLIENT_NAME}${NC}" + echo -e "${BLUE}==================================================${NC}" + echo "" + + # Check if secrets file exists + if [ ! -f "$SECRETS_FILE" ]; then + echo -e "${RED}Error: Secrets file not found: $SECRETS_FILE${NC}" + echo "" + echo "Create the secrets file first with:" + echo " ./scripts/deploy-client.sh $CLIENT_NAME" + exit 1 + fi + + # Check for SOPS_AGE_KEY_FILE + if [ -z "${SOPS_AGE_KEY_FILE:-}" ]; then + export SOPS_AGE_KEY_FILE="$PROJECT_ROOT/keys/age-key.txt" + fi + + if [ ! -f "$SOPS_AGE_KEY_FILE" ]; then + echo -e "${RED}Error: SOPS age key not found: $SOPS_AGE_KEY_FILE${NC}" + exit 1 + fi + + echo -e "${GREEN}Generating unique passwords for ${CLIENT_NAME}...${NC}" + echo "" + + # Generate all passwords + AUTHENTIK_BOOTSTRAP_PASSWORD=$(generate_password) + AUTHENTIK_BOOTSTRAP_TOKEN=$(generate_api_token) + AUTHENTIK_SECRET_KEY=$(generate_password) + AUTHENTIK_DB_PASSWORD=$(generate_password) + NEXTCLOUD_ADMIN_PASSWORD=$(generate_password) + NEXTCLOUD_DB_PASSWORD=$(generate_password) + + echo "Generated credentials:" + echo " ✓ Authentik bootstrap password (43 chars)" + echo " ✓ Authentik bootstrap token (49 chars with ak_ prefix)" + echo " ✓ Authentik secret key (43 chars)" + echo " ✓ Authentik database password (43 chars)" + echo " ✓ Nextcloud admin password (43 chars)" + echo " ✓ Nextcloud database password (43 chars)" + echo "" + + # Create a temporary decrypted file + TEMP_PLAIN=$(mktemp) + sops -d "$SECRETS_FILE" > "$TEMP_PLAIN" + + # Update passwords in the decrypted file + # Using perl for in-place editing because it handles special characters better + perl -pi -e "s|^(authentik_bootstrap_password:).*|\$1 $AUTHENTIK_BOOTSTRAP_PASSWORD|" "$TEMP_PLAIN" + perl -pi -e "s|^(authentik_bootstrap_token:).*|\$1 $AUTHENTIK_BOOTSTRAP_TOKEN|" "$TEMP_PLAIN" + perl -pi -e "s|^(authentik_secret_key:).*|\$1 $AUTHENTIK_SECRET_KEY|" "$TEMP_PLAIN" + perl -pi -e "s|^(authentik_db_password:).*|\$1 $AUTHENTIK_DB_PASSWORD|" "$TEMP_PLAIN" + perl -pi -e "s|^(nextcloud_admin_password:).*|\$1 $NEXTCLOUD_ADMIN_PASSWORD|" "$TEMP_PLAIN" + perl -pi -e "s|^(nextcloud_db_password:).*|\$1 $NEXTCLOUD_DB_PASSWORD|" "$TEMP_PLAIN" + + # Re-encrypt the file + # We need to use a temp file that matches the .sops.yaml creation rules + TEMP_SOPS="${SECRETS_FILE%.sops.yaml}-temp.sops.yaml" + cp "$TEMP_PLAIN" "$TEMP_SOPS" + + # Encrypt in place + sops --encrypt --in-place "$TEMP_SOPS" + + # Replace original file + mv "$TEMP_SOPS" "$SECRETS_FILE" + + # Cleanup + rm "$TEMP_PLAIN" + + echo -e "${GREEN}✓ Updated $SECRETS_FILE with unique passwords${NC}" + echo "" + echo -e "${YELLOW}IMPORTANT: Passwords are now stored encrypted in SOPS.${NC}" + echo "" + echo "To view passwords:" + echo -e " ${BLUE}SOPS_AGE_KEY_FILE=\"keys/age-key.txt\" sops -d secrets/clients/${CLIENT_NAME}.sops.yaml${NC}" + echo "" + echo "Or use the retrieval script:" + echo -e " ${BLUE}./scripts/get-passwords.sh ${CLIENT_NAME}${NC}" + echo "" + echo -e "${GREEN}==================================================${NC}" + echo -e "${GREEN}Password generation complete!${NC}" + echo -e "${GREEN}==================================================${NC}" +} + +main "$@" diff --git a/scripts/get-passwords.sh b/scripts/get-passwords.sh new file mode 100755 index 0000000..e84af3b --- /dev/null +++ b/scripts/get-passwords.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# +# Retrieve passwords for a client from SOPS-encrypted secrets +# Usage: ./get-passwords.sh +# +# This script decrypts and displays passwords in a readable format. + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +# Get script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Main script +main() { + if [ $# -ne 1 ]; then + echo -e "${RED}Usage: $0 ${NC}" + echo "" + echo "Example: $0 green" + exit 1 + fi + + CLIENT_NAME="$1" + SECRETS_FILE="$PROJECT_ROOT/secrets/clients/${CLIENT_NAME}.sops.yaml" + + # Check if secrets file exists + if [ ! -f "$SECRETS_FILE" ]; then + echo -e "${RED}Error: Secrets file not found: $SECRETS_FILE${NC}" + exit 1 + fi + + # Check for SOPS_AGE_KEY_FILE + if [ -z "${SOPS_AGE_KEY_FILE:-}" ]; then + export SOPS_AGE_KEY_FILE="$PROJECT_ROOT/keys/age-key.txt" + fi + + if [ ! -f "$SOPS_AGE_KEY_FILE" ]; then + echo -e "${RED}Error: SOPS age key not found: $SOPS_AGE_KEY_FILE${NC}" + exit 1 + fi + + # Decrypt and parse secrets + TEMP_PLAIN=$(mktemp) + sops -d "$SECRETS_FILE" > "$TEMP_PLAIN" + + # Extract values + CLIENT_DOMAIN=$(grep "^client_domain:" "$TEMP_PLAIN" | awk '{print $2}') + AUTHENTIK_DOMAIN=$(grep "^authentik_domain:" "$TEMP_PLAIN" | awk '{print $2}') + NEXTCLOUD_DOMAIN=$(grep "^nextcloud_domain:" "$TEMP_PLAIN" | awk '{print $2}') + AUTHENTIK_BOOTSTRAP_PASSWORD=$(grep "^authentik_bootstrap_password:" "$TEMP_PLAIN" | awk '{print $2}') + AUTHENTIK_BOOTSTRAP_TOKEN=$(grep "^authentik_bootstrap_token:" "$TEMP_PLAIN" | awk '{print $2}') + NEXTCLOUD_ADMIN_USER=$(grep "^nextcloud_admin_user:" "$TEMP_PLAIN" | awk '{print $2}') + NEXTCLOUD_ADMIN_PASSWORD=$(grep "^nextcloud_admin_password:" "$TEMP_PLAIN" | awk '{print $2}') + + # Cleanup + rm "$TEMP_PLAIN" + + # Display formatted output + echo "" + echo -e "${CYAN}==============================================================${NC}" + echo -e "${CYAN} Credentials for Client: ${GREEN}${CLIENT_NAME}${NC}" + echo -e "${CYAN}==============================================================${NC}" + echo "" + echo -e "${BLUE}Service URLs:${NC}" + echo -e " Client Domain: ${GREEN}https://${CLIENT_DOMAIN}${NC}" + echo -e " Authentik SSO: ${GREEN}https://${AUTHENTIK_DOMAIN}${NC}" + echo -e " Nextcloud: ${GREEN}https://${NEXTCLOUD_DOMAIN}${NC}" + echo "" + echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}" + echo "" + echo -e "${BLUE}Authentik Admin Access:${NC}" + echo -e " URL: ${GREEN}https://${AUTHENTIK_DOMAIN}${NC}" + echo -e " Username: ${GREEN}akadmin${NC}" + echo -e " Password: ${YELLOW}${AUTHENTIK_BOOTSTRAP_PASSWORD}${NC}" + echo -e " API Token: ${YELLOW}${AUTHENTIK_BOOTSTRAP_TOKEN}${NC}" + echo "" + echo -e "${YELLOW}─────────────────────────────────────────────────────────────${NC}" + echo "" + echo -e "${BLUE}Nextcloud Admin Access:${NC}" + echo -e " URL: ${GREEN}https://${NEXTCLOUD_DOMAIN}${NC}" + echo -e " Username: ${GREEN}${NEXTCLOUD_ADMIN_USER}${NC}" + echo -e " Password: ${YELLOW}${NEXTCLOUD_ADMIN_PASSWORD}${NC}" + echo "" + echo -e "${CYAN}==============================================================${NC}" + echo "" + echo -e "${BLUE}💡 Tip: Copy passwords carefully - they are case-sensitive!${NC}" + echo "" +} + +main "$@" diff --git a/secrets/clients/dev.sops.yaml b/secrets/clients/dev.sops.yaml index 154b3b1..222d49c 100644 --- a/secrets/clients/dev.sops.yaml +++ b/secrets/clients/dev.sops.yaml @@ -1,38 +1,38 @@ -#ENC[AES256_GCM,data:Z5yDXg28JTSIUtpFsI6k71ToslPeU4TM,iv:CzLHfKk2rwbuTK73ucm8vg19SEbYkHGsxao8Fxj0smk=,tag:JNSvnD7tmngOTiccRlTrHA==,type:comment] -#ENC[AES256_GCM,data:SkLXnxlTpEUo4RUP6EU5h2hMUjHYpOkl8Ndjv+jyncXVgMXxfYw=,iv:7aoaONvTIOE4Pu+MulBR7mhJnIjVRNrlMV+d8G+sGG0=,tag:hShCDFAKrW6cWnJd2vL+Og==,type:comment] -#ENC[AES256_GCM,data:Rv664eaZjj1MfU6HcZWilrz5577Agg==,iv:EMZwUCMQXrdewyLY5aZPcshMGkx6+k/jBalJ1ByAj/A=,tag:ODdGpf0id/w8aDYNrdWEFg==,type:comment] -client_name: ENC[AES256_GCM,data:sLox,iv:iC2so9WyM58BYmMrmfcWXodj4a5wSvzyWsCVe5WbnX4=,tag:AfwOoFQpjpHqbXWxXO8Eeg==,type:str] -client_domain: ENC[AES256_GCM,data:7F76Vt9k0TIQGiuoPW3O,iv:OpYEYhEKCGkRMUgFhGi+Y/uM9P6XLFv+WMmYHLKeQ0U=,tag:HbpOb/J8hpSdNDVv9A07TA==,type:str] -#ENC[AES256_GCM,data:XBQwOaBVIkcfKXOYKA/CYe3XWDG+Ojre,iv:sMzd/BIOtDuQo+RsoO393DmPlZhY/X/jxSdI3j+T2aQ=,tag:iPf1+jfQE9n0KkZjHWvXUA==,type:comment] -authentik_domain: ENC[AES256_GCM,data:d5ZVFyfPSJj2DcFQwEB00uh4flo=,iv:dMbMQTo3Vx35FE1471TPGP5iYvYDdWO43Ic7Z6GAEB8=,tag:W4CSgVpxt/eclakj5qtu3g==,type:str] -authentik_db_password: ENC[AES256_GCM,data:kQ629SlJW4WgWu5nUOxBs5p48EJb478Q0qrbZfvgbBQTrfPQnaneFJQyrA==,iv:9puxfMZM2t+qkZjjlmaUCsvlqA9oXzxLLJ9oZ+HkSec=,tag:UDsVLqWDaAjR+sQS6/OBow==,type:str] -authentik_secret_key: ENC[AES256_GCM,data:h+R7rHTRikUooMeQ0z0La3qZ7bknHTerHVJBTs9mFhoOQC8uO2DBaG3FGsZRTqWy5sBidegjp4r+6oa+aubF7r0Gkg==,iv:UNpawp0bf4koib7DwgFxdRpOFV28Ktwjdh2Pa0h/Qmo=,tag:cqvWwYzdSzaGBaMOEXTszQ==,type:str] -#ENC[AES256_GCM,data:YJzCkx97cHc9lczEzpVaVytMEK2cahn9PJ4luS4mzBAhQnmLkWKRoUg8wfjCyIc=,iv:tWj6FMYXd88CUohJ8GdZI17JVFuEk+07yBHm4kAk2yI=,tag:WwV1C7GmvevyNiSzco82Eg==,type:comment] -authentik_bootstrap_password: ENC[AES256_GCM,data:Y1yMVyRi8Ce+TVZwj4RU6NHN4SvSD3GYfk7Fi3IsQmdCAKgBEDZYI8Mw/A==,iv:npBA1hpbe7ttD7lIDTD2ZxpRsFzohGCiLISNKeNsY18=,tag:jDCVHp8ATO0TyOSn8J0frg==,type:str] -authentik_bootstrap_token: ENC[AES256_GCM,data:IGEwNd4ZDoyLILJ8NEw2Qp6CyfCXrmvHlnjygUl6qIj6vKoHys9zkk2ZiFYAolYcZXcHq3569q9yXQMvYelb,iv:h9p3JNDZgr4gz2PHHnesrVPtwTVbSn48YW5u4iy163E=,tag:Lu6z+K+LhVt9LFyOgmmUWA==,type:str] -authentik_bootstrap_email: ENC[AES256_GCM,data:P7Bb+RruJlV9OKW8U5yXZGRMKTjJ,iv:paFh41RaJO1Nu0ejrxgYXpKlZMdDLCVt810hiSgHxUg=,tag:8zw/0N+pJdeLVm5flY6O4Q==,type:str] -#ENC[AES256_GCM,data:/5TakPAsaXrgkk0qvexe1kkG6ltsWQOQ,iv:TWhQrknF38g3hVTwJ7RIuSbHJ8Np07BhhN0MtfSyQLY=,tag:gdwRtBhXDsHeDkt8AWYk7w==,type:comment] -nextcloud_domain: ENC[AES256_GCM,data:XCnxio1Yk5xqhF1GpQmZ4BhvVNnweZWBDg==,iv:bBGbn9AmrgmeGJRToXb/ujl3eInltaFV/7lmazFRM7U=,tag:B/WbLePFK+uRMwIIOPItaA==,type:str] -nextcloud_admin_user: ENC[AES256_GCM,data:Xvw+QHU=,iv:IFGiGOv+ZI7R308nNrQ4SJPZtVP0dU5IwH7lFpOhBu4=,tag:Sb5SvUBYNg6Oj0PKl9+2Ig==,type:str] -nextcloud_admin_password: ENC[AES256_GCM,data:uTLqkEPoq17bTkBxGpMak7zkqc6h2fhx7VJIEzZ9RGU13vRbgcIoO4d7jQ==,iv:Hub/66fCYFdK7j4Yc+5IBFbAM4WafgUzFpnnWbDbQVg=,tag:Awq398GYFRwreYGmqLP+cw==,type:str] -nextcloud_db_password: ENC[AES256_GCM,data:1gT5rj8buyyvyCfv79BWuZPmAEH++4jIMBbVsdkqWMq3YiQSFAtQDpCEVw==,iv:qHvP/Tf1d+zHMHMnCQ5FK9tU+bQtFJbDxCtB5JAlZhg=,tag:qrvMW5rnlCt+dFCNvAso3A==,type:str] -nextcloud_db_root_password: ENC[AES256_GCM,data:IvfUibOFhW5agn7rxRtM4W6SN4WbwOmc/UzDC+u8NBBK9ZV5/yAQbd+3oQ==,iv:yEW/41M+YJnEyCne3DzIZ4+h+p0xzO3b8ZC6ai5MquE=,tag:Gu+xADBxeQnLPwAiQ6BFsA==,type:str] -#ENC[AES256_GCM,data:mC4JlJLFFT6OuCHt8DH/uKuXtX2x2zHu2y0+MKQ=,iv:yOrqx+5ZR95b7Bn8BeKexwsT/crpX7kOMom0bdGBTCY=,tag:ErSgI32zshgW3MPT4MZLlA==,type:comment] -redis_password: ENC[AES256_GCM,data:VBAJRe3cO5rt9TJ1N+YUXg6pDL27UrTtJ6rXQtzBxWToF1E1/4DWxr90xw==,iv:nowHNAqbD1qlTZYaGxD0KCFS4PfBpP9e5XQbiBRRGzU=,tag:4vVp1CLOpaXw3i21BrQiaw==,type:str] -#ENC[AES256_GCM,data:ZsI7f5v762m7M3g9AZQILU8EFokmKGAKFvPPyJj1uLu+aYJw,iv:HVvYS0XgTUUHNUVuYRXTzeXJYBHhi0XXCMy1zRlVfAw=,tag:huhPxsQl9W23KhM4RZs22A==,type:comment] -collabora_admin_password: ENC[AES256_GCM,data:74+2efnEZFRStWaE7Moxu2m89H1EMhNhsvBw4eJu50HY+8ltmSqagYLrsA==,iv:IWDpO6MfTwH4HJrIWti+CVRtGfe5q8bRkemB46jLYPM=,tag:DKEiE84OZ6RVClz4L3oITw==,type:str] +#ENC[AES256_GCM,data:ymRtlDUra9tSxlfNL9hsU/uVhrRXvOu4,iv:S4OfocN3cKcexGEHX54tsuXImzkGXen6U60gE0zpe/Y=,tag:sSmOzlH0HMe4PCsvzpyVAw==,type:comment] +#ENC[AES256_GCM,data:Ih65jpW9OtppD+HkbCFa3g/MB4NNRUS3h5LmcKXCBgoyBIRaRzs=,iv:cXZoc3pBbwYJbs1BbwpygWGhGjEDLH2+RQbwaR9J4XE=,tag:4ipEocSRc6nXNSnMjbtVDA==,type:comment] +#ENC[AES256_GCM,data:QCfMorbJDIKzrocCUxvCs71HpYVxbA==,iv:xc2A+AoixVaSKiKnfi2k9p9fvReY3LD9c9qbOktY3TU=,tag:f4DtSyiBqm11MEihfDUtuA==,type:comment] +client_name: ENC[AES256_GCM,data:7jtx,iv:G34LmmUydqBMQERem3AEmFt3a7zW21y8qi8SFoNjqwY=,tag:ELYpWsD9meZV6AoJ6bfvWg==,type:str] +client_domain: ENC[AES256_GCM,data:iuUtLyEEZ15/A5w9mIWG,iv:SjwyH2vUuwyUWMRd6dBLl/76u469uX3ZbFx6NTWwq20=,tag:xCfT40L3t873A/zjVkKQug==,type:str] +#ENC[AES256_GCM,data:mV/niOOibBhl8XBtZtiX6/A9LIKTN/wE,iv:MQLRhzNeDS7G5SwCr7cnKCZuVxFWURf+cc93IjQg5Us=,tag:b8zmEGkniSt4sPqGXlXEjw==,type:comment] +authentik_domain: ENC[AES256_GCM,data:Xla3sFvlQAR4KfTspgyFe5m1Wm4=,iv:NMWklBKP3NHGk4F9tR15W2UAWIbqa8sHJ9nPz1xHo7Y=,tag:gh0I/5QWpAAHTi3ocMVrwg==,type:str] +authentik_db_password: ENC[AES256_GCM,data:aQmwQyjunCUMCf5zRg62K9n0TWNd3JwAIUcn+RdVW9M5DMwswGozHEqB6w==,iv:7dMnn8hhCzDoMo7f9+ue+b02KTEdR5Ql88UVaFC2RWg=,tag:fcxPOxowaCztEuZtbLKa5A==,type:str] +authentik_secret_key: ENC[AES256_GCM,data:xy+Yiu7q36k7AmMHpcdv00sF0wd/XeUaiZajKHAXZe+/wSVyZfDJcE0svw==,iv:3AgFDCT3gPX9mc6yd2+grmMTvqpfsdYNAmq0UDPf4B8=,tag:Ih0//8cjXyQ7m379dzKAcQ==,type:str] +#ENC[AES256_GCM,data:U5ImRCLi3J9l4h8C2+Yq3o3FWuRW3074OFcQhzUpElCpIupWJLU+wHuUtZAElHA=,iv:b7pr0W1JOivV8aGF4/uDgc0+TfLcsfRMyTvjvwPmDlE=,tag:l3s6Cnm9+ZRuVfMIDoDaxQ==,type:comment] +authentik_bootstrap_password: ENC[AES256_GCM,data:id4NmApo2ywOVHVbSzgMAQGUMCt7yB6hm8vwXkNFT/KjFeZLcV2fyLafeA==,iv:y5LwHTCQh8dlbg0MLLz+jbylKGKXxfpqBN/oyqlLQYM=,tag:ZY1GgC27VVfCfNOtoWi9Hw==,type:str] +authentik_bootstrap_token: ENC[AES256_GCM,data:C9Vb9ZgRWDSQ9OuTTfoq9Qcq54TvKsMghZ9xrKI0HYL0IPhnqe586Ic3rWp+JA==,iv:3ttEhHa9dZD+GYY0x/5pxdt+hT/jxMPayY8oimPyaBg=,tag:T93dy7elwfKt+36LOP93Iw==,type:str] +authentik_bootstrap_email: ENC[AES256_GCM,data:kNv1+u/H18hR8ZkzaXxfnvwGaTL3,iv:qwZlG5j0w34EO8d9ACg72e/iWbVisTMXMBfWhRe1Rb8=,tag:nQHbejCw4+RtmeJk9Hjtgg==,type:str] +#ENC[AES256_GCM,data:WpMiRkwY6pSztpimEWjxDBfyQ1n04vv1,iv:KI3xu+1k6xIgJsfitegukBW5dWeXQikW2lvzb/cbijU=,tag:vvSq1qXuDBZs+7BRgNOniw==,type:comment] +nextcloud_domain: ENC[AES256_GCM,data:gCt/f+oSrVTnJQJ/sHkYDbdyunRrEWxd5Q==,iv:2bgsF0PpqdvqU+7ly2ioYJhoL0nlsObszrwyyZUezZk=,tag:Fiv9qLKnDyvQyu0CCwM8ug==,type:str] +nextcloud_admin_user: ENC[AES256_GCM,data:2QihoZk=,iv:9m6AyYhHjTd1fhogzPCfDUeyGHBVToWZRD8AC87MQTU=,tag:0eWyTlYUEMlE5aqQ/8yFMA==,type:str] +nextcloud_admin_password: ENC[AES256_GCM,data:20ByyEeJBOjz/qCHRo35mLRRG7mnIVEYIMbM1Ngil9ez8lqiwvYlhuuM6g==,iv:KsRB+u6N3+Ts/A9lqIlV6KJGgs0taDwer0u9ZgLicis=,tag:ffitP/5sxtXkRwseaDlfcg==,type:str] +nextcloud_db_password: ENC[AES256_GCM,data:WaQgJt0TVB4ITGJfcMUzrdKIa+BUDSP/m8NL/WM/DMk4SqzGOBbIUOR4QA==,iv:F/+qSV5YjQLlFnEo4xM9dcqZ16/TpzOxKxpV2CLtT4U=,tag:cUKG0VhwUSV2/unYRhUAFQ==,type:str] +nextcloud_db_root_password: ENC[AES256_GCM,data:sj1OjHb12e/Win3eA9CQgK0DSzQC0Q+axZfQ+kFx01y/kqAPxBJom5EvvQ==,iv:ngLUsxQ58YxkyELNh/Kz24Nw398B0qSeBJHxzsnuXmI=,tag:7LxrfnAgFGAMzqGi1IpgrQ==,type:str] +#ENC[AES256_GCM,data:HpCu3pN8ViTgEP4AwNAcZ9pLjOyTW+sGDIpYdMc=,iv:uZCxNQ04KiXn7q4LvEKLr1/b+/ubk8WJYePKY9g0ncg=,tag:I4J8R9DmFiAAysmfWGzLtg==,type:comment] +redis_password: ENC[AES256_GCM,data:t2bYWu5jJ6JdTrOzjBqvbVJJSlv4qkFxpSg4eRhRZMyhiq6f+HGff2fsjw==,iv:/7Nbh8acsmoQskdcN8kY3fXRe6jcwK/vC9JLpA18ziY=,tag:bdffnRdvZ7I6heh6DF5qNA==,type:str] +#ENC[AES256_GCM,data:ut++04KnSSYlD3iRzNFhOFaEvZPArHVbSlikhC2VT5jDlfzJ,iv:QVsOoWjr2vFhERCyMs6W/bGWLlj3UJlBCnQ661MG138=,tag:+WvL/AHwqz/0xJoWJHvK9w==,type:comment] +collabora_admin_password: ENC[AES256_GCM,data:E+BD7F6q9PyvU2g+c/66aCw5YR5G5U3BzMCzcBnseWEZt1Sw8W//ka4YMw==,iv:dLW1jkvgD8Ius5p1SFy51Nb7SURvGXF9AuNy6hnd+XM=,tag:WRkpA4PsuYanb2+1Zc2RlA==,type:str] sops: age: - recipient: age170jqy5pg6z62kevadqyxxekw8ryf3e394zaquw0nhs9ae3v9wd6qq2hxnk enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWUXloeEZMcEt4M3kxL3U5 - MXpiU1c4Vy9uTkVDL0R3Rng5N25DZFhPTUhjCllyeU0rbEp0SVFTLzFNUVJscHhv - L1htaUt3S2pJN3NZQ0UwTXpReG9NcnMKLS0tIGpQbnU4SnRyb3RzeCswL2t1d1Vt - aTR0SGowcmdBdE9GV0pDV2hUajR2QzAKZupaPPPAgagGrj88sVZF9/SbmLpZIBJC - EyKmyzi4HR2cb541LVTFY2FCBX3oy6xWbt6omCqnmnymAqD1s8IaTw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFY01lRTJxS0RzcG5ZQTEr + RERPamdvb1pCNlg3cWpRSWpFUHhCUXdrWVJFCmpVN3h6ZXRjdmo0Q3pvRmJzRWxL + Qlc0dUVTWTNuR1JDSUNFMDRaaXljMTgKLS0tIGg1NHVodm9sWkpFL3JacmplZ2p0 + WmhQUnFzSW9HeEh2MWx1NWVKRzFDVWcKVviSyHfzQt7iu3cGp1VExGBVi0zfJ/p1 + YddPTbtm3uzFqHwFRPNDcNwJkZXOY2LO1ouKFFr6W5UubRHaHppeBw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-01-14T13:32:54Z" - mac: ENC[AES256_GCM,data:q0NindbnNfVCnzr7fgvWUPZlk5Dw7rIMhDqCCaOSdYJaJ+gLTbmO1eaG2rA/Q2u7ATYge4AV7rxuAAMk5kws7btzLLJjnZ1pVpmoOGuKV8Py1+6d3Ah7Lzvn4Rgdi3b4VHL5N2e967yodqFRz7WPGoqeHGnjlijYh3/gOYOfmNQ=,iv:UCi3Ar6Vq79RFcY36giDX79fQnq0wPnT1hoBB/JyVhI=,tag:MlqjepPQDl4i1ddYG9o7oA==,type:str] + lastmodified: "2026-01-18T16:02:15Z" + mac: ENC[AES256_GCM,data:7cPJP+ELChBnSiTiio6KkajcF7UrrIrUSrkWtg/AfL7DhN2pLNFxkvvBsuYrYMz4myZ6X2u1YiDl61sEGVMgRu+b9qcqQcQvO35tfXSN1j04Tnvl+T9oKAG+bpBJaAkJrbDTRuIp2OjSdXNPl+KCiZ1ross7QImTNXVeosequdQ=,iv:j20TFApriRHirC5CIY332I8RVq4khRnTcKgJVptx4gI=,tag:80VFem7Dl6gNE/rAEqyKzw==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0 diff --git a/secrets/clients/green.sops.yaml b/secrets/clients/green.sops.yaml new file mode 100644 index 0000000..2d99527 --- /dev/null +++ b/secrets/clients/green.sops.yaml @@ -0,0 +1,38 @@ +#ENC[AES256_GCM,data:SoOe8N8L0Y8Hs6eTkOj4VuImtGdlj+hjCzE=,iv:/X3YVaoaw2Z7C4/54WIgtzeFMrfJfqEoZBGg04FZDoU=,tag:wPgCo8RaPgm/JdcSYo9hug==,type:comment] +#ENC[AES256_GCM,data:AhZkYvipCltGJR01C5imkY/LH2TrVoI/rFQYdGGGqdde6WT5rDo=,iv:ZjFc9moNOtZsYtUBGb1PVVQ25ozflguIYFBF64N073s=,tag:3EcnIRkLo3NMqkzSPXx0zw==,type:comment] +#ENC[AES256_GCM,data:c4qTyE4koVokaohPlnUA0erZyo7Jwg==,iv:GkyGUhDK5vNFD7BB7e3tXTmWS2ydnU+cquwkuCyKD9M=,tag:x7begk8wA2DGRtpcPaIqyw==,type:comment] +client_name: ENC[AES256_GCM,data:/gE8Drw=,iv:Dhich+2Wf+HdfQ5KSWP7kr1e9LYSYCdHRSMwW7fKacI=,tag:8eBTT8al3cwlphaCB0TsJA==,type:str] +client_domain: ENC[AES256_GCM,data:0ZVh+LZFp8V8ZdI3NPxcYdY=,iv:OGyI0i/x9tdXzlA55VcPtNsfBWR/vM6PS0NohWXIUz0=,tag:sN6leHQjyZkFEt0StTDUUA==,type:str] +#ENC[AES256_GCM,data:NSbqmgsxWPxXjMJ5yg1ZErVwkpeU2CA8,iv:bS9eu+DxVOTuADqIunFi8aLeRMy2sB1y+o8i8LF1Ne8=,tag:Bo1LwtqUOSwb3fbhR3o7oA==,type:comment] +authentik_domain: ENC[AES256_GCM,data:sxZ/AT0Vix7+8FVE720041E6bnL76g==,iv:WqTrmrQblmWrKluPKZKQwZ/6AyBmnpGmOdSV6nLYbrk=,tag:Bf1+1Qwe0o31WS0kE0sG0w==,type:str] +authentik_db_password: ENC[AES256_GCM,data:CH1mLJ1U1Wqrc8/Jrl4FJuzSv+yl45fnaYNIOajiFlaBMUsV4c6diQHICg==,iv:Goq3JaDP54Ctzy1gx6ipEk/K4pfZnPKIk8WA+eANSFg=,tag:ocUN4UMCHSgfAvon/DTUOQ==,type:str] +authentik_secret_key: ENC[AES256_GCM,data:9DLYWG5nRg5L1gEv5C7OTDG8LrqnI9PmaRRbkuLsn1Hn+XSjb8MUIpAW2w==,iv:liZ/IuafnT/9mKrmJdDvoZp79lQApoRqxjDXa0i6/9A=,tag:iAqCJ1Ud48Y4fsZuK1EWXQ==,type:str] +#ENC[AES256_GCM,data:uT/yL6SAhzRUIviCCUTvpwxVFk7troc2gvkPyTLU82t48QjNWdDh2uKw8JqzI9w=,iv:T5xSsQRnaSn8eG3t7/dyIxQM8RkX8ja9c/KPltXJuzY=,tag:nz9+AvdMSR6D2r6uPlLsPQ==,type:comment] +authentik_bootstrap_password: ENC[AES256_GCM,data:B1k92cCaF2RBVq5vWRKLBrfnHG0ZXIOPR88YBcAVCT0INfo8wmmsIoHFAQ==,iv:GhFnhbjDieOlzj8O7p84JB+xIDK0iAE5X23TRbxsTLQ=,tag:pma6cPybG1gE+/qAeRihGQ==,type:str] +authentik_bootstrap_token: ENC[AES256_GCM,data:ml4JFuE6B67hCPTBgqHyPwPF5FOXEE9g11EeDyRghtmSFC32M3CjUDckqh/5dg==,iv:K+Cj+u0FrYMWCpH3bpap4ZUdc709hvpuFghSXlYeOTc=,tag:DtXk9bpA5Ksx4MdE1cSWgg==,type:str] +authentik_bootstrap_email: ENC[AES256_GCM,data:k+hDXJzb3i29kg/ceKrLGYWi263n/3A=,iv:t2Ew5E69McmmYmhZfenFwcfhAylGieuS0XCACHQY8QQ=,tag:9HONIHr8apYNMc2HyE/wyQ==,type:str] +#ENC[AES256_GCM,data:QDv++JHvUjsVlHCg5caxbfBkaz63D6WN,iv:9C3gJeOBn/ywu21l5PZYKvSif4CGDl1Vf/kFWoaROXY=,tag:+3iodypQ/Id4V4EdX8TxhA==,type:comment] +nextcloud_domain: ENC[AES256_GCM,data:KeuKtUz/KJKx4pp0ah2o95YlxDKwQlfip1g/,iv:UnLxLMlFvfX7VvIq5h8RizqAxzMF/fSXJ6BESuYsUfw=,tag:sSp93F16f4w9lOL4GxklNQ==,type:str] +nextcloud_admin_user: ENC[AES256_GCM,data:SIqiQHs=,iv:43K1si1+BMNFkkfdGxqnldfE+J9V6IdurUKyyyqqKDI=,tag:tl57gv/5Bit4sw0wLAPcRg==,type:str] +nextcloud_admin_password: ENC[AES256_GCM,data:Nh0+REGEhscg2lnK+SCk9zI/xsX4i9vvkm8/L0bRHZd5ANGPZ3iaOYYDZA==,iv:1iW6iq1OxkeEKELYIC6CX5pEaMvX0/zunnX+JGYmMiQ=,tag:UE85K4QdQ3hVt4IH/C8NnQ==,type:str] +nextcloud_db_password: ENC[AES256_GCM,data:18VDj1nIr3LKYvrTmU/PdsbVURDhZL0+pnT81Lc00ZH36teVABMESrij/Q==,iv:yTtV2GevUvQt/7JcoR46YY10dhiGhD1h9EMBaoBkoUU=,tag:eGh/ytnuPgRw2EKvhPq2Mw==,type:str] +nextcloud_db_root_password: ENC[AES256_GCM,data:TAd9P0Bu5Jj61X1B9FzZVeTEjXcYEhDoTtEcpLLGK0p9L/qy73kyZHgmrQ==,iv:U7j84V3wE+PyT2dDr3Q60iaW5WzzkuuDU1C0z8Sdx/s=,tag:bUJZnkXDDVKIYWiEWKdLgg==,type:str] +#ENC[AES256_GCM,data:CN8A9tXAAkyZs0XcN6YHc2HQv1VfFplr437yC9M=,iv:UT30ox1DXNx18C198/rGekH9fSIUADvAJLbvQhunzng=,tag:GvU3xsudPkskOGlVlzTGyA==,type:comment] +redis_password: ENC[AES256_GCM,data:oy+AjfkYymVjMPtPHAb8nWQ+ck5sWt2S9yWJ0MUp5AUFKzkzpPxVtBf+MA==,iv:x9iu1p8ECtzw/mMS2kHbX9YgIJdOdF+uZIwsWwfNX0A=,tag:VXTQdnKukH6phaCQk2qQWA==,type:str] +#ENC[AES256_GCM,data:YAlGJFpMQBQxOSbp07EnKdNaoZDqzzAppjo4BXtAZbb4mTCx,iv:i8qk8eGR9d8398dTiyTw5eNI3IRk0nGc+hwBEBAuBZQ=,tag:DCSVid0nZij4MkQoII4xyw==,type:comment] +collabora_admin_password: ENC[AES256_GCM,data:rf80B5GB4uOUeYVxQNGpxAYG2ItDVFZyH4/ifmt+F+zdYItYgEiTKHOd+w==,iv:LsNYLtawJjoQr/lqG8Jl+suL6aL3b5TZK+2EmV3uP1Y=,tag:ZIjPtpKekDiKUuh1sKtDog==,type:str] +sops: + age: + - recipient: age170jqy5pg6z62kevadqyxxekw8ryf3e394zaquw0nhs9ae3v9wd6qq2hxnk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhQTBXVVQ1elJaZUhOSU5Z + Y0ZmZG1ZN1I1RG9icHhpWDFKdkFPNnAvb0I0CkpmRVRiSndHYXhzengwY3UxZlZ6 + K2M3K0ZUUzY1TFhvTk1MY241SFhzVkkKLS0tIFViZ2oxeDA5QkgyeGFuK0VaVXYy + Z0dLa3RlSkdPMHQ3NkZXYnY3VEFDMzAKUcPDUoRcHkrn8C7chtc2ARk5sOkF3Gm+ + wmKA4RPvrGtrgp80MVt346H1iA39bDDGCAymZuTTA/81HYCrZ2xUjA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2026-01-18T16:02:23Z" + mac: ENC[AES256_GCM,data:hGJPwiCKhqn/MS76rn6Z/yptYTkOj45yqEjKuoRhZquwm0Vmooxu2BS6EI9THdkdPQV2gNFqklneV9assEiCc73st6koI2lL0OJdhgD80TVfz6kY2f/3Xg06LkQbcbhglhzwzHfo+VLoR/1ZT6JkEj/EJerr2xrEkooc4/y84pI=,iv:b/kcsbNl/cOTvQ9usY71+Lge7rIBoBJx3I7xyulfJ0s=,tag:C1Qz9UFVEAVLmqtyXi8izA==,type:str] + unencrypted_suffix: _unencrypted + version: 3.11.0