diff --git a/.github/workflows/copy-source-to-repo.yaml b/.github/workflows/copy-source-to-repo.yaml index f69e389..15ab370 100644 --- a/.github/workflows/copy-source-to-repo.yaml +++ b/.github/workflows/copy-source-to-repo.yaml @@ -3,7 +3,8 @@ name: Copy Source To Repo # Reusable sync-to-mirror job (port of pipeline-library's # copy-source-to-repo.yml / infrastructure-modules' sync-customer-modules): # rsync the paths listed in a path-list file into a target repository, -# commit as the CI bot (GPG-signed), tag with the given version, and push. +# commit as the CI bot (SSH-signed, per the armor bot convention), tag with +# the given version, and push over HTTPS with the bot's token. # Content synced by this workflow should be validated in the SOURCE repo # before release — the mirror receives it as-is. @@ -33,22 +34,20 @@ on: required: false type: string default: '' - gpg_key_id: - description: Fingerprint of the CI bot signing key. + committer_name: + description: Committer name for the bot commits. required: false type: string - default: 5DEFE5F42550F28A17F9B83AC7E6D88B99BC6D9D - gpg_key_subject: - description: Committer email matching the signing key. + default: mdr-autodeploy-dev + committer_email: + description: Committer email for the bot commits (must be verified on the bot account for the Verified badge). required: false type: string - default: ci@quantum.security + default: mdr-autodeploy-dev@armor.com secrets: - IMPORT_GPG_KEY: + GIT_TOKEN_BASIC: required: true - IMPORT_GPG_KEY_PASSPHRASE: - required: true - QUANTUM_CI_BOT_GITHUB_SSH_KEY: + CI_BOT_SSH_KEY: required: true jobs: @@ -60,7 +59,8 @@ jobs: SOURCE_ORG: ${{ inputs.source_org }} PATH_LIST_FILE: ${{ inputs.path_list_file }} SYNC_VERSION: ${{ inputs.version }} - GPG_KEY_SUBJECT: ${{ inputs.gpg_key_subject }} + COMMITTER_NAME: ${{ inputs.committer_name }} + COMMITTER_EMAIL: ${{ inputs.committer_email }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -72,30 +72,23 @@ jobs: exit 1 fi - - name: Import GPG key + - name: Configure SSH commit signing env: - GPG_KEY_BASE64: ${{ secrets.IMPORT_GPG_KEY }} - GPG_PASSPHRASE: ${{ secrets.IMPORT_GPG_KEY_PASSPHRASE }} - GPG_KEY_ID: ${{ inputs.gpg_key_id }} - run: | - echo "$GPG_KEY_BASE64" | base64 -d | gpg --batch --yes --no-tty --always-trust --import - echo "ENCRYPTION_TEST" | gpg --always-trust --encrypt --recipient "$GPG_KEY_SUBJECT" > temp.encrypted - gpg --batch --yes --no-tty --decrypt --passphrase "$GPG_PASSPHRASE" --pinentry-mode loopback --always-trust temp.encrypted - rm -f temp.encrypted - git config --global user.signingkey "$GPG_KEY_ID" - git config --global commit.gpgsign true - - - name: Setup SSH key - env: - SSH_KEY: ${{ secrets.QUANTUM_CI_BOT_GITHUB_SSH_KEY }} + SSH_SIGNING_KEY: ${{ secrets.CI_BOT_SSH_KEY }} run: | mkdir -p ~/.ssh - echo "$SSH_KEY" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan github.com >> ~/.ssh/known_hosts + echo "$SSH_SIGNING_KEY" > ~/.ssh/signing_key + chmod 600 ~/.ssh/signing_key + git config --global gpg.format ssh + git config --global user.signingkey ~/.ssh/signing_key + git config --global commit.gpgsign true + git config --global user.name "$COMMITTER_NAME" + git config --global user.email "$COMMITTER_EMAIL" - name: Clone target repository - run: git clone "git@github.com:${SOURCE_ORG}/${TARGET_REPOSITORY}.git" + env: + GIT_TOKEN: ${{ secrets.GIT_TOKEN_BASIC }} + run: git clone "https://x-access-token:${GIT_TOKEN}@github.com/${SOURCE_ORG}/${TARGET_REPOSITORY}.git" - name: Sync paths run: | @@ -109,8 +102,6 @@ jobs: COMMIT_MESSAGE: ${{ inputs.commit_message }} run: | cd "$TARGET_REPOSITORY" - git config user.email "$GPG_KEY_SUBJECT" - git config user.name "Quantum CI Bot" MESSAGE="${COMMIT_MESSAGE:-Import updates from ${GITHUB_REPOSITORY#*/}@${SYNC_VERSION} (patch)}" git add -A git commit --allow-empty -m "$MESSAGE" diff --git a/.github/workflows/import-release-content.yaml b/.github/workflows/import-release-content.yaml index 0b267c6..4c1fd5b 100644 --- a/.github/workflows/import-release-content.yaml +++ b/.github/workflows/import-release-content.yaml @@ -42,6 +42,16 @@ on: required: false type: string default: master + committer_name: + description: Committer name for the import commits. + required: false + type: string + default: mdr-autodeploy-dev + committer_email: + description: Committer email for the import commits. + required: false + type: string + default: mdr-autodeploy-dev@armor.com secrets: GIT_TOKEN_BASIC: required: true @@ -252,8 +262,8 @@ jobs: env: RELEASE_VERSION: ${{ steps.release.outputs.version }} run: | - git config user.email "ci@quantum.security" - git config user.name "Quantum CI Bot" + git config user.email "${{ inputs.committer_email }}" + git config user.name "${{ inputs.committer_name }}" # Check if there are actual changes to commit git add "$DESTINATION" diff --git a/.github/workflows/update-source-reference.yaml b/.github/workflows/update-source-reference.yaml index d1da23c..832d9c6 100644 --- a/.github/workflows/update-source-reference.yaml +++ b/.github/workflows/update-source-reference.yaml @@ -2,14 +2,16 @@ name: Update Source Reference # Reusable port of pipeline-library's update-source-reference.yml: after a # package release, rewrite the package's `?ref=` pins in the target repo -# (default: infrastructure-modules). Minor/patch bumps push directly to the -# default branch as GPG-signed bot commits; major bumps go via a feature +# (default: mdr-infrastructure-modules). Minor/patch bumps push directly to +# the default branch as SSH-signed bot commits; major bumps go via a feature # branch + PR for human review. # -# Hardening carried from the TRU-327/342 security review: strict-semver guard -# on the tag-derived version, no shell tracing (consumers are public repos -# with world-readable logs), least-privilege GITHUB_TOKEN (all pushes -# authenticate via GIT_TOKEN_BASIC / SSH). +# Bot identity follows the armor convention: commits are signed with the CI +# bot's SSH key (git gpg.format=ssh) and pushed over HTTPS with the bot's +# token — no GPG keyring, no SSH transport. Hardening carried from the +# TRU-327/342 security review: strict-semver guard on the tag-derived +# version, no shell tracing (consumers are public repos with world-readable +# logs), least-privilege GITHUB_TOKEN. on: workflow_call: @@ -33,24 +35,20 @@ on: required: false type: string default: master - gpg_key_id: - description: Fingerprint of the CI bot signing key. + committer_name: + description: Committer name for the bot commits. required: false type: string - default: 5DEFE5F42550F28A17F9B83AC7E6D88B99BC6D9D - gpg_key_subject: - description: Committer email matching the signing key. + default: mdr-autodeploy-dev + committer_email: + description: Committer email for the bot commits (must be verified on the bot account for the Verified badge). required: false type: string - default: ci@quantum.security + default: mdr-autodeploy-dev@armor.com secrets: GIT_TOKEN_BASIC: required: true - IMPORT_GPG_KEY: - required: true - IMPORT_GPG_KEY_PASSPHRASE: - required: true - QUANTUM_CI_BOT_GITHUB_SSH_KEY: + CI_BOT_SSH_KEY: required: true jobs: @@ -62,7 +60,8 @@ jobs: TARGET_REPOSITORY: ${{ inputs.target_repository }} SOURCE_ORG: ${{ inputs.source_org }} DEFAULT_BRANCH: ${{ inputs.default_branch }} - GPG_KEY_SUBJECT: ${{ inputs.gpg_key_subject }} + COMMITTER_NAME: ${{ inputs.committer_name }} + COMMITTER_EMAIL: ${{ inputs.committer_email }} steps: - name: Checkout code uses: actions/checkout@v4 @@ -99,27 +98,18 @@ jobs: echo "LATEST_VERSION=$LATEST_VERSION" >> "$GITHUB_ENV" echo "VERSION_CHANGED=$VERSION_CHANGED" >> "$GITHUB_ENV" - - name: Import GPG key + - name: Configure SSH commit signing env: - GPG_KEY_BASE64: ${{ secrets.IMPORT_GPG_KEY }} - GPG_PASSPHRASE: ${{ secrets.IMPORT_GPG_KEY_PASSPHRASE }} - GPG_KEY_ID: ${{ inputs.gpg_key_id }} - run: | - echo "$GPG_KEY_BASE64" | base64 -d | gpg --batch --yes --no-tty --always-trust --import - echo "ENCRYPTION_TEST" | gpg --always-trust --encrypt --recipient "$GPG_KEY_SUBJECT" > temp.encrypted - gpg --batch --yes --no-tty --decrypt --passphrase "$GPG_PASSPHRASE" --pinentry-mode loopback --always-trust temp.encrypted - rm -f temp.encrypted - git config --global user.signingkey "$GPG_KEY_ID" - git config --global commit.gpgsign true - - - name: Setup SSH key - env: - SSH_KEY: ${{ secrets.QUANTUM_CI_BOT_GITHUB_SSH_KEY }} + SSH_SIGNING_KEY: ${{ secrets.CI_BOT_SSH_KEY }} run: | mkdir -p ~/.ssh - echo "$SSH_KEY" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan github.com >> ~/.ssh/known_hosts + echo "$SSH_SIGNING_KEY" > ~/.ssh/signing_key + chmod 600 ~/.ssh/signing_key + git config --global gpg.format ssh + git config --global user.signingkey ~/.ssh/signing_key + git config --global commit.gpgsign true + git config --global user.name "$COMMITTER_NAME" + git config --global user.email "$COMMITTER_EMAIL" - name: Update source references env: @@ -129,9 +119,7 @@ jobs: # No shell tracing: consumers are public repos, so Actions logs are # world-readable — keep output to the deliberate echoes only. set -e - git config --global user.email "$GPG_KEY_SUBJECT" - git config --global user.name "Quantum CI Bot" - git clone "git@github.com:${SOURCE_ORG}/${TARGET_REPOSITORY}.git" + git clone "https://x-access-token:${GITHUB_TOKEN}@github.com/${SOURCE_ORG}/${TARGET_REPOSITORY}.git" pushd "./${TARGET_REPOSITORY}" IFS='.' read -r -a current <<< "$LATEST_VERSION" current_major="${current[0]}" diff --git a/README.md b/README.md index f0964b2..cf6c3d3 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Reusable GitHub workflows shared by Quantum repositories. | `terragrunt-validation.yaml` | Pre-commit for terragrunt-based repos; optional `changed_files_only` mode. | | `strict-yaml-validation.yaml` | Strict YAML scan of a directory (duplicate keys rejected). | | `semantic-release.yaml` | Runs semantic-release on the consumer's release stack; outputs `semver` (empty when no release was created). Optional `release_artifact` input downloads a same-run workflow artifact before releasing. | -| `update-source-reference.yaml` | After a package release, rewrite the package's `?ref=` pins in a target repository. Minor/patch → direct push; major → feature branch + PR. | +| `update-source-reference.yaml` | After a package release, rewrite the package's `?ref=` pins in a target repository. Minor/patch → direct SSH-signed push; major → feature branch + PR. | | `import-release-content.yaml` | Import a release asset: download, validate everything it adds or changes, update the version pointer and changelog, commit. | | `copy-source-to-repo.yaml` | Sync the paths in a path-list file into a mirror repository and tag the version. | | `repository-dispatch.yaml` | Send a version-carrying `repository_dispatch` event to a downstream repository. |