Skip to main content

Cloud Auth Library using PKCS-11

Python library which supports TPPKCS-11 embedded authenticated credentials for various cloud providers.

The supported set of providers and credential types:

on python pypi: https://pypi.org/project/cloud-auth-pkcs/

This code is not affiliated with or supported by google

Also see


Usage

You need to first embed an RSA key into a PKCS-11 device which is described below but is out of scope of this library

The following using SoftHSM /usr/lib/softhsm/libsofthsm2.so

GCPCredentials

If the GCP RSA key is embedded in token1 a with label keylabel1

from google.cloud import storage
from cloud_auth_pkcs.gcp.gcpcredentials import GCPCredentials

####  pip3 install cloud_auth_pkcs[gcp]
pc = GCPCredentials(
  module='/usr/lib/softhsm/libsofthsm2.so',
  token='token1',
  label='keylabel1',
  pin='123456',

  email="jwt-access-svc-account@$PROJECT_ID.iam.gserviceaccount.com")                    

storage_client = storage.Client(project="$PROJECT_ID", credentials=pc)

buckets = storage_client.list_buckets()
for bkt in buckets:
    print(bkt.name)
AWSCredentials

If the AWS RolesAnywhere RSA key is embedded in token1 a with label keylabel2

import boto3
from cloud_auth_pkcs.aws.awscredentials import AWSCredentials

####  pip3 install cloud_auth_pkcs[aws]
pc = AWSCredentials(
  module='/usr/lib/softhsm/libsofthsm2.so',
  token='token1',
  label='keylabel2',
  pin='123456',

  public_certificate_file="certs/alice-cert.crt",
  region="us-east-2",
  duration_seconds=1000,
  trust_anchor_arn='arn:aws:rolesanywhere:us-east-2:291738886522:trust-anchor/a545a1fc-5d86-4032-8f4c-61cdd6ff92ac',
  session_name="foo", 
  role_arn="arn:aws:iam::291738886522:role/rolesanywhere1",
  profile_arn="arn:aws:rolesanywhere:us-east-2:291738886522:profile/6f4943fb-13d4-4242-89c4-be367595c560")

session = pc.get_session()

s3 = session.resource('s3')
for bucket in s3.buckets.all():
    print(bucket.name)
AWSHMACCredentials

If the AWS HMAC Key is embedded in token1 a with label keylabel3

import boto3
from cloud_auth_pkcs.aws.awshmaccredentials import AWSHMACCredentials

####  pip3 install cloud_auth_pkcs[aws]
pc = AWSHMACCredentials(
  module='/usr/lib/softhsm/libsofthsm2.so',
  token='token1',
  label='keylabel3',
  pin='123456',

  access_key="AWS_ACCESS_KEY_ID",
  region="us-east-2",
  duration_seconds=1000,
  role_session_name="foo",
  assume_role_arn="arn:aws:iam::291738886522:role/gcpsts")

session = pc.get_session()

s3 = session.resource('s3')
for bucket in s3.buckets.all():
    print(bucket.name)
AzureCredentials

If the AWS HMAC Key is embedded in token1 a with label keylabel4

from azure.storage.blob import BlobServiceClient
from cloud_auth_pkcs.azure.azurecredentials import AzureCredentials

####  pip3 install cloud_auth_pkcs[azure]
pc = AzureCredentials(
  module='/usr/lib/softhsm/libsofthsm2.so',
  token='token1',
  label='keylabel4',
  pin='123456',

  tenant_id="45243fbe-b73f-4f7d-8213-a104a99e428e",
  client_id="cffeaee2-5617-4784-8a4b-b647efd676e1",
  certificate_path="certs/azclient.crt")

blob_service_client = BlobServiceClient(
    account_url="https://$STORAGE_ACCOUNT.blob.core.windows.net",
    credential=pc
)
container_client = blob_service_client.get_container_client('container_name')
blob_list = container_client.list_blobs()
for blob in blob_list:
    print(blob.name)

Configuration

