Skip to content

Improve GPG signing documentation security and modernize approach#11

Merged
perNyfelt merged 5 commits intosecurity_dependenciesfrom
copilot/sub-pr-8-another-one
Dec 16, 2025
Merged

Improve GPG signing documentation security and modernize approach#11
perNyfelt merged 5 commits intosecurity_dependenciesfrom
copilot/sub-pr-8-another-one

Conversation

Copy link
Contributor

Copilot AI commented Dec 16, 2025

Addresses security feedback on PUBLISHING.md GPG signing instructions. The original documentation used legacy keyring format with insecure command syntax and missing permission controls.

Changes

  • Fixed GPG export command: Use -o flag instead of > redirection, add chmod 600 for strict permissions
  • Modernized signing approach: Document GPG 2.1+ in-memory signing with signing.key property as recommended method
  • Restructured documentation: Present modern approach first, relegate legacy secretKeyRingFile to alternative section
  • Enhanced security guidance:
    • Warn about plaintext key file risks
    • Show proper CI/CD secret referencing ($GPG_PRIVATE_KEY_SECRET) vs direct GPG command execution
    • Clarify newline handling in single-line property values

Before

gpg --export-secret-keys ABCD1234 > ~/.gnupg/secring.gpg

After

# Legacy approach (GPG < 2.1)
gpg --export-secret-keys -o ~/.gnupg/secring.gpg ABCD1234
chmod 600 ~/.gnupg/secring.gpg

# Recommended approach (GPG 2.1+)
gpg --armor --export-secret-keys ABCD1234
# Then use signing.key property in gradle.properties

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits December 16, 2025 23:00
Co-authored-by: perNyfelt <13261538+perNyfelt@users.noreply.github.com>
Co-authored-by: perNyfelt <13261538+perNyfelt@users.noreply.github.com>
Co-authored-by: perNyfelt <13261538+perNyfelt@users.noreply.github.com>
Copilot AI changed the title [WIP] Update to address feedback on security and dependencies Improve GPG signing documentation security and modernize approach Dec 16, 2025
Copilot AI requested a review from perNyfelt December 16, 2025 23:04
@perNyfelt perNyfelt marked this pull request as ready for review December 16, 2025 23:05
Copilot AI review requested due to automatic review settings December 16, 2025 23:05
@perNyfelt perNyfelt merged commit 463c5bb into security_dependencies Dec 16, 2025
@perNyfelt perNyfelt deleted the copilot/sub-pr-8-another-one branch December 16, 2025 23:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the GPG signing documentation in PUBLISHING.md by modernizing the approach and enhancing security guidance. The changes address security concerns with the original legacy keyring format instructions and provide clearer guidance for modern GPG versions (2.1+).

Key changes:

  • Modernized GPG export commands with proper flags (-o instead of > redirection) and added strict file permissions (chmod 600)
  • Restructured to present the modern in-memory signing approach (signing.key property) as the recommended method, with legacy secretKeyRingFile approach relegated to an alternative section
  • Enhanced security warnings about plaintext key files and improved CI/CD secret handling examples

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

**Important Security Notes:**
- Never commit credentials to version control
- Use environment variables in CI/CD instead of files
- The modern in-memory approach (`signing.key`) is preferred as it doesn't require a plaintext key file on disk
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially misleading security claim. The statement that the modern in-memory approach "doesn't require a plaintext key file on disk" is not entirely accurate. When the signing.key property is stored in ~/.gradle/gradle.properties, it is still a plaintext key file on disk - just in a different location. The main security advantage is that the key can be provided via environment variables in CI/CD without persisting to disk, which should be clarified.

Suggested change
- The modern in-memory approach (`signing.key`) is preferred as it doesn't require a plaintext key file on disk
- The modern in-memory approach (`signing.key`) is preferred because it supports providing the key via environment variables (so it does not need to be written to disk in CI/CD) and avoids the legacy keyring file; if you store `signing.key` in `~/.gradle/gradle.properties`, it is still a plaintext key in a file on disk

