This library (and command line utlity) allows to use AWS KMS keys (RSA only, for now) to generate GnuPG / OpenPGP compatible signatures (v4).
Your mileage might vary (whether you use the AWS console, AWS cli, or tools like CloudFormation or Terraform) but overall any RSA "signing" key can be used.
By default the User ID associated with the key will be something along the
lines of PgpKms-AwsWrapper (...uuid...)
where uuid
is the random UUID
associated with the key in KMS.
In order to properly specify a User ID in the format of Name <email@domain>
we can use a couple of tags on the AWS key itself:
PGPName
: theName
part of the User ID.PGPEmail
: theemail@domain
part of the User ID.
The pgpkms
module provides a quick, minimalistic command line able to
export the public key, or sign a file:
python3 -m pgpkms <command> [options]
or just pgpkms <command> [options]
if the package is installed in a python virtualenv and env is activated.
export
: Export the public key in a PGP-compatible format.sign
: Sing some data and write a detached PGP signature.message
: Wrap a plaintext in a PGP message and sign it.
-
-o <file>
or--output <file>
Use the specified file as output instead of stdout. -
-i <file>
or--input <file>
Use the specified file as input instead of stdin. -
-b
or--binary
Do not armour the output (ignored when command ismessage
). -
--sha256
or--sha384
or--sha512
Use the specified hashing algorithm.
PGP_KMS_KEY
: The default ID, ARN or alias of the key to use.GPG_KEY_EXPIRATION
: Public GPG key expiration time, in days, to be used for the key during theexport
commandPGP_KMS_HASH
: The hashing algorithm to use (default tp "sha256").GPG_KEY_FINGERPRINT
: Set this to reduce the amount of requests to KMS during Git commit signing (optionally, but highly recommended)
In addition, AWS variables for the boto
AWS Python module:
AWS_ACCESS_KEY_ID
: AWS Service account key idAWS_SECRET_ACCESS_KEY
: AWS Service account secret keyAWS_DEFAULT_REGION
: AWS Region of the key
Export the (unarmoured) public key into the "trusted.gpg" file.
$ python3 -m pgpkms export --binary --output trusted.gpg
Sign the file "myfile.bin" and emit the armoured signature to stdout.
$ python3 -m pgpkms sign --input myfile.bin
First, create and activate a Python virtualenv by
python3 -m venv venv
source venv/bin/activate
Install the whole package by pip3 install .
from the root of the repo, it will make pgpkms-git
and pgpkms
scripts quickly accessible.
Prepare GPG:
- use
gpg --import
to import an already prepared KMS-based GPG key
OR (not recommended, since it produces more versions of public keys):
- export the public key to the local gpg:
pgpkms export | gpg --import
- obtain the fingerprint of the key:
pgpkms export | gpg --show-key
Then configure the local git:
git config --local commit.gpgsign true
git config --local gpg.program pgpkms-git
git config --local user.name <What is in the PGPName tag above>
git config --local user.email <What was in the PGPEmail tag above>
git config --local user.signingKey <GPG Key fingerprint>
A normal git commit
will produce a signed commit.
However, reading git signatures like git log --show-signature
won't be supported, it is needed to change gpg.program
back to gpg
, to verify the signatures, because this signing workflow is only designed for securely signing in the pipelines.
First, create and activate a Python virtualenv by
python3 -m venv venv
source venv/bin/activate
Install the whole package by pip3 install .
from the root of the repo, it will make pgpkms-reprepro
, pgpkms
and prepare-to-gpg-clearsign
scripts quickly accessible.
Prepare GPG:
- use
gpg --import
to import an already prepared KMS-based GPG key
OR (not recommended, since it produces more versions of public keys):
- export the public key to the local gpg:
pgpkms export | gpg --import
- obtain the fingerprint of the key:
pgpkms export | gpg --show-key
Then configure the reprepro instance. It is needed to leverage the SignWith setting in the hook mode, as it described there:
SignWith: ! /path/to/pgpkms-reprepro
, i.e. an exclamation mark followed by a space and the full or relative path to a hook script to call. Use which pgpkms-reprepro
to quickly get it.
Simply import the package and look for the KmsPgpKey
class documentation:
import pgpkms
help(pgpkms.KmsPgpKey)
This is summarized as follows:
The KmsPgpKey
class wraps an AWS KMS key and is capable of producing
signatures compatible with GnuPG / OpenPGP.
-
key_id
: The ID, ARN or alias of the AWS KMS key. -
kms_client
: A BotoCore KMS client, ifNone
this will be initialized as:session = botocore.session.get_session() kms_client = session.create_client('kms')
Return the public key from AWS KMS wrapped in an OpenPGP v4 key format as a
bytes
string.
hash
: The hashing algorithm used to prepare the self-signature of the public key.armoured
: Whether the returned key should be armoured (text) or not (binary).kms_client
: A BotoCore KMS client (optional).
Sign the specified input using this key, and return the signature in a format
compatible with GnuPG / OpenPGP as a bytes
string.
input
: The data to be signed.hash
: The hashing algorithm used to sign the data.armoured
: Whether the returned signature should be armoured (text) or not (binary).kms_client
: A BotoCore KMS client (optional).
This method returns a bytes
string containing the GnuPG / OpenPGP formatted
signature.
Sign the specified TEXT input using this key, writing the signed message AND signature to the output specified.
input
: The data to be signed.output
: Where to write the output.hash
: The hashing algorithm used to sign the data.kms_client
: A BotoCore KMS client (optional).
If output was None
, this method returns a string containing the GnuPG /
OpenPGP formatted message and signature.
Compared with the original v1.0.7 by Juit Developers:
-
1.3.0: Support for Debian Repository manager reprepro
-
1.2.1: Move expiration date parameter to
to_pgp
method instead of the whole class, to fix the signatures -
1.2.0: add
GPG_KEY_EXPIRATION
env variable for the GPG public key, GPG keys can expire -
1.1.1: add
GPG_KEY_FINGERPRINT
env variable for Git commit signing -
1.1.0: adds GPG commit signing emulation
-
1.0.8: makes the
PGP_KMS_KEY
environmental variable really working, and removes the hardcoded key name from the code. Removes the-k
option from the list of options as not really used. -
1.0.7: Origial Python package by Juit Developers