Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions .github/workflows/gpgKeys_generation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: GPG Key Generation

on:
workflow_dispatch:
inputs:
reason:
description: 'Reason for generating new GPG key'
required: false
type: string

jobs:
generate-gpg-keys:
runs-on: ubuntu-latest
environment: GpgKeysOHAI

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup GPG
run: |
echo "GPG Version:"
gpg --version
echo "Creating GPG directory..."
mkdir -p ~/.gnupg
chmod 700 ~/.gnupg

- name: Generate GPG Keys
env:
OHAI_GPG_PASSPHRASE: ${{ secrets.OHAI_GPG_PASSPHRASE }}
GPG_KEY_NAME: "New Relic Infrastructure Agent"
GPG_KEY_EMAIL: "infrastructure-eng@newrelic.com"
run: |
chmod +x .github/workflows/scripts/gpgKeys_generation.sh
.github/workflows/scripts/gpgKeys_generation.sh

- name: Verify generated keys
run: |
echo "Verifying generated files..."
ls -lh gpg-*.asc
echo ""
echo "Keys generated successfully!"

- name: Upload private key to GitHub Secrets
env:
GH_TOKEN: ${{ secrets.OHAI_PAT }}
run: |
echo "Installing GitHub CLI..."
type -p gh &> /dev/null || (curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y)

echo "Encoding private key to base64..."
ENCODED_KEY=$(cat gpg-private-key.asc | base64 -w 0)

echo "Creating unique secret name with timestamp..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
SECRET_NAME_TIMESTAMPED="OHAI_GPG_PRIVATE_SHA256_${TIMESTAMP}"
SECRET_NAME_CURRENT="OHAI_GPG_PRIVATE_SHA256"

echo "Uploading to current secret (will be overwritten each time)..."
gh secret set "${SECRET_NAME_CURRENT}" --body "${ENCODED_KEY}" --org newrelic --visibility selected --repos "infrastructure-agent,infrastructure-bundle,infrastructure-publish-action,newrelic-agent-control,infrastructure-public-keys,fluent-bit-package,newrelic-ebpf-agent,nr-control-e2e-testing,newrelic-prometheus-exporters-packages,coreint-automation,nrjmx,nri-discovery-kubernetes"
echo "βœ“ Current key uploaded to: ${SECRET_NAME_CURRENT}"

echo "Uploading to timestamped secret (historical backup)..."
gh secret set "${SECRET_NAME_TIMESTAMPED}" --body "${ENCODED_KEY}" --org newrelic --visibility selected --repos "infrastructure-agent,infrastructure-bundle,infrastructure-publish-action,newrelic-agent-control,infrastructure-public-keys,fluent-bit-package,newrelic-ebpf-agent,nr-control-e2e-testing,newrelic-prometheus-exporters-packages,coreint-automation,nrjmx,nri-discovery-kubernetes"
echo "βœ“ Backup key uploaded to: ${SECRET_NAME_TIMESTAMPED}"

echo ""
echo "Summary:"
echo " - Current/Active: ${SECRET_NAME_CURRENT} (overwritten)"
echo " - Historical Backup: ${SECRET_NAME_TIMESTAMPED} (new)"

- name: Export GPG key in binary format
run: |
echo "Getting Key ID..."
KEY_ID=$(gpg --list-keys --with-colons "infrastructure-eng@newrelic.com" | awk -F: '/^pub:/ {print $5}' | head -n 1)
echo "Key ID: ${KEY_ID}"

echo "Exporting public key in .gpg binary format..."
gpg --export "${KEY_ID}" > public-key.gpg
ls -lh public-key.gpg
echo "βœ“ Binary GPG key exported"

- name: Copy public keys to gpg/keys folder
run: |
echo "Getting Key ID..."
KEY_ID=$(gpg --list-keys --with-colons "infrastructure-eng@newrelic.com" | awk -F: '/^pub:/ {print $5}' | head -n 1)
echo "Key ID: ${KEY_ID}"

echo "Creating directory structure if it doesn't exist..."
mkdir -p gpg/keys/new
mkdir -p gpg/keys/current

echo "Creating timestamp for backup..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

echo "Exporting current RPM key (will be overwritten each time)..."
gpg --armor --export "${KEY_ID}" > gpg/keys/current/newrelic_rpm_key_current.gpg

echo "Exporting timestamped RPM key (historical backup)..."
gpg --armor --export "${KEY_ID}" > gpg/keys/new/newrelic_rpm_key_${TIMESTAMP}.gpg

