Google KMS on AppEngine / Python & Development AppServer

From it is not clear how you can use the Google Key Management System (KMS) in the Google App Engine standard, especially when developing local using the development server.

It would look simple enough:

  • Installing google-api-python-client

    in Python virtual env (and adding virtual path from google.appengine.ext.vendor

    to appengine_config.py

    )
  • import googleapiclient.discovery

  • getting app id using google.appengine.api.app_identity

  • Client usage kms

    as expected / documented

... then follow the guide linked to the documentation. However, my attempts so far have been unsuccessful and it seems the documentation wants to follow a few steps.

It looks like I'm breaking new ground that I'm sure others should already have.

Has anyone documented the use of Google KMS in the App Engine standard and its local development server?

EDIT - update with sample code

Here's some code that illuminates - the problem will be with my default credentials setup.

mykms.py

import googleapiclient.discovery
from google.appengine.api import app_identity

from oauth2client.client import GoogleCredentials
credentials = GoogleCredentials.get_application_default()

PROJECT = 'my-crypto-project'
IS_LOCAL = True
LOCATION = 'global'
TESTING_KR = 'testing-keyring'
KEY_RING = TESTING_KR if IS_LOCAL else app_identity.get_application_id()

kms = googleapiclient.discovery.build('cloudkms', 'v1', credentials=credentials)

def encrypt(plaintext, cryptokey, keyring=KEY_RING, location=LOCATION):
    name = 'projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}'.format(
        PROJECT, location, keyring, cryptokey
    )
    cryptokeys = kms.projects().locations().keyRings().cryptoKeys()
    request = cryptokeys.encrypt(name=name, body={'plaintext': plaintext})
    return request.execute()


def decrypt(ciphertext, cryptokey, keyring=KEY_RING, location=LOCATION):
    name = 'projects/{}/locations/{}/keyRings/{}/cryptokey'.format(
        PROJECT, location, keyring
    )
    cryptokeys = kms.projects().locations().keyRings().cryptoKeys()
    request = cryptokeys.decrypt(name=name, body={'ciphertext': ciphertext})
    return request.execute()

      

Now call through dev_appserver.py

:

import mykms
mykms.encrypt("my text", cryptokey="my-key-ring")

      

gives error:

HttpError: https://cloudkms.googleapis.com/v1/projects/np-crypto/locations/global/keyRings/localhost-testing/cryptoKeys/machine-identifiers:encrypt?alt=json returns "The request had an invalid authentication credentials Expected OAuth 2 access token, login cookie, or other valid credentials. See https://developers.google.com/identity/sign-in/web/devconsole-project . " >

This is not particularly useful as it mostly concerns Google login to the website; however, when I import mykms

from the command line, I get the error:

The default credentials for the app are not available. They are available if they are running on the Google Compute Engine. Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined to point to the file that defines the credentials. See https://developers.google.com/accounts/docs/application-default-credentials for details .

At the moment, this seems to be correct. Will reset it and report back.

EDIT # 2

Now the application connects to KMS. I deleted and went to gcloud auth application-default login

.

However, there is a strange side effect - something like a disk scan, and hundreds of messages (presumably for every available directory as root), like the following log mess:

INFO Jun 30, 2017 20:06:57 Sandbox denied access to file "/ Users"

INFO 30 Jun 2017 20:06:57 If it is a static file, check that application_readable: true

app.yaml is installed in your application

0


source to share


1 answer


If you are developing Cloud KMS in GAE you don't have a local dev service, you can only communicate with the main production service as you go. You could use libraries as you detailed to develop locally, but will still run into production.

Please note that you will need to provide default credentials for GAE using scope, see https://cloud.google.com/kms/docs/accessing-the-api#google_app_engine



You can also make requests as a GAE service account if you use gcloud iam service-accounts keys

and gcloud auth activate-service-account

.

In general, for a dev environment, you can segment this as a separate KeyRing (or even a separate project) from your production resources.

+2


source







All Articles