Option Description
module Path to PKCS Module: (required; default: ``)
token Name of the PKCS TOKEN: (required; default: ``)
label Label set for the key (required; default: ``)
pin PIN for the token: (optional; default: ``)
GCPCredentials
Option Description
email ServiceAccount email (required; default: ``)
scopes Signed Jwt Scopes (optional default: "https://www.googleapis.com/auth/cloud-platform")
keyid ServiceAccount keyid (optional; default: ``)
expire_in Token expiration in seconds (optional; default: 3600)
AWSCredentials
Option Description
public_certificate_file Path to public x509 (required; default: ``)
region AWS Region (optional default: ``)
duration_seconds Duration in seconds for the token lifetime (optional; default: 3600)
trust_anchor_arn RolesAnywhere Trust anchor ARN (required; default: ``)
role_arn RolesAnywhere RoleArn (required; default: ``)
profile_arn RolesAnywhere Profile Arn (Required; default: ``)
session_name AWS Session Name (optional; default: ``)
AWSHMACCredentials
Option Description
region AWS Region (optional default: ``)
aws_access_key_id AWS_ACCESS_KEY_ID if using HMAC based credentials (required; default: ``)
duration_seconds Duration in seconds for the token lifetime (optional; default: 3600)
get_session_token If using GetSessionToken (optional; default: False)
assume_role_arn AssumeRole ARN (required if AssumeRole set; default: ``)
role_session_name RoleSessionName if AssumeRole set (optional; default: ``)
AzureCredentials
Option Description
tenant_id Azure TentantID (required; default: ``)
client_id Azure Application (client) ID (required; default: ``)
certificate_path x509 certificate to authenticate with (required; default ``)

Setup

This demo uses SoftHSM but you are free to use any other PKCS-11 compliant system

apt-get -y install libsofthsm2-dev opensc

# go to the example/ folder and set the path to the softhsm config:
cd example/
rm -rf /tmp/tokens
mkdir /tmp/tokens

export SOFTHSM2_CONF=`pwd`/softhsm.conf
export MODULE="/usr/lib/softhsm/libsofthsm2.so"

## initialize
pkcs11-tool --module $MODULE --list-mechanisms --slot-index 0
pkcs11-tool --module $MODULE  --slot-index=0 \
   --init-token --label="token1" --so-pin="123456"

pkcs11-tool --module $MODULE  --label="token1" \
   --init-pin --so-pin "123456" --pin mynewpin

## print mechanisms
pkcs11-tool --module $MODULE --list-mechanisms --slot-index 0

## print slot details
pkcs11-tool --module $MODULE --list-token-slots

Using RSA Keys on PKCS

First step is to acquire the private RSA keys for whichever provider you're interested in

Once you have the raw RSA private key in in regular PEM format, you can use pkcs11-tool to load the key.

Each provider has its own way to create the raw RSA key and associate it with a cloud credential. See instructions below for each provider.

Setup - GCP

This is an extension of GCP google-auth-python specifically intended to use service account credentials which are embedded inside a PCKS-11 device.

Setup a new key and download the json

export PROJECT_ID=`gcloud config get-value core/project`
export GCP_SA_EMAIL=jwt-access-svc-account@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create jwt-access-svc-account --display-name "Test Service Account"
gcloud iam service-accounts keys create jwt-access-svc-account.json --iam-account=$GCP_SA_EMAIL

gcloud projects add-iam-policy-binding $PROJECT_ID --member=serviceAccount:$GCP_SA_EMAIL --role=roles/storage.admin

## create a test bucket
export GCP_BUCKET=gs://$PROJECT_ID-test
gcloud storage buckets create gs://$GCP_BUCKET --project=$PROJECT_ID

Extract the key_id, email and the raw RSA key.

cat jwt-access-svc-account.json | jq -r '.private_key' > /tmp/rsakey.pem

## convert the rsa key to DER for importing
openssl rsa -text -in /tmp/rsakey.pem
openssl rsa -in /tmp/rsakey.pem -outform DER -out /tmp/gcp_key.der

Import /tmp/gcp_key.der into the device. Once the key is embedded into the device, you can discard the raw key

export MODULE="/usr/lib/softhsm/libsofthsm2.so"

pkcs11-tool  --module $MODULE --pin mynewpin \
   --write-object /tmp/gcp_key.der --type privkey --id 10 --label keylabel3 --slot-index 0

pkcs11-tool --module $MODULE --list-token-slots
pkcs11-tool --module $MODULE  --list-objects --pin mynewpin