echo "Generated keys:"
echo "Current key (overwritten):"
ls -lh gpg/keys/current/newrelic_rpm_key_current.gpg
echo "Timestamped backup:"
ls -lh gpg/keys/new/newrelic_rpm_key_${TIMESTAMP}.gpg
echo "βœ“ Public RPM keys exported in ASCII-armored format"

- name: Commit public keys to repository
env:
GH_TOKEN: ${{ secrets.OHAI_PAT }}
run: |
echo "Configuring git..."
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

echo "Adding generated keys..."
git add gpg/keys/current/newrelic_rpm_key_current.gpg
git add gpg/keys/new/newrelic_rpm_key_*.gpg

echo "Committing changes..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
REASON="${{ github.event.inputs.reason }}"
if [ -n "$REASON" ]; then
git commit -m "Add generated GPG public keys: current (overwritten) and backup (${TIMESTAMP})" -m "Reason: ${REASON}" || echo "No changes to commit"
else
git commit -m "Add generated GPG public keys: current (overwritten) and backup (${TIMESTAMP})" || echo "No changes to commit"
fi

echo "Pushing to repository..."
git push

echo "βœ“ Public RPM key committed to gpg/keys/new/ folder"
echo "βœ“ File available at: gpg/keys/new/newrelic_rpm_key_new.gpg"

- name: Cleanup sensitive files
if: always()
run: |
echo "Securely removing private key files..."

# Use shred to overwrite the file multiple times before removal
if [ -f "gpg-private-key.asc" ]; then
echo "Shredding gpg-private-key.asc..."
shred -vfz -n 10 gpg-private-key.asc
rm -f gpg-private-key.asc
echo "βœ“ gpg-private-key.asc securely removed"
fi

# Also clean up the GPG batch config if it exists
if [ -f "gpg-batch-config.txt" ]; then
echo "Shredding gpg-batch-config.txt..."
shred -vfz -n 10 gpg-batch-config.txt
rm -f gpg-batch-config.txt
echo "βœ“ gpg-batch-config.txt securely removed"
fi

# Verify files are removed
echo "Verifying cleanup..."
if [ -f "gpg-private-key.asc" ] || [ -f "gpg-batch-config.txt" ]; then
echo "⚠ Warning: Some sensitive files still exist!"
exit 1
else
echo "βœ“ All sensitive files successfully removed"
fi

46 changes: 46 additions & 0 deletions .github/workflows/scripts/gpgKeys_generation.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash
set -e

# Configuration
NAME_REAL="${GPG_KEY_NAME:-New Relic Infrastructure Agent}"
NAME_EMAIL="${GPG_KEY_EMAIL:-infrastructure-eng@newrelic.com}"
PASSPHRASE="${OHAI_GPG_PASSPHRASE}"

echo "Generating GPG key with SHA256..."

# Create GPG batch configuration
cat > gpg-batch-config.txt <<EOF
Key-Type: RSA
Key-Length: 4096
Key-Usage: sign
Subkey-Type: RSA
Subkey-Length: 4096
Subkey-Usage: encrypt
Name-Real: ${NAME_REAL}
Name-Email: ${NAME_EMAIL}
Expire-Date: 0
Passphrase: ${PASSPHRASE}
Preferences: SHA256 SHA384 SHA512 AES256 AES192 AES
%commit
EOF

# Generate the key
gpg --batch --generate-key gpg-batch-config.txt

# Get the key ID
KEY_ID=$(gpg --list-keys --with-colons "${NAME_EMAIL}" | awk -F: '/^pub:/ {print $5}' | head -n 1)

echo "Key ID: ${KEY_ID}"

# Export keys with passphrase
gpg --batch --pinentry-mode loopback --passphrase "${PASSPHRASE}" --armor --export-secret-keys "${KEY_ID}" > gpg-private-key.asc
gpg --armor --export "${KEY_ID}" > gpg-public-key.asc

# Clean up
rm -f gpg-batch-config.txt

echo "βœ“ GPG keys generated successfully with SHA256"
echo " Email: ${NAME_EMAIL}"
echo " Expiration: Never"
echo " Private key: gpg-private-key.asc"
echo " Public key: gpg-public-key.asc"
52 changes: 52 additions & 0 deletions gpg/keys/new/newrelic_rpm_key_new.gpg
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

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
C3nIejRUROsJ5mIEC5Ey92Bllsk=
=YD+n
-----END PGP PUBLIC KEY BLOCK-----
Loading