diff --git a/.forgejo/workflows/build-secrets-backup-image.yml b/.forgejo/workflows/build-secrets-backup-image.yml new file mode 100644 index 0000000..4f5185f --- /dev/null +++ b/.forgejo/workflows/build-secrets-backup-image.yml @@ -0,0 +1,35 @@ +name: Build secrets-backup image + +on: + push: + paths: + - 'build/secrets-backup/Dockerfile' + branches: + - main + workflow_dispatch: + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Log in to registry + run: | + echo "${{ secrets.PACKAGES_TOKEN }}" | \ + docker login edp.buildth.ing \ + -u "${{ env.FORGEJO_REPOSITORY_OWNER }}" \ + --password-stdin + + - name: Build image + run: | + docker build \ + -t edp.buildth.ing/devfw-cicd/secrets-backup:1.0.1 \ + -t edp.buildth.ing/devfw-cicd/secrets-backup:latest \ + build/secrets-backup/ + + - name: Push image + run: | + docker push edp.buildth.ing/devfw-cicd/secrets-backup:1.0.1 + docker push edp.buildth.ing/devfw-cicd/secrets-backup:latest diff --git a/build/secrets-backup/Dockerfile b/build/secrets-backup/Dockerfile new file mode 100644 index 0000000..fa560d7 --- /dev/null +++ b/build/secrets-backup/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine/k8s:1.32.0 +# No extra packages needed — kubectl and aws CLI are bundled in alpine/k8s +# OBS SSE-KMS handles encryption at rest; no openssl required diff --git a/template/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml b/template/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml index aafcf84..5ea260d 100644 --- a/template/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml +++ b/template/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml @@ -29,17 +29,6 @@ roleRef: name: secrets-backup-reader apiGroup: rbac.authorization.k8s.io --- -apiVersion: v1 -kind: Secret -metadata: - name: secrets-backup-config - namespace: gitea -type: Opaque -stringData: - # IMPORTANT: Replace this placeholder with a strong passphrase per environment. - # This secret should be managed via external-secrets or manually set after initial deploy. - encryption-passphrase: "CHANGE-ME-SET-PER-ENVIRONMENT" ---- apiVersion: batch/v1 kind: CronJob metadata: @@ -61,7 +50,7 @@ spec: serviceAccountName: secrets-backup containers: - name: secrets-backup - image: alpine/k8s:1.32.0 + image: edp.buildth.ing/devfw-cicd/secrets-backup:1.0.1 imagePullPolicy: IfNotPresent env: - name: AWS_ACCESS_KEY_ID @@ -74,11 +63,6 @@ spec: secretKeyRef: name: forgejo-cloud-credentials key: secret-key - - name: ENCRYPTION_PASSPHRASE - valueFrom: - secretKeyRef: - name: secrets-backup-config - key: encryption-passphrase - name: SOURCE_BUCKET valueFrom: secretKeyRef: @@ -92,9 +76,6 @@ spec: - | set -euo pipefail - # Ensure openssl is available (not bundled in alpine/k8s image) - apk add --no-cache openssl --quiet - TIMESTAMP=$(date +%Y%m%d-%H%M%S) BACKUP_DIR="/tmp/secrets-backup-${TIMESTAMP}" NAMESPACES="argocd cert-manager external-secrets" @@ -110,20 +91,14 @@ spec: > "${BACKUP_DIR}/${NS}-secrets.json" done - echo "=== Encrypting backup with AES-256-CBC ===" + echo "=== Creating compressed archive ===" ARCHIVE="${BACKUP_DIR}/secrets-backup-${TIMESTAMP}.tar.gz" tar -czf "${ARCHIVE}" -C "${BACKUP_DIR}" \ $(ls "${BACKUP_DIR}"/*.json 2>/dev/null | xargs -n1 basename) - ENCRYPTED="${BACKUP_DIR}/secrets-backup-${TIMESTAMP}.tar.gz.enc" - openssl enc -aes-256-cbc -salt -pbkdf2 -iter 100000 \ - -in "${ARCHIVE}" \ - -out "${ENCRYPTED}" \ - -pass env:ENCRYPTION_PASSPHRASE - - echo "=== Uploading to OBS ===" - aws s3 cp "${ENCRYPTED}" \ - "s3://${SOURCE_BUCKET}/cluster-secrets-backup/${TIMESTAMP}/secrets-backup.tar.gz.enc" \ + echo "=== Uploading to OBS (SSE-KMS encryption at rest) ===" + aws s3 cp "${ARCHIVE}" \ + "s3://${SOURCE_BUCKET}/cluster-secrets-backup/${TIMESTAMP}/secrets-backup.tar.gz" \ --endpoint-url "https://${OBS_ENDPOINT}" echo "=== Cleanup ==="