Now test the

cd example/
pip3 install -r requirements-gcp.txt

python3 main_gcp.py --module="$MODULE" \
   --token="token1" --label="keylabel3" --pin="mynewpin" \
   --email="$GCP_SA_EMAIL" \
   --project_id="$GCP_PROJECT" --bucket="$GCP_BUCKET"

How it works:

GCP APIs allows for service account authentication using a Self-signed JWT with scope.

What that means is if you take a private key and generate a valid JWT with in the following format, you can just send it to the service as an auth token, that simple.

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "abcdef1234567890"
}
{
  "iss": "jwt-access-svc-account@$PROJECT_ID.iam.gserviceaccount.com",
  "sub": "jwt-access-svc-account@$PROJECT_ID.iam.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/cloud-platform",
  "iat": 1511900000,
  "exp": 1511903600
}

So since we have the RSA key on the TPM, we can use the ESAPI to make it "sign" data for the JWT.

Setup - AWS

AWS Roles Anywhere allows for client authentication based on digital signature from trusted private keys.

The trusted client RSA or EC key is embedded within a PKCS-11 device and that is used to sign the RolesAnywhere header values.

For a detailed example, see AWS SDK CredentialProvider for RolesAnywhere

The following example assumes you have setup RolesAnwwhere and the client certificate and key are available at awsclient.key and awsclient.crt

When you setup RolesAnywhere, note down the ARN for the TrustAnchorArn, ProfileArn and RoleArn as well as the region. Ideally, the role has AmazonS3ReadOnlyAccess to list buckets.

Then attempt to use the credentials and specify the specific ARN values

export AWS_PEM="/path/to/awsclient.key"
export AWS_CERT="/path/to/awsclient.crt"
export AWS_REGION="us-east-2"
export AWS_TRUST_ANCHOR_ARN="arn:aws:rolesanywhere:us-east-2:redacted:trust-anchor/redacted"
export AWS_ROLE_ARN="arn:aws:iam::redacted:role/cicd-role"
export AWS_PROFILE_ARN="arn:aws:rolesanywhere:us-east-2:redacted:profileredacted"
export AWS_HMAC_REGION="us-east-1"

### convert to der and importy the key
openssl rsa -in $AWS_PEM -outform DER -out /tmp/aws_key.der

pkcs11-tool  --module $MODULE --pin mynewpin \
   --write-object /tmp/aws_key.der --type privkey --id 10 --label keylabel5 --slot-index 0

pip3 install -r requirements-aws.txt

python3 main_aws.py --module="$MODULE" \
   --token="token1" --label="keylabel5" --pin="mynewpin" \
   --public_certificate_file="$AWS_CERT" \
   --region="$AWS_REGION" --trust_anchor_arn="$AWS_TRUST_ANCHOR_ARN" \
   --role_arn="$AWS_ROLE_ARN" \
   --profile_arn="$AWS_PROFILE_ARN"
AWS HMAC

AWS supports HMAC based authentication as well. see the following for a TPM equivalent: AWS Credentials for Hardware Security Modules and TPM based AWS_SECRET_ACCESS_KEY and specifically AWS v4 signed request using Trusted Platform Module

This repo includes an example setup and to use this, you need your AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY and embed the secret into the PKCS device and make it perform the HMAC

### first embed the hmac key with an optional password
export AWS_ACCESS_KEY_ID=recacted
export AWS_SECRET_ACCESS_KEY=redacted

## add the AWS4 prefix to the key per the signing protocol
export secret="AWS4$AWS_SECRET_ACCESS_KEY"
echo -n $secret > hmac.key

pkcs11-tool  --module $MODULE --pin mynewpin \
   --write-object /tmp/hmac.key --type secrkey --private --sensitive \
    --usage-sign --private --id 10 --label keylabel4 --slot-index 0 \
      --mechanism SHA256-HMAC 

pip3 install -r requirements-aws.txt

python3 main_aws_hmac.py --module="$MODULE" \
   --token="token1" --label="keylabel4" --pin="mynewpin" \
   --aws_access_key_id=$AWS_ACCESS_KEY \
   --region="$AWS_HMAC_REGION" \
   --assume_role_arn="$AWS_ROLE_ARN"

