Google Service Account Credentials are available in two file formats: Json and P12. P12 is also known as PFX. The following code shows how to use P12 credentials to list the buckets in Google Cloud Storage without using an SDK.

Note: The P12 file format is deprecated. The Google recommended format is now Json.

You will need the Google Service Account Email address, Service Account Credentials in P12 format, the P12 password (defaults to notasecret) and your project Id (gcloud config list project)

The P12 file is processed and the Private Key is loaded into memory to be used to sign a Json Web Token (JWT). This Signed-JWT (JWS) is then passed to a Google OAuth 2.0 endpoint to be exchanged for a Bearer Access Token. This token is then used in the HTTP Authorization header to authorize Google API calls.

The HTTP headers for a Google API request look like this:

Host: www.googleapis.com
Authorization: Bearer + token
Content-Type: application/json

Example Python 3.x source code:

############################################################
# Version 1.00
# Date Created: 2018-12-21
# Last Update:  2018-12-21
# https://www2.jhanley.com
# Copyright (c) 2018, John J. Hanley
# Author: John Hanley
############################################################

'''
List a project's buckets using a P12 Service Account Credentials.
This code is written for Python 3.x and does not use the Google SDKs.

https://developers.google.com/identity/protocols/OAuth2ServiceAccount#authorizingrequests
'''

import json
import time
import jwt
import httplib2
import requests
import OpenSSL.crypto

# Project ID for this request
project = 'development-123456'

# Create the HTTP url for the Google Storage REST API
url = "https://www.googleapis.com/storage/v1/b?project=" + project

# Google Endpoint for creating OAuth 2.0 Access Tokens from Signed-JWT
auth_url = "https://www.googleapis.com/oauth2/v4/token"

# Set how long this token will be valid in seconds
expires_in = 3600	# Expires in 1 hour

#scopes = "https://www.googleapis.com/auth/cloud-platform"
scopes = "https://www.googleapis.com/auth/devstorage.read_only"

# Details on the Google Service Account. The email must match the Google Console.
sa_filename = 'compute-engine.p12'
sa_password = 'notasecret'
sa_email = '123456789012-compute@developer.gserviceaccount.com'

def load_private_key(p12_path, p12_password):
	''' Read the private key and return as base64 encoded '''

	# print('Opening:', p12_path)
	with open(p12_path, 'rb') as f:
		data = f.read()

	# print('Loading P12 (PFX) contents:')
	p12 = OpenSSL.crypto.load_pkcs12(data, p12_password)

	# Dump the Private Key in PKCS#1 PEM format
	pkey = OpenSSL.crypto.dump_privatekey(
			OpenSSL.crypto.FILETYPE_PEM,
			p12.get_privatekey())

	# return the private key
	return pkey

def requestToken(p12_path, p12_password, p12_email, scope):
	''' Create an AccessToken from a service account p12 credentials file '''

	pkey = load_private_key(p12_path, p12_password)

	issued = int(time.time())
	expires = issued + expires_in	# expires_in is in seconds

	# Note: this token expires and cannot be refreshed. The token must be recreated

	# JWT Headers
	additional_headers = {
			"alg": "RS256",
			"typ": "JWT"	# Google uses SHA256withRSA
	}

	# JWT Payload
	payload = {
		"iss": p12_email,	# Issuer claim
		"sub": p12_email,	# Issuer claim
		"aud": auth_url,	# Audience claim
		"iat": issued,		# Issued At claim
		"exp": expires,		# Expire time
		"scope": scope		# Permissions
	}

	# Encode the headers and payload and sign creating a Signed JWT (JWS)
	sig = jwt.encode(payload, pkey, algorithm="RS256", headers=additional_headers)

	# JWT Grant type
	params = {
		# JWT Bearer Token Grant Type Profile for OAuth 2.0
		"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
		"assertion": sig
	}

	# Call the Google Endpoint to create a Bearer Access Token
	r = requests.post(auth_url, data=params)

	#print(r.json())

	if r.ok:
		return(r.json()['access_token'], '')

	return None, r.text

token, err = requestToken(sa_filename, sa_password, sa_email, scopes)

if token is None:
	print('Error: Cannot get credentials')
	print(err)
	exit(1)

#print(url)

# HTTP request headers
headers = {
		"Host": "www.googleapis.com",
		"Authorization": "Bearer " + token,
		"Content-Type": "application/json"
	 }

h = httplib2.Http()

resp, content = h.request(uri=url, method="GET", headers=headers)

s = content.decode('utf-8').replace('\n', '')

j = json.loads(s)

print('')
print('Buckets')
print('----------------------------------------')
for item in j['items']:
	print(item['name'])