GCP x509 Workload Federation in python using TPM based authentication and openssl
assume you have a workload federation trusted cert and PEM key (workload3.crt
, workload3.key
), the following will embed the key into the tpm. Workload federation will use the tpm-based key for mtls.
you can ofcourse create the key inside the tpm or securely import it. those options are described here
apt-get update
apt -y install autoconf-archive libcmocka0 libcmocka-dev procps iproute2 build-essential git pkg-config gcc libtool automake libssl-dev uthash-dev autoconf doxygen libcurl4-openssl-dev dbus-x11 libglib2.0-dev libjson-c-dev acl swtpm swtpm-tools python3-pip python3-requests python3-flask
cd
git clone https://github.com/tpm2-software/tpm2-tss.git
cd tpm2-tss
./bootstrap
./configure --with-udevrulesdir=/etc/udev/rules.d
make -j$(nproc)
make install
udevadm control --reload-rules && sudo udevadm trigger
ldconfig
cd
git clone https://github.com/tpm2-software/tpm2-tools.git
cd tpm2-tools
./bootstrap
./configure
make install
cd
git clone https://github.com/tpm2-software/tpm2-openssl.git
cd tpm2-openssl
./bootstrap
./configure
make install
printf '\x00\x00' > /tmp/unique.dat
tpm2_createprimary -C o -G ecc -g sha256 \
-c primary.ctx \
-a "fixedtpm|fixedparent|sensitivedataorigin|userwithauth|noda|restricted|decrypt" -u /tmp/unique.dat
tpm2_import -C primary.ctx -G ecc256:ecdsa -i workload3.key -u key.pub -r key.priv
tpm2_encodeobject -C primary.ctx -u key.pub -r key.priv -o workload3_tpm.key
$ cat cert_config.json
{
"cert_configs": {
"workload": {
"cert_path": "/root/python_tls/workload3.crt",
"key_path": "/root/python_tls/workload3_tpm.key"
}
}
}
$ cat sts-creds-mtls.json
{
"universe_domain": "googleapis.com",
"type": "external_account",
"audience": "//iam.googleapis.com/projects/995081019036/locations/global/workloadIdentityPools/cert-pool-1/providers/cert-provider-1",
"subject_token_type": "urn:ietf:params:oauth:token-type:mtls",
"token_url": "https://sts.mtls.googleapis.com/v1/token",
"credential_source": {
"certificate": {
"certificate_config_location": "/root/python_tls/cert_config.json"
}
},
"token_info_url": "https://sts.mtls.googleapis.com/v1/introspect"
}
create openssl.cnf
:
$ cat openssl.cnf
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
tpm2 = tpm2_sect
[default_sect]
activate = 1
[tpm2_sect]
activate = 1
export OPENSSL_CONF=`pwd`/openssl.cnf
$ openssl list --providers
Providers:
default
name: OpenSSL Default Provider
version: 3.0.15
status: active
tpm2
name: TPM 2.0 Provider
version: 1.2.0-25-g87082a3
status: active
Print the TPM based key details
cat workload3_tpm.key
-----BEGIN TSS2 PRIVATE KEY-----
MIIBEgYGZ4EFCgEDoAMBAf8CBEAAAAEEWgBYACMACwAEAEAAAAAQABgACwADABAA
IMzaHMjj+kYAU8ipJA5bgBHQgrxvP7Z1/izmUfvxYsrKACD4QFAH3thp8NOq+vba
kow82CcbRp5Tle+159cd0k3lrwSBoACeACAEwQLyGtSn/aqweqAM5mhMjRy6SbDE
kACG6pT52zOG7AAQW/YAj3eHwPNH9ny+bz9A4I8h9boqf5bIdzZ+wJJGBGSb3Edj
n1HiFZdzkDghmLLscoKZ1XrBU9FBKinNJOacprgJYhj6/lYUfPxpwTOgVCa7CUSi
yc5LN73ncZtSRVh+nuSJLI6DTQjO7IhY0DA0hOvprTZkRduiaa0=
-----END TSS2 PRIVATE KEY-----
$ openssl ec -provider tpm2 -provider default -in workload3_tpm.key --text
read EC key
Private-Key: (EC P-256, TPM 2.0)
Parent: 0x40000001
pub:
04:cc:da:1c:c8:e3:fa:46:00:53:c8:a9:24:0e:5b:
80:11:d0:82:bc:6f:3f:b6:75:fe:2c:e6:51:fb:f1:
62:ca:ca:f8:40:50:07:de:d8:69:f0:d3:aa:fa:f6:
da:92:8c:3c:d8:27:1b:46:9e:53:95:ef:b5:e7:d7:
1d:d2:4d:e5:af
ASN1 OID: prime256v1
Object Attributes:
userWithAuth
sign / encrypt
writing EC key
unable to write EC key
Create a gcp storage client
client.py
from google.cloud import storage
storage_client = storage.Client('your-project')
bucket_name = "your-bucket"
file_name = "foo.txt"
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(file_name)
file_content = blob.download_as_string()
print(file_content)
Finally,
export GOOGLE_API_USE_CLIENT_CERTIFICATE=true
export GOOGLE_API_USE_MTLS_ENDPOINT=always
export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/sts-creds-mtls.json
export OPENSSL_CONF=`pwd`/openssl.cnf
pip3 install pyOpenSSL google-cloud-storage
python3 client.py