Skip to main content

Python TPM based Credentials for Cloud Providers

Project description

Cloud Auth Library using Trusted Platform Module (TPM)

Python library which supports TPM embedded credentials for various cloud providers.

Ath the moment, only GCP but followup with AWS and Azure when i find time (they're all implemented in golang, its just tedious to map to python)

For GCP:

This is an extension of GCP google-auth-python specifically intended to use service account credentials which are embedded inside a Trusted Platform Module (TPM).

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

>>WARNING<<: This code is not affiliated with or supported by google


Usage

  • GCPCredentials
from google.cloud import storage
from cloud_auth_tpm.gcp.gcpcredentials import GCPCredentials

### acquire credential source on the TPM
####  pip3 install cloud_auth_tpm[gcp]
pc = GCPCredentials(tcti="device:/dev/tpmrm0",
                    path="/HS/SRK/sign1",
                    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)
  • AWSHmacCredentials

    TODO

  • AWSRolesAnywhereCredentials

    TODO

  • AzureCredentials

    TODO


Common

| tcti | Path to TPM: (required; default: device:/dev/tpmrm0) | | path | Path to FAPI signing object (required; default: ``) | | profile | FAPI Profile name (optional; default: `P_RSA2048SHA256`) | | `system_dir` | FAPI system_dir (optional; default: `"/.local/share/tpm2-tss/system/keystore"`) | | `profile_dir` | FAPI profile_dir (optional; default: `"/etc/tpm2-tss/fapi-profiles"`) | | `user_dir` | FAPI user_dirs (optional; default: `"/.local/share/tpm2-tss/user/keystore/" `) |

For GCP Credentials

Option Description
email ServiceAccount email (required; default: ``)
scopes Signed Jwt Scopes (optional default: "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/userinfo.email")
keyid ServiceAccount keyid (optional; default: ``)
expire_in Token expiration in seconds (optional; default: 3600)

For AWS Credentials (HMAC)

TODO:

For AWS Credentials (Roles Anywhere)

TODO

For Azure Credentials

TODO


Setup

This library uses the Feature API provided through tpm2_pytss.

To install that:

## tpm2-tss > 4.1.0 https://github.com/tpm2-software/tpm2-tss
apt-get install libtss2-dev
python3 -m pip install tpm2-pytss

Setup - GCP

There are several ways you can have a TPM based service account key:

  1. create a key on the tpm, use it to create an x509 and upload the certificate
  2. import an the raw private key into the TPM
  3. securely transfer a key from on machine to the machine with the TPM and then import

This example will just cover (2) for simplicity. For more info, see oauth2/tpm2tokensource

For additional examples on using FAPI with python to perform operations, see salrashid123/tpm2/pytss

Once you install the FAPI, you will need to embed a service account key into the TPM.

Setup a new key and download the json

export PROJECT_ID=`gcloud config get-value core/project`

gcloud iam service-accounts create jwt-access-svc-account --display-name "Test Service Account"

export SERVICE_ACCOUNT_EMAIL=jwt-access-svc-account@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts keys create jwt-access-svc-account.json --iam-account=$SERVICE_ACCOUNT_EMAIL

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

Extract the key_id, email and the raw RSA key

export KEYID=`cat jwt-access-svc-account.json | jq -r '.private_key_id'`

export EMAIL=`cat jwt-access-svc-account.json | jq -r '.client_email'`

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

Now use the load.py FAPI commands to embed the key into the TPM and save it at FAPI path of your choice, eg /HS/SRK/sign1:

cd example/
pip3 install -r requirements.txt

# rm -rf ~/.local/share/tpm2-tss   # warning, this'll delete fapi objects you have
python3 load_gcp.py --path="/HS/SRK/sign1" --private_key=/tmp/private.pem --tcti=device:/dev/tpmrm0 # --tcti="swtpm:port=2321"


### then run:
python3 main_gcp.py --path=/HS/SRK/sign1 --email=$EMAIL --project_id=$PROJECT_ID --tcti=device:/dev/tpmrm0  # --tcti="swtpm:port=2321"
How it works - GCP

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 FAPI to make it "sign" data for the JWT.

Setup - AWS

HMAC

TODO: once FAPI supports hmac

ref: AWS Credentials for Hardware Security Modules and TPM based AWS_SECRET_ACCESS_KEY

Roles Anywhere

TODO: support AWA RolesAnywhere Signer

Setup - Azure

TODO: KMS, TPM and HSM based Azure Certificate Credentials

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 ../
pip3 install -r requirements-gcp.txt 

Software TPM

If you want to test locally, you can use a software TPM swtpm:

rm -rf /tmp/myvtpm && mkdir /tmp/myvtpm
sudo swtpm_setup --tpmstate /tmp/myvtpm --tpm2 --create-ek-cert 
sudo swtpm socket --tpmstate dir=/tmp/myvtpm --tpm2 --server type=tcp,port=2321 --ctrl type=tcp,port=2322 --flags not-need-init,startup-clear  --log level=5

Once its setup, you can export the following environment variables and use this with tpm2_tools

export TPM2TOOLS_TCTI="swtpm:port=2321"
export TPM2OPENSSL_TCTI="swtpm:port=2321"

tpm2_flushcontext -t && tpm2_flushcontext -s && tpm2_flushcontext -l

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cloud_auth_tpm-0.0.41.tar.gz (10.0 kB view hashes)

Uploaded Source

Built Distribution

cloud_auth_tpm-0.0.41-py3-none-any.whl (10.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page