Copilot uses AI. Check for mistakes.
# GPG signing configuration (modern approach)
signing.keyId=ABCD1234
signing.password=your-gpg-passphrase
signing.key=-----BEGIN PGP PRIVATE KEY BLOCK-----\n...(paste output from gpg --armor --export-secret-keys)...\n-----END PGP PRIVATE KEY BLOCK-----
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete example with placeholder text. The example shows "...(paste output from gpg --armor --export-secret-keys)..." which may be confusing. It would be more helpful to clarify that this placeholder should be replaced with the actual multi-line ASCII-armored output, or provide a clearer indication of what the actual content looks like (e.g., showing a few more lines of the typical structure).

Suggested change
signing.key=-----BEGIN PGP PRIVATE KEY BLOCK-----\n...(paste output from gpg --armor --export-secret-keys)...\n-----END PGP PRIVATE KEY BLOCK-----
signing.key=-----BEGIN PGP PRIVATE KEY BLOCK-----\nVersion: GnuPG v2\n\nmQINBF1EXAMPLEBEADAwEAAQ...\n...(multi-line base64 data from `gpg --armor --export-secret-keys ABCD1234` output, with each newline replaced by `\n`)...\n=ABCD\n-----END PGP PRIVATE KEY BLOCK-----

Copilot uses AI. Check for mistakes.
signing.key=-----BEGIN PGP PRIVATE KEY BLOCK-----\n...(paste output from gpg --armor --export-secret-keys)...\n-----END PGP PRIVATE KEY BLOCK-----
```

**Note:** The `signing.key` value should be the entire ASCII-armored private key block from the `gpg --armor --export-secret-keys ABCD1234` command output. When storing as a single-line property, replace actual newlines with the literal string `\n`.
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warning about creating a plaintext secret key file is helpful, but the same concern applies to the modern approach when storing in gradle.properties. Consider adding a note that when using the modern approach with signing.key in ~/.gradle/gradle.properties, users should also set strict permissions on that file (chmod 600) since it contains the private key in plaintext as well.

Suggested change
**Note:** The `signing.key` value should be the entire ASCII-armored private key block from the `gpg --armor --export-secret-keys ABCD1234` command output. When storing as a single-line property, replace actual newlines with the literal string `\n`.
**Note:** The `signing.key` value should be the entire ASCII-armored private key block from the `gpg --armor --export-secret-keys ABCD1234` command output. When storing as a single-line property, replace actual newlines with the literal string `\n`. The `~/.gradle/gradle.properties` file now contains your private key in plaintext, so ensure it has strict permissions (for example, run `chmod 600 ~/.gradle/gradle.properties`).

Copilot uses AI. Check for mistakes.
export ORG_GRADLE_PROJECT_signingKeyId=ABCD1234
export ORG_GRADLE_PROJECT_signingPassword=your-passphrase
# In CI/CD, reference the key from a secret (preferred)
export ORG_GRADLE_PROJECT_signingKey="$GPG_PRIVATE_KEY_SECRET"
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent secret variable naming. Line 102 uses $GPG_PRIVATE_KEY_SECRET as an example, but line 218 documents the GitHub Actions secret as GPG_SIGNING_KEY. For consistency and to avoid confusion, the example on line 102 should reference the same variable name used in the GitHub Actions section, or clearly indicate that users should replace this with their actual secret variable name.

Suggested change
export ORG_GRADLE_PROJECT_signingKey="$GPG_PRIVATE_KEY_SECRET"
export ORG_GRADLE_PROJECT_signingKey="$GPG_SIGNING_KEY"

Copilot uses AI. Check for mistakes.
Add credentials to your `~/.gradle/gradle.properties` (NOT the project's `gradle.properties`):
#### Recommended: Modern In-Memory Signing (GPG 2.1+)

For modern GPG versions, use the in-memory signing approach with the `signingKey` property:
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent property name reference. Line 47 mentions signingKey property, but line 64 uses signing.key (with dot notation). The correct Gradle property name is signing.key, so this reference should be updated to match the actual property name used in the configuration examples.

Suggested change
For modern GPG versions, use the in-memory signing approach with the `signingKey` property:
For modern GPG versions, use the in-memory signing approach with the `signing.key` property:

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants