From 4e236a219abb08c7820d64fc998232c83a84223c Mon Sep 17 00:00:00 2001 From: Denis Loginov Date: Sat, 15 Aug 2020 18:00:10 -0400 Subject: [PATCH] Upload pubkey through Google Cloud SDK --- .gitignore | 2 ++ README.md | 31 +++++++++++++------------------ google_yubikey/__init__.py | 37 +++---------------------------------- setup.py | 1 - 4 files changed, 18 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 0c88a85..a452449 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ *_cache* *cache_* .vscode/* + +**.pem diff --git a/README.md b/README.md index 8863424..5a43257 100644 --- a/README.md +++ b/README.md @@ -39,42 +39,37 @@ pip3 install google-yubikey or to renew it after expiration: ``` - google-yubikey generate-key + google-yubikey generate-key > yubikey.pem ``` -3. Install and authenticate with - [Google Cloud SDK](https://cloud.google.com/sdk/install): +3. Install [Google Cloud SDK](https://cloud.google.com/sdk/install) and run: ``` - gcloud auth application-default login + gcloud auth login + gcloud beta iam service-accounts keys upload yubikey.pem \ + --iam-account + gcloud auth revoke # optional, but recommended ``` - This is needed only for initially setting up YubiKey with a Service Account. + This is needed only for setting up YubiKey with a Service Account. Your user account must have at least `Service Account Key Admin` role or `iam.serviceAccountKeys.create` permission on the target Service Account(s). -4. Run this once to associate your YubiKey with each Service Account: - - ``` - google-yubikey upload-key -a - ``` - -5. As a good practice, revoke your Google Cloud SDK credentials, + As a good practice, the last command revokes your Google Cloud SDK credentials, which limits the potential for their exposure - only to the time of the public key upload: + only to the time of the public key upload. - ``` - gcloud auth application-default revoke - ``` + Alernatively to step 3, you can upload `yubikey.pem` from step 2 via + Google Cloud Console for the target Service Account(s). -6. Run this every time you'd like to generate a Service Account token: +4. Run this every time you'd like to generate a Service Account token: ``` google-yubikey token -a ``` -7. Further customization options are available through: +5. Further customization options are available through: ``` google-yubikey [] -h diff --git a/google_yubikey/__init__.py b/google_yubikey/__init__.py index bb7233c..b52d44b 100755 --- a/google_yubikey/__init__.py +++ b/google_yubikey/__init__.py @@ -18,9 +18,7 @@ import warnings import requests -from click import Context, Command from cryptography.hazmat.primitives import serialization -from googleapiclient.discovery import build as google_api from ykman.descriptor import open_device from ykman.cli.util import prompt_for_touch from ykman.piv import \ @@ -51,7 +49,6 @@ def convert(str_value: str): class Action(ArgEnum): """ Action type """ GENERATE_KEY = 1 - UPLOAD_KEY = 2 TOKEN = 3 @@ -131,16 +128,6 @@ def parse_args(): help='Prompt for management key', ) - # "upload-key" action - parser_upload_key = subparsers.add_parser( - str(Action.UPLOAD_KEY), - help='Associate public key of the YubiKey with a Service Account', - ) - parser_upload_key.add_argument( - '-a', '--service-account-email', required=True, - help='Service Account email', - ) - # "token" action parser_token = subparsers.add_parser( str(Action.TOKEN), @@ -210,6 +197,7 @@ def gen_private_key(yubikey: YubiKey, slot: SLOT, prompt_management_key: bool, slot.value, public_key, subject, start, end, touch_callback=prompt_for_touch, ) + return get_public_key(yubikey, slot) def get_public_key(yubikey: YubiKey, slot: SLOT): @@ -218,22 +206,6 @@ def get_public_key(yubikey: YubiKey, slot: SLOT): return cert.public_bytes(serialization.Encoding.PEM) -def upload_pubkey(service_account_email: str, public_key: bytes): - """ Registers Google Service Account public key """ - info('Uploading public key...') - warnings.filterwarnings( - "ignore", "Your application has authenticated using end user credentials" - ) - # pylint: disable=maybe-no-member - response = google_api('iam', 'v1').projects().serviceAccounts().keys().upload( - name=f'projects/-/serviceAccounts/{service_account_email}', - body={ - 'publicKeyData': b64encode_str(public_key), - }, - ).execute() - return response['name'].split('/')[-1] - - def b64encode_str(bbytes: bytes): """ Encodes bytes as base64 string """ return b64encode(bbytes).decode('utf-8') @@ -293,15 +265,12 @@ def main(): yubikey = get_yubikey() if args.action == str(Action.GENERATE_KEY): - gen_private_key( + public_key = gen_private_key( yubikey, args.slot, args.prompt_management_key, args.pin_policy, args.touch_policy, args.subject, args.valid_days, ) - elif args.action == str(Action.UPLOAD_KEY): - public_key = get_public_key(yubikey, args.slot) - key_id = upload_pubkey(args.service_account_email, public_key) - info(f'Key id: {key_id}') + print(public_key.decode('utf-8')) else: id_token = get_id_token( yubikey, args.slot, args.prompt_management_key, diff --git a/setup.py b/setup.py index 01a0e26..f4c70d9 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,6 @@ 'relative_to': __file__, }, install_requires=[ - 'google-api-python-client >= 1.10.0', 'requests >= 2.24.0', 'yubikey-manager >= 3.1.1', ],