Setup - Azure

Azure authentication uses an the basic Microsoft identity platform application authentication certificate credentials where the variation here is that the client rsa key is on PKCS

The following example assumes you have set this up similar to

The following assumes you have configured Azure certificate based autentication and the certificate and key are available locally

export AZURE_CLIENT_ID=cffeaee2-5617-4784-8a4b-redacted
export AZURE_TENANT_ID=45243fbe-b73f-4f7d-8213-redacted
export AZURE_STORAGEACCOUNT=redacted
export AZURE_CONTAINER=redacted
export AZURE_CLIENT_PEM="/path/to/azureclient.key"
export AZURE_CERT="/path/to/azureclient.crt"

## test that you have the cert based auth working
az login --service-principal -u $CLIENT_ID -p $CERTIFICATE_PATH_COMBINED_DER --tenant=$TENANT_ID
az account get-access-token   --scope="api://$CLIENT_ID/.default"

## if the principal has access to a storage container, test that
export STORAGE_ACCOUNT=your-storage-account
export CONTAINER=your-container
export AZURE_TOKEN=$(az account get-access-token --resource https://storage.azure.com/ --query accessToken -o tsv)

curl -s --oauth2-bearer "$AZURE_TOKEN"  -H 'x-ms-version: 2017-11-09'  \
     "https://$STORAGE_ACCOUNT.blob.core.windows.net/$CONTAINER?restype=container&comp=list" | xmllint -  --format

## now you're ready to embed the key and test with the client using the embedded  key

openssl rsa -in $AZURE_CLIENT_PEM -outform DER -out /tmp/azure_key.der
pkcs11-tool  --module $MODULE --pin mynewpin \
   --write-object /tmp/azure_key.der --type privkey --id 10 --label keylabel6 --slot-index 0

pip3 install -r requirements-azure.txt

python3 main_azure.py --module="$MODULE" \
   --token="token1" --label="keylabel6" --pin="mynewpin" \
   --certificate_path="$AZURE_CERT" \
   --tenant_id="$AZURE_TENANT_ID" \
   --client_id="$AZURE_CLIENT_ID" \
   --storageaccount="$AZURE_STORAGEACCOUNT"  --container="$AZURE_CONTAINER"

Local Build

to generate the library from scratch and run local, run

python3 setup.py sdist bdist_wheel

cd example
virtualenv env
source env/bin/activate

pip3 install ../
## depending on the variant provider
# pip3 install -r requirements-gcp.txt 
# pip3 install -r requirements-aws.txt 
# pip3 install -r requirements-azure.txt 


### to deploy/upload
# virtualenv env 
# source env/bin/activate
# python3 -m pip install --upgrade build
# python3 -m pip install --upgrade twine
# python3 -m build
# python3 -m twine upload --repository testpypi dist/*
# python3 -m twine upload  dist/*

Metadata

Release files for cloud-auth-pkcs 0.0.21

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cloud-auth-pkcs 0.0.21
File Size Uploaded
cloud_auth_pkcs-0.0.21.tar.gz 24.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cloud-auth-pkcs 0.0.21
File Interpreter ABI Platform
cloud_auth_pkcs-0.0.21-py3-none-any.whl Python 3 none any Details

Total release size: 48.3 kB

Release files / cloud_auth_pkcs-0.0.21.tar.gz

Download URL cloud_auth_pkcs-0.0.21.tar.gz
Size 24.5 kB
Tags Source
SHA-256 checksum
How to use checksums
f91c408452d10dc1059d83e7dfd8a2e09595e2cfbe4d97575a04a87a17e8d344
BLAKE2b-256 checksum
How to use checksums
382fc7b8cbd6485b0b0298eae60594c5179a1a395a5c96e8efc0e1756b24d6dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2025.

Transparency log

Release files / cloud_auth_pkcs-0.0.21-py3-none-any.whl

Download URL cloud_auth_pkcs-0.0.21-py3-none-any.whl
Size 23.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f9f4a089fe52e7e74fd95106620360accd2bbc9a4eae60a23b64aac0ce691c4e
BLAKE2b-256 checksum
How to use checksums
b0983df3b41682f430ff80cef14050e8f3d7d40a0615a3587f501cbfe6888db9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.21 This release

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page