verify-tag Git Command Guide
The git verify-tag command validates GPG signatures on Git tags to ensure they were created by the claimed author and haven’t been tampered with. It’s essential for maintaining the integrity and authenticity of release tags and version markers in security-conscious environments.
git verify-tag Syntax:
Section titled “git verify-tag Syntax:”git verify-tag [--raw] [-v | --verbose] [-q | --quiet] [--keyid-format=<format>] [--gpg-program=<gpg-program>] [--gpg-default-key=<key>] [--gpg-home-dir=<dir>] [--gpg-ssh-allowed-signers=<file>] [--gpg-ssh-default-key=<key>] [--gpg-ssh-program=<program>] <tag>...Verification Options:
Section titled “Verification Options:”| Option | Description |
|---|---|
--raw | Print raw GPG status output |
-v, --verbose | Verbose output |
-q, --quiet | Suppress output |
--keyid-format=<format> | Key ID display format (short, long, etc.) |
GPG Configuration Options:
Section titled “GPG Configuration Options:”| Option | Description |
|---|---|
--gpg-program=<program> | Use custom GPG program |
--gpg-default-key=<key> | Default GPG key |
--gpg-home-dir=<dir> | GPG home directory |
--gpg-ssh-allowed-signers=<file> | SSH allowed signers file |
--gpg-ssh-default-key=<key> | Default SSH key |
--gpg-ssh-program=<program> | SSH signing program |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<tag> | Tag(s) to verify (name, SHA-1, etc.) |
Understanding Tag Verification:
Section titled “Understanding Tag Verification:”Tag Signature Process:
Section titled “Tag Signature Process:”Tag Signing and Verification:├── Tag Creation: Developer creates annotated tag with message├── GPG Signing: Tag SHA-1 signed with private key├── Signature Storage: Signature embedded in tag object├── Verification: Public key used to verify signature├── Trust Validation: Key trustworthiness confirmed└── Integrity Check: Tag content matches signed hashTag Types and Signatures:
Section titled “Tag Types and Signatures:”Tag Object Structure:├── Lightweight Tags: Simple refs to commits (no signature)├── Annotated Tags: Full objects with metadata and signatures├── Signed Tags: Annotated tags with GPG/SSH signatures├── Verification Scope: Message, timestamp, tagger, target commit└── Trust Chain: Key validity, signature validity, content integritySignature Verification States:
Section titled “Signature Verification States:”Tag Signature Results:├── GOOD: Valid signature from trusted key├── BAD: Invalid signature or tampered content├── EXPIRED: Key or signature has expired├── REVOKED: Signing key has been revoked├── UNKNOWN: Key not in keyring or untrusted└── NO_PUBKEY: Public key not availableBasic Verify-Tag Operations:
Section titled “Basic Verify-Tag Operations:”Verify Single Tag:
Section titled “Verify Single Tag:”# Verify specific taggit verify-tag v1.0
# Verify latest taggit verify-tag $(git describe --tags --abbrev=0)
# Verify multiple tagsgit verify-tag v1.0 v2.0 v3.0
# Verify tag by SHA-1git verify-tag abc123def456Verify All Tags:
Section titled “Verify All Tags:”# Verify all tags in repositorygit tag | xargs git verify-tag
# Verify recent tags onlygit tag --sort=-version:refname | head -5 | xargs git verify-tag
# Verify tags from specific patterngit tag | grep "^v[0-9]" | xargs git verify-tagDetailed Verification Output:
Section titled “Detailed Verification Output:”# Verbose verification with detailsgit verify-tag -v v1.0
# Raw GPG output for debugginggit verify-tag --raw v1.0
# Quiet verification (exit code only)git verify-tag -q v1.0Advanced Verify-Tag Scenarios:
Section titled “Advanced Verify-Tag Scenarios:”Batch Tag Verification:
Section titled “Batch Tag Verification:”# Verify all tags with status reportingverify_all_tags() { echo "Verifying all tags in repository..."
git tag | while read -r tag; do if git verify-tag -q "$tag" 2>/dev/null; then echo "✓ $tag" else echo "✗ $tag" fi done}
# Verify tags by contributorverify_contributor_tags() { local contributor="$1"
echo "Verifying tags created by $contributor..."
git tag --format="%(refname:short) %(creator)" | while read -r tag creator; do if [[ "$creator" == *"$contributor"* ]]; then if git verify-tag -q "$tag" 2>/dev/null; then echo "✓ $tag" else echo "✗ $tag" fi fi done}
# Usageverify_contributor_tags "John Doe"Tag Chain Verification:
Section titled “Tag Chain Verification:”# Verify tag chronological chainverify_tag_chain() { echo "Verifying tag chronological chain..."
# Get tags sorted by creation date git tag --sort=creatordate --format="%(refname:short) %(creatordate)" | while read -r tag date; do echo "Verifying $tag (created: $date)..."
if git verify-tag -q "$tag" 2>/dev/null; then echo " ✓ Signature valid"
# Check if tag points to valid commit commit=$(git rev-parse "$tag^{commit}") if git cat-file -e "$commit" 2>/dev/null; then echo " ✓ Points to valid commit: $commit" else echo " ✗ Points to invalid commit: $commit" fi else echo " ✗ Signature invalid" fi echo done}
# Verify release tag sequenceverify_release_sequence() { echo "Verifying release tag sequence..."
git tag --sort=version:refname | grep "^v" | while read -r tag; do echo "Checking $tag..."
# Verify signature if ! git verify-tag -q "$tag" 2>/dev/null; then echo " ✗ Invalid signature" continue fi
# Check version ordering version=$(echo "$tag" | sed 's/^v//') # Additional version validation logic here
echo " ✓ Valid release tag" done}Key Management Integration:
Section titled “Key Management Integration:”# Verify tags with specific key requirementsverify_with_key_policy() { local required_key="$1"
echo "Verifying tags with key policy: $required_key"
git tag | while read -r tag; do echo "Checking $tag..."
# Get signature details sig_info=$(git verify-tag --raw "$tag" 2>&1 | grep -E "(VALIDSIG|ERRSIG)")
if [[ "$sig_info" == *"$required_key"* ]]; then echo " ✓ Signed with required key" else echo " ✗ Not signed with required key" echo " Required: $required_key" echo " Found: $sig_info" fi done}
# Check key validity for tag signerscheck_signer_key_validity() { echo "Checking validity of keys used for tag signing..."
git tag | while read -r tag; do # Extract signing key from raw output key_id=$(git verify-tag --raw "$tag" 2>&1 | grep "VALIDSIG" | awk '{print $3}')
if [ -n "$key_id" ]; then echo "Tag $tag signed with key: $key_id"
# Check key validity if gpg --list-keys "$key_id" >/dev/null 2>&1; then echo " ✓ Key exists in keyring"
# Check expiration if gpg --list-keys --with-colons "$key_id" | grep -q "^pub:e:"; then echo " ✗ Key has expired" else echo " ✓ Key is valid" fi else echo " ✗ Key not found in keyring" fi else echo "Tag $tag is not signed" fi echo done}
# Usageverify_with_key_policy "ABC123DEF456"check_signer_key_validityConfiguration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for Tag Verification:
Section titled “Git Configuration for Tag Verification:”# Configure GPG for tag signinggit config --global user.signingkey "ABC123DEF456"git config --global tag.gpgsign true
# Configure GPG programgit config --global gpg.program "gpg"git config --global gpg.ssh.program "ssh-keygen"
# Configure key display formatgit config --global verify.keyidformat "long"
# Configure SSH signinggit config --global gpg.ssh.allowedSignersFile "~/.ssh/allowed_signers"git config --global gpg.ssh.defaultKeyCommand "ssh-add -L"GPG Key Setup for Tags:
Section titled “GPG Key Setup for Tags:”# Generate GPG key for tag signinggenerate_gpg_key() { echo "Generating GPG key for tag signing..."
# Generate key (interactive) gpg --full-generate-key
# List keys gpg --list-secret-keys --keyid-format LONG
# Export public key echo "Export your public key:" echo "gpg --armor --export YOUR_KEY_ID" echo "Share with team members for tag verification"}
# Setup SSH signing for tagssetup_ssh_signing() { echo "Setting up SSH signing for tags..."
# Generate SSH key for signing ssh-keygen -t ed25519 -C "git-tag-signing" -f ~/.ssh/tag_signing_key
# Configure allowed signers echo "$(git config user.email) $(cat ~/.ssh/tag_signing_key.pub)" >> ~/.ssh/allowed_signers
# Configure Git to use SSH signing git config --global gpg.ssh.defaultKeyCommand "ssh-add -L ~/.ssh/tag_signing_key" git config --global gpg.format ssh git config --global tag.gpgsign true}
# Import team member keyssetup_team_keys() { echo "Setting up team GPG keys for tag verification..."
# Import keys from keyserver gpg --keyserver hkps://keys.openpgp.org --recv-keys KEY_ID_1 KEY_ID_2
# Import from files gpg --import team-member-1.asc team-member-2.asc
# Sign imported keys (establish trust) gpg --sign-key KEY_ID_1 gpg --sign-key KEY_ID_2
echo "Team keys imported and signed"}Safe Tag Verification Operations:
Section titled “Safe Tag Verification Operations:”# Safe tag verification with error handlingsafe_verify_tag() { local tag="$1"
echo "Verifying tag: $tag"
# Check if tag exists if ! git show-ref --verify "refs/tags/$tag" >/dev/null 2>&1; then echo "Error: Tag $tag does not exist" return 1 fi
# Attempt verification if git verify-tag -q "$tag" 2>/dev/null; then echo "✓ Tag signature is valid" return 0 else echo "✗ Tag signature verification failed" return 1 fi}
# Batch verification with progressbatch_verify_tags() { local tag_count tag_count=$(git tag | wc -l) local current=0
echo "Batch verifying $tag_count tags..."
git tag | while read -r tag; do ((current++)) echo -n "[$current/$tag_count] Verifying $tag... "
if safe_verify_tag "$tag" >/dev/null 2>&1; then echo "✓" else echo "✗" fi done
echo "Batch verification complete"}
# Usagebatch_verify_tagsIntegration with Development Workflows:
Section titled “Integration with Development Workflows:”CI/CD Pipeline Integration:
Section titled “CI/CD Pipeline Integration:”# Verify tags in CI/CD pipelinesci_tag_verification() { echo "=== CI/CD Tag Verification ==="
# Verify release tags verify_release_tags() { echo "Verifying release tags..."
# Get release tags from current branch git tag --merged HEAD | grep "^v[0-9]" | while read -r tag; do echo "Verifying release tag $tag"
if git verify-tag -q "$tag" 2>/dev/null; then echo "✓ Signature valid"
# Additional validation tag_commit=$(git rev-parse "$tag^{commit}") echo " Points to commit: $tag_commit"
# Check tag message tag_message=$(git tag -l --format="%(contents)" "$tag") if [ -n "$tag_message" ]; then echo " ✓ Has annotation" else echo " ⚠ Lightweight tag" fi else echo "✗ Signature invalid - rejecting release" exit 1 fi done
echo "All release tags verified" }
# Setup tag signing requirement setup_tag_signing() { echo "Setting up tag signing requirements..."
# Configure Git to require signing git config --global tag.gpgsign true
# Setup pre-push hook cat > .git/hooks/pre-push << 'EOF'#!/bin/bash# Require tag signing for pushes
zero_commit="0000000000000000000000000000000000000000"
while read -r local_ref local_sha remote_ref remote_sha; do # Check if pushing tags if [[ "$local_ref" == refs/tags/* ]]; then tag_name="${local_ref#refs/tags/}" echo "Verifying tag signature for $tag_name..."
if ! git verify-tag -q "$tag_name" 2>/dev/null; then echo "ERROR: Tag $tag_name is not signed" echo "Please sign your tags before pushing." exit 1 fi
echo "✓ Tag $tag_name is properly signed" fidone
echo "Pre-push tag verification complete"EOF
chmod +x .git/hooks/pre-push
echo "Tag signing requirement configured" }
# Generate tag verification report generate_tag_report() { echo "Generating tag verification status report..."
cat > tag-verification-report.md << EOF# Tag Verification Status Report
Generated: $(date)Repository: $(basename "$(pwd)")Branch: $(git branch --show-current)
## Tag StatisticsEOF
total_tags=$(git tag | wc -l) signed_tags=$(git tag | while read -r tag; do git verify-tag -q "$tag" 2>/dev/null && echo "$tag"; done | wc -l) unsigned_tags=$((total_tags - signed_tags))
echo "- Total tags: $total_tags" >> tag-verification-report.md echo "- Signed tags: $signed_tags" >> tag-verification-report.md echo "- Unsigned tags: $unsigned_tags" >> tag-verification-report.md echo "- Signing rate: $((signed_tags * 100 / total_tags))%" >> tag-verification-report.md
cat >> tag-verification-report.md << EOF
## Recent Tag Signing Status$(git tag --sort=-creatordate | head -10 | while read -r tag; do if git verify-tag -q "$tag" 2>/dev/null; then echo "- ✓ $tag" else echo "- ✗ $tag" fidone)
## RecommendationsEOF
if [ "$unsigned_tags" -gt 0 ]; then echo "- Enable tag signing: \`git config tag.gpgsign true\`" >> tag-verification-report.md echo "- Setup GPG key for signing" >> tag-verification-report.md fi
echo "Tag verification report generated: tag-verification-report.md" }
# Run CI/CD verification verify_release_tags generate_tag_report}
# Usage in CIci_tag_verificationRepository Security Auditing:
Section titled “Repository Security Auditing:”# Audit repository for signed tagsaudit_tag_signing() { echo "=== Repository Tag Signing Audit ==="
# Analyze signing coverage analyze_signing_coverage() { echo "Analyzing tag signing coverage..."
declare -A signer_stats
git tag --format="%(refname:short) %(creator)" | while read -r tag creator; do if git verify-tag -q "$tag" 2>/dev/null; then signer_stats["$creator"]=$((signer_stats["$creator"] + 1)) fi done
echo "Signing coverage by creator:" for creator in "${!signer_stats[@]}"; do echo " $creator: ${signer_stats[$creator]} signed tags" done }
# Find unsigned tags find_unsigned_tags() { echo "Finding unsigned tags..."
git tag | while read -r tag; do if ! git verify-tag -q "$tag" 2>/dev/null; then echo "Unsigned tag: $tag" # Show tag details git tag -l "$tag" echo fi done }
# Check tag signing key rotation check_key_rotation() { echo "Checking tag signing key rotation..."
git tag --sort=creatordate --format="%(refname:short) %(creatordate)" | while read -r tag date; do if git verify-tag -q "$tag" 2>/dev/null; then # Extract key info (simplified) key_info=$(git verify-tag --raw "$tag" 2>&1 | grep "VALIDSIG" | awk '{print $3}') echo "$date - $tag - $key_info" fi done | sort | uniq -c | sort -nr }
# Generate security report generate_security_report() { echo "Generating tag security report..."
cat > tag-security-audit-report.md << EOF# Tag Security Audit Report
Generated: $(date)Repository: $(basename "$(pwd)")
## Tag Signing AnalysisEOF
total_tags=$(git tag | wc -l) signed_tags=$(git tag | while read -r tag; do git verify-tag -q "$tag" 2>/dev/null && echo "$tag"; done | wc -l) unsigned_tags=$((total_tags - signed_tags))
echo "### Overall Statistics" >> tag-security-audit-report.md echo "- Total tags: $total_tags" >> tag-security-audit-report.md echo "- Signed tags: $signed_tags" >> tag-security-audit-report.md echo "- Unsigned tags: $unsigned_tags" >> tag-security-audit-report.md echo "- Signing compliance: $((signed_tags * 100 / total_tags))%" >> tag-security-audit-report.md
echo >> tag-security-audit-report.md echo "### Unsigned Tags" >> tag-security-audit-report.md git tag | while read -r tag; do if ! git verify-tag -q "$tag" 2>/dev/null; then echo "- $tag" >> tag-security-audit-report.md fi done
echo >> tag-security-audit-report.md echo "### Security Recommendations" >> tag-security-audit-report.md if [ "$unsigned_tags" -gt 0 ]; then echo "- **HIGH**: $unsigned_tags tags are unsigned" >> tag-security-audit-report.md echo "- Enable mandatory tag signing" >> tag-security-audit-report.md echo "- Implement CI/CD tag verification" >> tag-security-audit-report.md fi
echo "Tag security audit report generated: tag-security-audit-report.md" }
# Run audit analyze_signing_coverage echo find_unsigned_tags echo check_key_rotation echo generate_security_report}
# Usageaudit_tag_signingDevelopment Team Workflows:
Section titled “Development Team Workflows:”# Team tag signing workflowteam_tag_workflow() { echo "=== Team Tag Signing Workflow ==="
# Setup team signing policy setup_team_policy() { echo "Setting up team tag signing policy..."
cat > team-tag-policy.md << EOF# Team Tag Signing Policy
## Policy OverviewAll release tags must be signed with approved keys.
## Requirements- Release tags (v*) must be signed- Development tags may be unsigned- Keys must be approved by security team- Annual key rotation mandatory
## Process1. Create annotated tag with release notes2. Sign tag with approved key3. Push tag to protected branch4. CI/CD verifies signature before deployment
## Verification- CI/CD pipelines reject unsigned release tags- Security audits check compliance monthly- Key rotation reminders sent quarterlyEOF
echo "Team tag policy created: team-tag-policy.md" }
# Setup developer tag signing setup_developer_signing() { local developer="$1"
echo "Setting up tag signing for developer: $developer"
# Create developer config mkdir -p "developer-configs/$developer"
cat > "developer-configs/$developer/tag-signing-setup.sh" << EOF#!/bin/bash# Tag signing setup for $developer
echo "Setting up tag signing..."
# Configure Gitgit config --global user.name "$developer"git config --global user.email "$developer@company.com"git config --global tag.gpgsign true
# Generate GPG key (interactive)echo "Run: gpg --full-generate-key"echo "Then configure: git config --global user.signingkey YOUR_KEY_ID"
echo "Tag signing setup complete for $developer"EOF
chmod +x "developer-configs/$developer/tag-signing-setup.sh"
echo "Developer tag signing setup created" }
# Monitor team compliance monitor_team_compliance() { echo "Monitoring team tag signing compliance..."
# Check release tags release_tags=$(git tag | grep "^v[0-9]" | wc -l) signed_release_tags=$(git tag | grep "^v[0-9]" | while read -r tag; do git verify-tag -q "$tag" 2>/dev/null && echo "$tag" done | wc -l)
if [ "$release_tags" -gt 0 ]; then compliance=$((signed_release_tags * 100 / release_tags)) echo "Release tag compliance: ${compliance}% ($signed_release_tags/$release_tags signed)" fi
# Check recent tags echo "Recent tag signing status:" git tag --sort=-creatordate | head -5 | while read -r tag; do if git verify-tag -q "$tag" 2>/dev/null; then echo " ✓ $tag" else echo " ✗ $tag" fi done }
# Interactive team workflow echo "Team Tag Workflow Options:" echo "1. Setup team policy" echo "2. Setup developer signing" echo "3. Monitor team compliance"
read -p "Select option (1-3): " option
case "$option" in 1) setup_team_policy ;; 2) read -p "Developer name: " dev setup_developer_signing "$dev" ;; 3) monitor_team_compliance ;; esac}
# Usageteam_tag_workflowTroubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Signature Verification Issues:
Section titled “Signature Verification Issues:”# Diagnose tag signature verification problemsdiagnose_tag_signature_issues() { echo "Diagnosing tag signature verification issues..."
# Test basic verification if git verify-tag -q v1.0 2>/dev/null; then echo "✓ Basic tag signature verification works" else echo "✗ Tag signature verification failed"
# Check for common issues if ! command -v gpg >/dev/null 2>&1 && ! command -v ssh-keygen >/dev/null 2>&1; then echo " No GPG or SSH signing tools found" fi
# Check if tag is signed if ! git show --show-signature v1.0 | grep -q "gpg:"; then echo " Tag is not signed" fi fi
# Check GPG keyring if command -v gpg >/dev/null 2>&1; then key_count=$(gpg --list-keys 2>/dev/null | grep -c "^pub") echo "GPG keys in keyring: $key_count"
if [ "$key_count" -eq 0 ]; then echo " No GPG keys found - import signer keys" fi fi
# Check SSH allowed signers if [ -f ~/.ssh/allowed_signers ]; then signer_count=$(wc -l < ~/.ssh/allowed_signers) echo "SSH allowed signers: $signer_count" else echo "SSH allowed signers file not found" fi}
# Fix tag signature issuesfix_tag_signature_issues() { echo "Attempting to fix tag signature issues..."
# Import missing keys echo "Attempting to import missing keys..."
# Get failed tag failed_key=$(git verify-tag v1.0 2>&1 | grep -o "gpg:.*key.*not.*found" | sed 's/.*key \([A-F0-9]*\).*/\1/')
if [ -n "$failed_key" ]; then echo "Missing key: $failed_key" echo "Attempting to fetch from keyserver..."
if gpg --keyserver hkps://keys.openpgp.org --recv-keys "$failed_key" 2>/dev/null; then echo "✓ Key imported successfully" else echo "✗ Could not import key" fi fi
# Check SSH configuration if [ ! -f ~/.ssh/allowed_signers ]; then echo "Creating SSH allowed signers file..." touch ~/.ssh/allowed_signers fi
# Test verification again if git verify-tag -q v1.0 2>/dev/null; then echo "✓ Tag signature verification now works" else echo "✗ Tag signature verification still failing" fi}
# Usagediagnose_tag_signature_issuesfix_tag_signature_issuesKey Management Issues:
Section titled “Key Management Issues:”# Troubleshoot tag key management problemstroubleshoot_tag_key_management() { echo "Troubleshooting tag key management issues..."
# Check key validity check_tag_key_status() { local key_id="$1"
echo "Checking status of key: $key_id"
# Check if key exists if ! gpg --list-keys "$key_id" >/dev/null 2>&1; then echo "✗ Key not found in keyring" return 1 fi
# Check expiration if gpg --list-keys --with-colons "$key_id" | grep -q "^pub:e:"; then echo "✗ Key has expired" return 1 fi
# Check revocation if gpg --list-keys --with-colons "$key_id" | grep -q "^pub:r:"; then echo "✗ Key has been revoked" return 1 fi
echo "✓ Key is valid" return 0 }
# Find tags with invalid signatures find_invalid_tag_signatures() { echo "Finding tags with invalid signatures..."
git tag | while read -r tag; do if ! git verify-tag -q "$tag" 2>/dev/null; then echo "Invalid signature: $tag" fi done }
# Update keyring update_tag_keyring() { echo "Updating GPG keyring for tag verification..."
# Update from keyservers gpg --keyserver hkps://keys.openpgp.org --refresh-keys
# Update trust database gpg --check-trustdb
echo "Tag keyring update complete" }
# Interactive troubleshooting echo "Tag Key Management Troubleshooting:" echo "1. Check key status" echo "2. Find invalid signatures" echo "3. Update keyring"
read -p "Select option (1-3): " option
case "$option" in 1) read -p "Key ID: " key_id check_tag_key_status "$key_id" ;; 2) find_invalid_tag_signatures ;; 3) update_tag_keyring ;; esac}
# Usagetroubleshoot_tag_key_managementConfiguration Issues:
Section titled “Configuration Issues:”# Troubleshoot tag configuration problemstroubleshoot_tag_config_issues() { echo "Troubleshooting tag configuration issues..."
# Check Git configuration echo "Git tag signing configuration:" git config --list | grep -E "(gpgsign|tag\.gpgsign)" | while read -r config; do echo " $config" done
# Check if tag signing is enabled if [ "$(git config --bool tag.gpgsign)" != "true" ]; then echo "⚠ Tag signing is not enabled" echo " Enable with: git config tag.gpgsign true" fi
# Check signing key signing_key=$(git config user.signingkey) if [ -z "$signing_key" ]; then echo "⚠ No signing key configured" echo " Configure with: git config user.signingkey YOUR_KEY_ID" else echo "✓ Signing key configured: $signing_key" fi
# Check GPG program gpg_program=$(git config gpg.program) if [ -n "$gpg_program" ]; then if ! command -v "$gpg_program" >/dev/null 2>&1; then echo "✗ Configured GPG program not found: $gpg_program" else echo "✓ GPG program available: $gpg_program" fi fi
# Check SSH signing if [ "$(git config gpg.format)" = "ssh" ]; then echo "SSH signing is configured"
allowed_signers=$(git config gpg.ssh.allowedSignersFile) if [ -n "$allowed_signers" ] && [ -f "$allowed_signers" ]; then echo "✓ SSH allowed signers file exists: $allowed_signers" else echo "✗ SSH allowed signers file missing or not configured" fi fi}
# Fix tag configuration issuesfix_tag_config_issues() { echo "Attempting to fix tag configuration issues..."
# Enable tag signing git config tag.gpgsign true echo "✓ Enabled tag signing"
# Find and set signing key secret_keys=$(gpg --list-secret-keys --keyid-format short | grep "^sec" | head -1 | awk '{print $2}' | cut -d'/' -f2)
if [ -n "$secret_keys" ]; then git config user.signingkey "$secret_keys" echo "✓ Configured signing key: $secret_keys" else echo "⚠ No GPG secret keys found" echo " Generate with: gpg --full-generate-key" fi
# Test configuration if git verify-tag -q $(git tag | head -1) 2>/dev/null; then echo "✓ Tag configuration is working" else echo "⚠ Tag configuration may still need adjustment" fi}
# Usagetroubleshoot_tag_config_issuesfix_tag_config_issuesReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Enterprise Release Management:
Section titled “Enterprise Release Management:”#!/bin/bash# Enterprise tag-based release management
enterprise_release_management() { echo "=== Enterprise Release Management ==="
# Setup release signing requirements setup_release_signing() { echo "Setting up enterprise release signing requirements..."
cat > release-signing-requirements.md << EOF# Enterprise Release Signing Requirements
## OverviewAll release tags must be cryptographically signed and verified.
## Requirements- Release tags (vX.Y.Z) must be annotated and signed- Signatures must use approved GPG keys- Keys must be valid and not expired- CI/CD must verify signatures before deployment
## Process1. Create release branch from main2. Test and validate release3. Create signed annotated tag4. Push tag to trigger deployment5. CI/CD verifies signature and deploys
## Security Controls- Pre-push hooks prevent unsigned tag pushes- CI/CD rejects deployments from unsigned tags- Regular key rotation audits- Automated signature verificationEOF
echo "Release signing requirements documented: release-signing-requirements.md" }
# Create signed release tag create_signed_release() { local version="$1" local message="$2"
echo "Creating signed release tag v$version..."
# Validate version format if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Invalid version format: $version" echo "Expected: X.Y.Z" return 1 fi
# Check if tag already exists if git tag | grep -q "^v$version$"; then echo "Tag v$version already exists" return 1 fi
# Create annotated signed tag git tag -a -s "v$version" -m "Release $version
$message
Signed-by: $(git config user.name) <$(git config user.email)>Created: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
# Verify the tag was created and signed if git verify-tag -q "v$version" 2>/dev/null; then echo "✓ Signed release tag v$version created successfully"
# Show tag details git tag -l "v$version" else echo "✗ Failed to create signed tag" return 1 fi }
# Verify release deployment readiness verify_release_readiness() { local tag="$1"
echo "Verifying release readiness for $tag..."
# Verify tag exists and is signed if ! git verify-tag -q "$tag" 2>/dev/null; then echo "✗ Tag $tag is not signed" return 1 fi
# Check tag format if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "⚠ Tag $tag does not follow release format vX.Y.Z" fi
# Verify tag points to valid commit commit=$(git rev-parse "$tag^{commit}") if ! git cat-file -e "$commit" 2>/dev/null; then echo "✗ Tag $tag points to invalid commit" return 1 fi
# Check if commit is in main branch if ! git branch --contains "$commit" | grep -q " main$\| master$"; then echo "⚠ Tag $tag points to commit not in main branch" fi
echo "✓ Release $tag is ready for deployment" }
# Setup automated release verification setup_release_verification() { echo "Setting up automated release verification..."
# Create release verification script cat > verify-release.sh << 'EOF'#!/bin/bash# Automated release verification
TAG="$1"
if [ -z "$TAG" ]; then echo "Usage: $0 <tag>" exit 1fi
echo "Verifying release $TAG..."
# Verify signatureif ! git verify-tag -q "$TAG" 2>/dev/null; then echo "❌ RELEASE REJECTED: Tag $TAG is not signed" exit 1fi
# Verify tag formatif [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "❌ RELEASE REJECTED: Invalid tag format: $TAG" exit 1fi
# Additional checks can be added here# - Security scans# - Test results# - Compliance checks
echo "✅ RELEASE APPROVED: $TAG passed all verification checks"EOF
chmod +x verify-release.sh
echo "Release verification script created: verify-release.sh" }
# Interactive enterprise release management echo "Enterprise Release Management Options:" echo "1. Setup release signing requirements" echo "2. Create signed release tag" echo "3. Verify release readiness" echo "4. Setup automated verification"
read -p "Select option (1-4): " option
case "$option" in 1) setup_release_signing ;; 2) read -p "Version (X.Y.Z): " version read -p "Release message: " message create_signed_release "$version" "$message" ;; 3) read -p "Tag to verify: " tag verify_release_readiness "$tag" ;; 4) setup_release_verification ;; esac}
enterprise_release_managementSecurity Auditing and Compliance:
Section titled “Security Auditing and Compliance:”# Advanced tag security auditingtag_security_auditing() { echo "=== Advanced Tag Security Auditing ==="
# Audit tag signing compliance audit_tag_compliance() { echo "Auditing tag signing compliance..."
total_tags=$(git tag | wc -l) signed_tags=0 unsigned_tags=0
declare -A signer_keys
git tag | while read -r tag; do if git verify-tag -q "$tag" 2>/dev/null; then ((signed_tags++)) # Extract key info key=$(git verify-tag --raw "$tag" 2>&1 | grep "VALIDSIG" | awk '{print $3}') signer_keys["$key"]=$((signer_keys["$key"] + 1)) else ((unsigned_tags++)) fi done
echo "Compliance Summary:" echo " Total tags: $total_tags" echo " Signed tags: $signed_tags" echo " Unsigned tags: $unsigned_tags" echo " Compliance rate: $((signed_tags * 100 / total_tags))%"
echo "Signing keys used:" for key in "${!signer_keys[@]}"; do echo " $key: ${signer_keys[$key]} tags" done }
# Detect tag signing anomalies detect_tag_anomalies() { echo "Detecting tag signing anomalies..."
# Check for expired signatures git tag | while read -r tag; do if git verify-tag -q "$tag" 2>/dev/null; then # Check signature age tag_date=$(git tag --format="%(creatordate:unix)" "$tag") current_time=$(date +%s) age_days=$(( (current_time - tag_date) / 86400 ))
if [ "$age_days" -gt 365 ]; then echo "⚠ Old signature: $tag ($age_days days old)" fi fi done
# Check for unusual signing patterns echo "Checking for unusual signing patterns..."
# Find tags signed by multiple keys declare -A tag_signers
git tag | while read -r tag; do if git verify-tag -q "$tag" 2>/dev/null; then key=$(git verify-tag --raw "$tag" 2>&1 | grep "VALIDSIG" | awk '{print $3}') tag_signers["$tag"]="$key" fi done
# Report findings unique_keys=$(echo "${tag_signers[@]}" | tr ' ' '\n' | sort | uniq | wc -l) total_signed_tags=$(echo "${!tag_signers[@]}" | wc -w)
echo "Signing pattern analysis:" echo " Unique signing keys: $unique_keys" echo " Signed tags: $total_signed_tags" }
# Generate compliance report generate_compliance_report() { echo "Generating tag compliance report..."
cat > tag-compliance-report-$(date +%Y%m%d).md << EOF# Tag Compliance Report
Generated: $(date)Repository: $(basename "$(pwd)")Audit Period: All time
## Executive SummaryThis report analyzes tag signing compliance and security posture.
## Compliance MetricsEOF
# Calculate metrics total_tags=$(git tag | wc -l) signed_tags=$(git tag | while read -r tag; do git verify-tag -q "$tag" 2>/dev/null && echo "$tag"; done | wc -l) unsigned_tags=$((total_tags - signed_tags))
compliance_rate=0 if [ "$total_tags" -gt 0 ]; then compliance_rate=$((signed_tags * 100 / total_tags)) fi
echo "### Overall Compliance" >> tag-compliance-report-$(date +%Y%m%d).md echo "- Total tags: $total_tags" >> tag-compliance-report-$(date +%Y%m%d).md echo "- Signed tags: $signed_tags" >> tag-compliance-report-$(date +%Y%m%d).md echo "- Unsigned tags: $unsigned_tags" >> tag-compliance-report-$(date +%Y%m%d).md echo "- Compliance rate: ${compliance_rate}%" >> tag-compliance-report-$(date +%Y%m%d).md
cat >> tag-compliance-report-$(date +%Y%m%d).md << EOF
## Risk AssessmentEOF
if [ "$compliance_rate" -lt 80 ]; then echo "**CRITICAL RISK**: Compliance below 80%" >> tag-compliance-report-$(date +%Y%m%d).md elif [ "$compliance_rate" -lt 95 ]; then echo "**HIGH RISK**: Compliance below 95%" >> tag-compliance-report-$(date +%Y%m%d).md else echo "**ACCEPTABLE**: Good compliance level" >> tag-compliance-report-$(date +%Y%m%d).md fi
cat >> tag-compliance-report-$(date +%Y%m%d).md << EOF
## Recommendations1. **IMMEDIATE**: Enable mandatory tag signing2. **HIGH**: Implement CI/CD signature verification3. **MEDIUM**: Rotate signing keys annually4. **LOW**: Regular compliance audits
## Unsigned Tags (First 10)EOF
git tag | while read -r tag; do if ! git verify-tag -q "$tag" 2>/dev/null; then echo "- $tag" >> tag-compliance-report-$(date +%Y%m%d).md fi done | head -10 >> tag-compliance-report-$(date +%Y%m%d).md
echo "Compliance report generated: tag-compliance-report-$(date +%Y%m%d).md" }
# Run comprehensive audit audit_tag_compliance echo detect_tag_anomalies echo generate_compliance_report}
# Usagetag_security_auditingAutomated Deployment Security:
Section titled “Automated Deployment Security:”# Automated deployment with tag verificationsecure_deployment_system() { echo "=== Secure Deployment System ==="
# Setup deployment security setup_deployment_security() { echo "Setting up deployment security controls..."
cat > deployment-security-policy.md << EOF# Deployment Security Policy
## OverviewDeployments are only allowed from properly signed and verified tags.
## Security Controls- All deployments must originate from signed tags- Tags must be verified before deployment starts- Deployment keys must be approved and rotated regularly- Audit logs must capture all deployment activities
## Process1. Developer creates signed release tag2. CI/CD verifies tag signature3. Security scan runs on tagged commit4. Manual approval required for production5. Automated deployment with full audit trail
## Monitoring- All deployment attempts logged- Signature verification failures alerted- Regular security audits performed- Compliance reports generated monthlyEOF
echo "Deployment security policy created: deployment-security-policy.md" }
# Verify deployment readiness verify_deployment_readiness() { local tag="$1" local environment="$2"
echo "Verifying deployment readiness for $tag to $environment..."
# Verify tag signature if ! git verify-tag -q "$tag" 2>/dev/null; then echo "❌ DEPLOYMENT BLOCKED: Tag $tag signature verification failed" return 1 fi
# Verify tag format for production if [ "$environment" = "production" ]; then if [[ ! "$tag" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "❌ DEPLOYMENT BLOCKED: Invalid production tag format: $tag" return 1 fi fi
# Additional security checks commit=$(git rev-parse "$tag^{commit}")
# Check commit is in protected branch protected_branches=("main" "master" "release/*") in_protected_branch=false
for branch in "${protected_branches[@]}"; do if git branch --contains "$commit" | grep -q "$branch"; then in_protected_branch=true break fi done
if [ "$in_protected_branch" = false ]; then echo "❌ DEPLOYMENT BLOCKED: Commit not in protected branch" return 1 fi
# Check for recent security scans (placeholder) echo "✓ Security checks passed"
echo "✅ DEPLOYMENT APPROVED: $tag ready for $environment deployment" return 0 }
# Execute secure deployment execute_secure