This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-gpg-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 41ae1b8 Consolidate documentation in order to reduce redundancy
41ae1b8 is described below
commit 41ae1b836198b84c5a03a2d264b36743152f9263
Author: Konrad Windszus <[email protected]>
AuthorDate: Tue Dec 2 17:38:46 2025 +0100
Consolidate documentation in order to reduce redundancy
Split between features used by both GnuPG and BC signer and signer
specific information.
Improve plugin parameter documentation (also with regards to primary and
secondary keys).
---
.../apache/maven/plugins/gpg/AbstractGpgMojo.java | 28 ++++-
src/site/fml/faq.fml | 2 +-
.../markdown/examples/deploy-signed-artifacts.md | 81 -------------
src/site/markdown/index.md.vm | 16 +--
src/site/markdown/{usage.md.vm => passphrase.md} | 79 +++++--------
src/site/markdown/usage.md.vm | 129 ++++++---------------
src/site/resources/.htaccess | 16 +++
src/site/site.xml | 4 +-
.../org/apache/maven/plugins/gpg/BcSignerTest.java | 22 +++-
9 files changed, 132 insertions(+), 245 deletions(-)
diff --git a/src/main/java/org/apache/maven/plugins/gpg/AbstractGpgMojo.java
b/src/main/java/org/apache/maven/plugins/gpg/AbstractGpgMojo.java
index 271921e..c664a63 100644
--- a/src/main/java/org/apache/maven/plugins/gpg/AbstractGpgMojo.java
+++ b/src/main/java/org/apache/maven/plugins/gpg/AbstractGpgMojo.java
@@ -54,9 +54,13 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
private String agentSocketLocations;
/**
- * BC Signer only: The path of the exported key in
+ * BC Signer only: The path of the exported key ring in
* <a
href="https://openpgp.dev/book/private_keys.html#transferable-secret-key-format">TSK
format</a>,
* and may be passphrase protected. If relative, the file is resolved
against user home directory.
+ * Both binary as well as <a
href="https://www.rfc-editor.org/rfc/rfc4880#section-6.2">ASCII armored
encoding</a>
+ * is supported.
+ * <p>
+ * Either this or {@link #keyEnvName} is mandatory for the BC signer.
* <p>
* <em>Note: it is not recommended to have sensitive files checked into
SCM repository. Key file should reside on
* developer workstation, outside of SCM tracked repository. For CI-like
use cases you should set the
@@ -68,7 +72,11 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
private String keyFilePath;
/**
- * BC Signer only: The fingerprint of the key to use for signing. If not
given, first key in keyring will be used.
+ * BC Signer only: The fingerprint of the primary or secondary key
(subkey) to use for signing.
+ * If not given the first key in the keyring will be used.
+ * Note that in contrast to {@link #keyname} user IDs are not supported
here.
+ * @see <a href="https://www.rfc-editor.org/rfc/rfc4880#section-12.2">Open
PGP Fingerprints</a>
+ * @see #keyFingerprintEnvName
*
* @since 3.2.0
*/
@@ -81,6 +89,10 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
* key (while it does use GnuPG Agent to ask for password in interactive
mode). The key should be in
* <a
href="https://openpgp.dev/book/private_keys.html#transferable-secret-key-format">TSK
format</a> and may
* be passphrase protected.
+ * Both binary as well as <a
href="https://www.rfc-editor.org/rfc/rfc4880#section-6.2">ASCII armored
encoding</a>
+ * is supported.
+ * <p>
+ * Either this or {@link #keyFilePath} is mandatory for the BC signer.
*
* @since 3.2.0
*/
@@ -88,9 +100,13 @@ public abstract class AbstractGpgMojo extends AbstractMojo {
private String keyEnvName;
/**
- * BC Signer only: The env variable name where the GnuPG key fingerprint
is set, if the provided keyring contains
- * multiple keys.
+ * BC Signer only: The env variable name where the GnuPG key fingerprint
is set.
+ * If set must contain the fingerprint of the primary or secondary key
(subkey) to use for signing.
+ * If not given the first key in the keyring will be used.
+ * Note that in contrast to {@link #keyname} user IDs are not supported
here.
+ * @see <a href="https://www.rfc-editor.org/rfc/rfc4880#section-12.2">Open
PGP Fingerprints</a>
*
+ * @see #keyFingerprint
* @since 3.2.0
*/
@Parameter(property = "gpg.keyFingerprintEnvName", defaultValue =
DEFAULT_ENV_MAVEN_GPG_FINGERPRINT)
@@ -143,6 +159,10 @@ public abstract class AbstractGpgMojo extends AbstractMojo
{
/**
* GPG Signer only: The "name" of the key to sign with. Passed to gpg as
<code>--local-user</code>.
+ * The value may be one of the formats supported by GPG outlined in <a
href="https://www.gnupg.org/documentation/manuals/gnupg/Specify-a-User-ID.html">
+ * identifying a key/user</a>.
+ * This supports both primary and secondary keys (subkeys).
+ * If not given the default primary key is used.
*/
@Parameter(property = "gpg.keyname")
private String keyname;
diff --git a/src/site/fml/faq.fml b/src/site/fml/faq.fml
index 394960a..8790545 100644
--- a/src/site/fml/faq.fml
+++ b/src/site/fml/faq.fml
@@ -50,7 +50,7 @@ under the License.
When plugin used in combination with <a
href="https://maven.apache.org/maven-release/maven-release-plugin/">Maven
Release Plugin</a>
the GPG signing will happen in "batch mode". This implies that you
must either use GPG passphrase passed in
via environment variable (preferred on systems like CI systems are),
or, if on Workstation, using primed
- gpg-agent is needed. Read more here about <a
href="usage.html#sign-artifacts-with-gnupg">GPG Agent priming</a>.
+ gpg-agent is needed. Read more here about <a
href="passphrase.html#Retrieve_passphrase_via_gpg-agent">GPG Agent priming</a>.
</p>
</answer>
</faq>
diff --git a/src/site/markdown/examples/deploy-signed-artifacts.md
b/src/site/markdown/examples/deploy-signed-artifacts.md
deleted file mode 100644
index a697635..0000000
--- a/src/site/markdown/examples/deploy-signed-artifacts.md
+++ /dev/null
@@ -1,81 +0,0 @@
----
-title: Deploy Signed Artifacts
-author:
- - Dennis Lundberg
-date: 2011-03-19
----
-
-<!-- Licensed to the Apache Software Foundation (ASF) under one-->
-<!-- or more contributor license agreements. See the NOTICE file-->
-<!-- distributed with this work for additional information-->
-<!-- regarding copyright ownership. The ASF licenses this file-->
-<!-- to you under the Apache License, Version 2.0 (the-->
-<!-- "License"); you may not use this file except in compliance-->
-<!-- with the License. You may obtain a copy of the License at-->
-<!---->
-<!-- http://www.apache.org/licenses/LICENSE-2.0-->
-<!---->
-<!-- Unless required by applicable law or agreed to in writing,-->
-<!-- software distributed under the License is distributed on an-->
-<!-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY-->
-<!-- KIND, either express or implied. See the License for the-->
-<!-- specific language governing permissions and limitations-->
-<!-- under the License.-->
-# Deploy Signed Artifacts
-
-Without this plugin you deploy your project like this:
-
-```unknown
-mvn deploy
-```
-
-If you have configured this plugin according to the instructions in the [usage
page](../usage.html), nothing changes for interactive sessions:
-
-```unknown
-mvn deploy
-```
-
-And the gpg-agent will prompt you for passphrase.
-
-General remark regarding environment variables: Examples below are NOT
instructions how to invoke Maven, as if you'd follow these examples
literally, it would defy the goal of not leaking cleartext passphrases, as
these would end up in terminal history\! You should set these environment
variables on your own discretion in some secure manner.
-
-If you use "batch" build \(or build is invoked by Maven Release
Plugin\), then gpg-agent will be unable to ask interactively for password. In
such cases you want to "prime" the agent with passwords first. See
[usage page](../usage.html) for details how to "prime" gpg-agent.
-
-In "agent-less" \(CI like usage\) mode one can supply passphrase via
environment variable only.
-
-```unknown
-MAVEN_GPG_PASSPHRASE=thephrase mvn --batch-mode deploy
-```
-
-## Sign using BC Signer
-
-By default the plugin uses the "gpg" Signer \(that relies on GnuPG
tool installed on host OS\). The "bc" Signer on the other hand
implements signing in pure Java using Bouncy Castle libraries.
-
-The "bc" signer, unlike "gpg", does not and cannot make
use of `~/.gnupg` directory in user home, and have to have configured both, the
key used to sign and the passphrase \(if key is passphrase protected\). The key
is expected to be in TSK format \(see ["Transferable Secret
Keys"](https://openpgp.dev/book/private_keys.html#transferable-secret-key-format)
format\).
-
-```unknown
-mvn deploy -Dgpg.signer=bc -Dgpg.keyFilePath=path/to/key
-```
-
-In interactive sessions, similarly as with "gpg" Signer, gpg-agent
will be used to ask for password. In batch sessions, you can use environment
variables to achieve similar thing:
-
-```unknown
-MAVEN_GPG_PASSPHRASE=thephrase mvn deploy -Dgpg.signer=bc
-Dgpg.keyFilePath=path/to/key
-```
-
-Ultimately, you can place both, they key and passphrase into environment
variables:
-
-```unknown
-MAVEN_GPG_KEY=thekeymaterial MAVEN_GPG_PASSPHRASE=thephrase mvn deploy
-Dgpg.signer=bc
-```
-
-## Install/Deploy without configuring the plugin in the POM
-
-Currently this is not easily accomplished. gpg signs the artifacts attached to
the build at the point that gpg runs. However, we want to "inject"
the gpg into the phases. What MIGHT work is:
-
-```unknown
-mvn verify gpg:sign install:install deploy:deploy
-```
-
-However, if there are other plugins configured for phases after the `verify`
phase, they will not be run.
-
diff --git a/src/site/markdown/index.md.vm b/src/site/markdown/index.md.vm
index 95b57a2..570af38 100644
--- a/src/site/markdown/index.md.vm
+++ b/src/site/markdown/index.md.vm
@@ -23,28 +23,20 @@ date: 2013-07-22
<!-- under the License.-->
# ${project.name}
-This plugin signs all of the project's attached artifacts with GnuPG.
+This plugin signs artifacts according to [OpenPGP
standard](https://www.ietf.org/rfc/rfc4880.txt). Signatures in this format are
for example [required by Maven
Central](https://central.sonatype.org/publish/requirements/gpg/).
#[[##]]# Goals Overview
- [gpg:sign](./sign-mojo.html) Sign project artifact, the POM, and attached
artifacts with GnuPG for deployment.
- [gpg:sign-and-deploy-file](./sign-and-deploy-file-mojo.html) Signs artifacts
and installs the artifact in the remote repository.
+- [gpg:sign-deployed](./sign-deployed-mojo.html) Resolves given artifacts from
a given remote repository, signs them, and deploys the signatures next to
signed artifacts.
+
#[[##]]# Usage
-General instructions on how to use the GPG Plugin can be found on the [usage
page](./usage.html). Some more specific use cases are described in the examples
given below.
+General instructions on how to use the GPG Plugin can be found on the [usage
page](./usage.html).
Since 3\.2\.0, plugin can enforce "best practices", and will fail
the build if any violation are detected. In short, intent is to stop users
putting secrets \(plaintext or quasi-encrypted\) in their Maven configuration
files \(settings.xml, POMs\) or use secrets in a way they leave trace \(like in
terminal history\). In this mode, plugin leaves two options to obtain
passphrase: use of gpg-agent \(with pinentry in interactive sessions, or
pre-seeded "cached" passwords [...]
-To "prime" the GnuPG agent, you have several options: either just
"sign" something beforehand \(usable on workstations\) like `echo
"test" | gpg --clearsign` \(optionally using a dedicated private key with
[`--local-user <keyname>>>), or use gpg-preset-passphrase GnuPG command, that
will "cache" the password in gpg-agent for given login session, cache content
is lost between reboots. Note: this tool, while is part of GnuPG suite, may not
be on path. Check your OS docu [...]
-
-**Note:** The GpgSigner, that uses GnuPG tool installed and configured on the
host OS, while it does contain support for older GnuPGP versions, is tested
\(locally by developers and on CI systems\) only by using [latest
"stable" GnuPG version](https://www.gnupg.org/download/index.html)
\(scroll to bottom of page for EOL information\).
-
In case you still have questions regarding the plugin's usage, please
have a look at the [FAQ](./faq.html) and feel free to contact the [user mailing
list](./mailing-lists.html). The posts to the mailing list are archived and
could already contain the answer to your question as part of an older thread.
Hence, it is also worth browsing/searching the [mail
archive](./mailing-lists.html).
If you feel like the plugin is missing a feature or has a defect, you can fill
a feature request or bug report in our [issue
tracker](./issue-management.html). When creating a new issue, please provide a
comprehensive description of your concern. Especially for fixing bugs it is
crucial that the developers can reproduce your problem. For this reason, entire
debug logs, POMs or most preferably little demo projects attached to the issue
are very much appreciated. Of course, patches are wel [...]
-
-#[[##]]# Examples
-
-To provide you with better understanding of some usages of the GPG Plugin, you
can take a look at the following example:
-
-- [Deploy Signed Artifacts](./examples/deploy-signed-artifacts.html)
diff --git a/src/site/markdown/usage.md.vm b/src/site/markdown/passphrase.md
similarity index 70%
copy from src/site/markdown/usage.md.vm
copy to src/site/markdown/passphrase.md
index ab32626..ee4e318 100644
--- a/src/site/markdown/usage.md.vm
+++ b/src/site/markdown/passphrase.md
@@ -1,8 +1,7 @@
---
-title: Usage
+title: Passphrases
author:
- - Dennis Lundberg
-date: 2011-03-19
+ - Konrad Windszus
---
<!-- Licensed to the Apache Software Foundation (ASF) under one-->
@@ -21,74 +20,45 @@ date: 2011-03-19
<!-- KIND, either express or implied. See the License for the-->
<!-- specific language governing permissions and limitations-->
<!-- under the License.-->
-# Usage
-#[[##]]# Sign artifacts with GnuPG
-Signs all of a project's attached artifacts with GnuPG.
+# Passphrases
-You need to have previously configured the default key using GnuPG.
+In most cases secret GPG keys are protected with a passphrase which must be
passed to this Maven plugin in order to sign.
-`gpg` also needs to be on the search path.
+There are different ways how a passphrase can be retrieved. They are outlined
in order of precedence (from safest to least safe)
-First you add the plugin to your `pom.xml` like this:
+<!-- MACRO{toc|fromDepth=2} -->
-```unknown
-<project>
- ...
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-gpg-plugin</artifactId>
- <version>${project.version}</version>
- <executions>
- <execution>
- <id>sign-artifacts</id>
- <phase>verify</phase>
- <goals>
- <goal>sign</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- ...
-</project>
-```
+General remark regarding environment variables: Examples below are NOT
instructions how to invoke Maven, as if you'd follow these examples
literally, it would defy the goal of not leaking cleartext passphrases, as
these would end up in terminal history\! You should set these environment
variables on your own discretion in some secure manner.
-Ideally, if invoked on workstation, you should rely on gpg-agent to collect
passphrase from, as in that way no secrets will enter terminal history nor any
file on disk. In agent-less \(batch\) sessions, typically on CI, you should
provide passphrases via environment variable \(see goals\).
+In the future, plugin will operate in `bestPractices` mode enabled, and will
fail the build if credentials are given in a unsafe manner. The goal of this
change was to protect plugin users from possible "leaks" of sensitive
information \(like passphrase is\). Sensitive information like passphrases
should never be stored on disks \(plaintext or quasi-encrypted\), nor should be
used in a way they may "leak" into other files \(for example bash
terminal history\).
+
+## Retrieve passphrase via gpg-agent
+
+Ideally, if invoked on workstation, you should rely on
[gpg-agent](https://www.gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html)
to collect passphrase from, as in that way no secrets will enter terminal
history nor any file on disk. In agent-less \(batch\) sessions, typically on
CI, you should provide passphrases via environment variable \(see goals\).
**Note:** When using the GPG Plugin in combination with the Maven Release
Plugin, on a developer Workstation, you should rely on gpg-agent, but have it
"primed", as Release plugin invokes build in batch mode, that will
prevent agent to present the "pinentry pop up". If fully unattended
release is being done, for example on a CI system, then with `useAgent` set to
`false` one can pass the passphrase via environment variable.
**To prime gpg-agent caches**, one can perform simple "sign"
operation on workstation like this `echo "test" | gpg --clearsign` or can use
gpg command
[gpg-preset-passphrase](https://www.gnupg.org/documentation/manuals/gnupg/Invoking-gpg_002dpreset_002dpassphrase.html).
+## Retrieve passphrase via environment variable
+
+In "agent-less" \(CI like usage\) mode one can supply passphrase via
environment variable only.
General remark regarding environment variables: Examples below are NOT
instructions how to invoke Maven, as if you'd follow these examples
literally, it would defy the goal of not leaking cleartext passphrases, as
these would end up in terminal history\! You should set these environment
variables on your own discretion in some secure manner.
-```unknown
+```
MAVEN_GPG_PASSPHRASE=thephrase mvn release:perform
```
One "real life" example, on Un*x systems could be this:
-```unknown
-read -s -p "Enter your GnuPG key passphrase: " MAVEN_GPG_PASSPHRASE; mvn
release:perform
```
-
-Finally, the passphrase can be given on the command line as well, but this is
not recommended, and plugin will emit warnings. This mode of invocation is
highly discouraged, as passphrase in cleartext is recorded into Terminal
history.
-
-```unknown
-mvn verify -Dgpg.passphrase=thephrase
+read -s -p "Enter your GnuPG key passphrase: " MAVEN_GPG_PASSPHRASE; mvn
release:perform
```
-#[[##]]# Security considerations
-
-In the future, plugin will operate in `bestPractices` mode enabled, and will
fail the build if any violation of those is detected. The goal of this change
was to protect plugin users from possible "leaks" of sensitive
information \(like passphrase is\). Sensitive information like passphrases
should never be stored on disks \(plaintext or quasi-encrypted\), nor should be
used in way they may "leak" into other files \(for example bash
terminal history\).
-
-Hence, examples below will work by emit warnings. In the future, once
"best practices" become enforced, these examples will not work
anymore.
-#[[##]]# Configure passphrase in settings.xml
+## Configure passphrase in settings.xml
**NOTE:** These techniques below are highly discouraged. Ideally sensitive
information should enter via gpg-agent or via environment variables.
@@ -107,7 +77,7 @@ Instead of specifying the passphrase on the command line,
you can place it in yo
</settings>
```
-#[[##]]# Configure passphrase in settings.xml with a keyname
+## Configure passphrase in settings.xml with a keyname
To allow discovery of keyname and passphrase at build time, configure this
plugin to map both _keyname_ and _passphraseServerId_ to a fixed property.
@@ -168,3 +138,14 @@ and use local `settings.xml` to discover the passphrase
via the keyname
</settings>
```
+## Configure passphrase via CLI argument
+
+Finally, the passphrase can be given on the command line as well, but this is
not recommended, and plugin will emit warnings. This mode of invocation is
highly discouraged, as passphrase in cleartext is recorded into Terminal
history.
+
+```
+mvn verify -Dgpg.passphrase=thephrase
+```
+
+*Never configure this with a literal value in the pom.xml!*
+
+
diff --git a/src/site/markdown/usage.md.vm b/src/site/markdown/usage.md.vm
index ab32626..cc57533 100644
--- a/src/site/markdown/usage.md.vm
+++ b/src/site/markdown/usage.md.vm
@@ -23,15 +23,18 @@ date: 2011-03-19
<!-- under the License.-->
# Usage
-#[[##]]# Sign artifacts with GnuPG
+There is two different ways how one can sign with $project.artifactId:
-Signs all of a project's attached artifacts with GnuPG.
+1. Leveraging [GnuPG](https://gnupg.org/) (external program)
+2. Leveraging [Bouncy Castle](https://www.bouncycastle.org/) (Java library, no
external prerequisites)
-You need to have previously configured the default key using GnuPG.
+<!-- MACRO{toc|fromDepth=2} -->
-`gpg` also needs to be on the search path.
+#[[##]]# Configure Plugin in POM
-First you add the plugin to your `pom.xml` like this:
+This is agnostic of the signing mechanism
+
+Add the plugin to your `pom.xml` like this:
```unknown
<project>
@@ -45,7 +48,7 @@ First you add the plugin to your `pom.xml` like this:
<executions>
<execution>
<id>sign-artifacts</id>
- <phase>verify</phase>
+ <phase>verify</phase><!-- this is the default phase, no need to
configure explicitly -->
<goals>
<goal>sign</goal>
</goals>
@@ -58,113 +61,51 @@ First you add the plugin to your `pom.xml` like this:
</project>
```
-Ideally, if invoked on workstation, you should rely on gpg-agent to collect
passphrase from, as in that way no secrets will enter terminal history nor any
file on disk. In agent-less \(batch\) sessions, typically on CI, you should
provide passphrases via environment variable \(see goals\).
-
-**Note:** When using the GPG Plugin in combination with the Maven Release
Plugin, on a developer Workstation, you should rely on gpg-agent, but have it
"primed", as Release plugin invokes build in batch mode, that will
prevent agent to present the "pinentry pop up". If fully unattended
release is being done, for example on a CI system, then with `useAgent` set to
`false` one can pass the passphrase via environment variable.
+This will sign all attached artifacts of the current project during phase
`verify`.
-**To prime gpg-agent caches**, one can perform simple "sign"
operation on workstation like this `echo "test" | gpg --clearsign` or can use
gpg command
[gpg-preset-passphrase](https://www.gnupg.org/documentation/manuals/gnupg/Invoking-gpg_002dpreset_002dpassphrase.html).
+#[[##]]# Install/Deploy without configuring the plugin in the POM
-General remark regarding environment variables: Examples below are NOT
instructions how to invoke Maven, as if you'd follow these examples
literally, it would defy the goal of not leaking cleartext passphrases, as
these would end up in terminal history\! You should set these environment
variables on your own discretion in some secure manner.
+Currently this is not easily accomplished. The goal `gpg:sign` signs the
artifacts attached to the build at the point that this plugin runs. However, we
want to "inject" the goal into the phases. What MIGHT work is:
-```unknown
-MAVEN_GPG_PASSPHRASE=thephrase mvn release:perform
```
-
-One "real life" example, on Un*x systems could be this:
-
-```unknown
-read -s -p "Enter your GnuPG key passphrase: " MAVEN_GPG_PASSPHRASE; mvn
release:perform
+mvn verify gpg:sign install:install deploy:deploy
```
-Finally, the passphrase can be given on the command line as well, but this is
not recommended, and plugin will emit warnings. This mode of invocation is
highly discouraged, as passphrase in cleartext is recorded into Terminal
history.
+However, if there are other plugins configured for phases after the `verify`
phase, they will not be run.
-```unknown
-mvn verify -Dgpg.passphrase=thephrase
-```
-#[[##]]# Security considerations
+#[[##]]# Sign using GnuPG
-In the future, plugin will operate in `bestPractices` mode enabled, and will
fail the build if any violation of those is detected. The goal of this change
was to protect plugin users from possible "leaks" of sensitive
information \(like passphrase is\). Sensitive information like passphrases
should never be stored on disks \(plaintext or quasi-encrypted\), nor should be
used in way they may "leak" into other files \(for example bash
terminal history\).
+**Note:** The GpgSigner, that uses GnuPG tool installed and configured on the
host OS, while it does contain support for older GnuPGP versions, is tested
\(locally by developers and on CI systems\) only by using [latest
"stable" GnuPG version](https://www.gnupg.org/download/index.html)
\(scroll to bottom of page for EOL information\).
-Hence, examples below will work by emit warnings. In the future, once
"best practices" become enforced, these examples will not work
anymore.
+#[[###]]# Prerequisites
-#[[##]]# Configure passphrase in settings.xml
+- `gpg` needs to be [installed](https://gnupg.org/download/index.html#binary)
and available in the search path
+- The secret key to be used must be added to GnuPG's keyring
-**NOTE:** These techniques below are highly discouraged. Ideally sensitive
information should enter via gpg-agent or via environment variables.
+Signing will just invoke `gpg` with some parameter to have artifacts in form
of files on the filesystem signed. If nothing else is configured the *default
primary key* from GnuPG will be used for signing.
+You can configure a different secret key with parameter `keyname`.
+Refer to [Passphrases](passphrase.html) on how an optional passphrase may be
passed.
-Instead of specifying the passphrase on the command line, you can place it in
your local `settings.xml` either in clear or
[encrypted](/guides/mini/guide-encryption.html) text.
+#[[##]]# Sign using Bouncy Castle
-```unknown
-<settings>
- [...]
- <servers>
- [...]
- <server>
- <id>gpg.passphrase</id>
- <passphrase>clear or encrypted text</passphrase>
- </server>
- </servers>
-</settings>
-```
+By default the plugin uses the "gpg" Signer \(that relies on GnuPG
tool installed on host OS\). The "bc" Signer on the other hand
implements signing in pure Java using Bouncy Castle libraries.
-#[[##]]# Configure passphrase in settings.xml with a keyname
+#[[###]]# Prerequisites
-To allow discovery of keyname and passphrase at build time, configure this
plugin to map both _keyname_ and _passphraseServerId_ to a fixed property.
+- Secret key to use for signing in TSK format \(see ["Transferable Secret
Keys"](https://openpgp.dev/book/private_keys.html#transferable-secret-key-format)
format\).
+- Parameter `gpg.signer` set to `bc`
-```unknown
-<project>
- ...
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-gpg-plugin</artifactId>
- <version>${project.version}</version>
- <executions>
- <execution>
- <id>sign-artifacts</id>
- <phase>verify</phase>
- <goals>
- <goal>sign</goal>
- </goals>
- <configuration>
- <keyname>${gpg.keyname}</keyname>
- <passphraseServerId>${gpg.keyname}</passphraseServerId>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- ...
-</project>
+The "bc" signer, unlike "gpg", does not and cannot make
use of `~/.gnupg` directory in user home, and have to have configured both, the
key used to sign and the passphrase \(if key is passphrase protected\).
+
+```
+mvn deploy -Dgpg.signer=bc -Dgpg.keyFilePath=path/to/key
```
-and use local `settings.xml` to discover the passphrase via the keyname
+The key can also be passed as environment variable:
-```unknown
-<settings>
- [...]
- <servers>
- [...]
- <server>
- <id>your.keyname</id>
- <passphrase>clear or encrypted text</passphrase>
- </server>
- </servers>
-
- [...]
- <profiles>
- <profile>
- <id>my_profile_id</id>
- <activation>
- <activeByDefault>true</activeByDefault>
- </activation>
- <properties>
- <gpg.keyname>your.keyname</gpg.keyname>
- </properties>
- </profile>
- <profiles>
-</settings>
+```
+MAVEN_GPG_KEY=thekeymaterial mvn deploy -Dgpg.signer=bc
```
+Refer to [Passphrases](passphrase.html) on how an optional passphrase may be
passed.
diff --git a/src/site/resources/.htaccess b/src/site/resources/.htaccess
new file mode 100644
index 0000000..5286a6d
--- /dev/null
+++ b/src/site/resources/.htaccess
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Redirect /examples/deploy-signed-artifacts.html /usage.html
\ No newline at end of file
diff --git a/src/site/site.xml b/src/site/site.xml
index d237739..f2d34a2 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -24,13 +24,11 @@ under the License.
<item name="Introduction" href="index.html"/>
<item name="Plugin Documentation" href="plugin-info.html"/>
<item name="Usage" href="usage.html"/>
+ <item name="Passphrases" href="passphrase.html"/>
<item name="FAQ" href="faq.html"/>
<!-- According to https://issues.apache.org/jira/browse/MNGSITE-152 -->
<item name="License" href="http://www.apache.org/licenses/"/>
<item name="Download" href="download.html"/>
</menu>
- <menu name="Examples">
- <item name="Deploy Signed Artifacts"
href="/examples/deploy-signed-artifacts.html"/>
- </menu>
</body>
</site>
diff --git a/src/test/java/org/apache/maven/plugins/gpg/BcSignerTest.java
b/src/test/java/org/apache/maven/plugins/gpg/BcSignerTest.java
index 60e92a1..ffa13fd 100644
--- a/src/test/java/org/apache/maven/plugins/gpg/BcSignerTest.java
+++ b/src/test/java/org/apache/maven/plugins/gpg/BcSignerTest.java
@@ -85,7 +85,7 @@ class BcSignerTest {
}
@Test
- void testSingleKeyAsc() throws NoLocalRepositoryManagerException,
MojoFailureException {
+ void testSingleKeyAscViaSubkeyFingerprint() throws
NoLocalRepositoryManagerException, MojoFailureException {
DefaultRepositorySystemSession session = new
DefaultRepositorySystemSession();
session.setLocalRepositoryManager(new
SimpleLocalRepositoryManagerFactory(new DefaultLocalPathComposer())
.newInstance(session, new
LocalRepository("target/local-repo")));
@@ -106,6 +106,26 @@ class BcSignerTest {
signer.secretKey.getPublicKey().getAlgorithm());
}
+ @Test
+ void testPrimaryKeyAsc() throws NoLocalRepositoryManagerException,
MojoFailureException {
+ DefaultRepositorySystemSession session = new
DefaultRepositorySystemSession();
+ session.setLocalRepositoryManager(new
SimpleLocalRepositoryManagerFactory(new DefaultLocalPathComposer())
+ .newInstance(session, new
LocalRepository("target/local-repo")));
+ BcSigner signer = new BcSigner(
+ session,
+ "unimportant",
+ "unimportant",
+ "undefined",
+ new
File("src/test/resources/signing-key-with-multiple-subkeys.asc").getAbsolutePath(),
+ "CD251351B3EC94057BC44FD683CAA88765254A26"); // fingerprint is
the primary key
+ signer.setPassPhrase("TEST");
+ signer.setUseAgent(false);
+ signer.setInteractive(false);
+ signer.prepare();
+ // check key algorithm, must be DSA
+ assertEquals(PublicKeyAlgorithmTags.DSA,
signer.secretKey.getPublicKey().getAlgorithm());
+ }
+
@Test
void testFirstSubkeyFromAsc() throws NoLocalRepositoryManagerException,
MojoFailureException {
DefaultRepositorySystemSession session = new
DefaultRepositorySystemSession();