Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Add support for imersonated_credentials.Sign, IDToken#348

Merged
busunkim96 merged 7 commits intogoogleapis:masterfrom
salrashid123:add-idtoken-signer-impersonated
Aug 7, 2019
Merged

Add support for imersonated_credentials.Sign, IDToken#348
busunkim96 merged 7 commits intogoogleapis:masterfrom
salrashid123:add-idtoken-signer-impersonated

Conversation

@salrashid123
Copy link
Contributor

Adds support for impersonated_credentials to sign and issue IDTokens.

impersonated_credentials uses IAMCredentials api at its core which also provides interfaces to generateIDToken() and signBlob():

This PR seesk to add support for those.

Some benefits:


The PR at the moment does not have sufficient test coverage (its a solid "C" at 75%). I'm unsure how to mock the internal request/responses since i used AuthorizedSession() internally within imersonated_credentials.py. Any tips or pointers there would let me add on coverage. I've left the anticipated responses i would like as comments in this current commit


Anyway, usage would be like this to sign and genrate ID tokens (i've verified the following works)

from google.oauth2 import id_token
from google.oauth2 import service_account
from google.auth import impersonated_credentials
import json
import google.auth
from google.auth import jwt
import google.auth.transport.requests
import base64
import os
from datetime import datetime, timedelta
from google.cloud import storage

from google.auth.transport.requests import AuthorizedSession


source_credentials = service_account.Credentials.from_service_account_file(
    '/path/to/svc.json')
target_scopes = ['https://www.googleapis.com/auth/cloud-platform']

target_credentials = impersonated_credentials.Credentials(
    source_credentials = source_credentials,
    target_principal='impersonated-account@fabled-ray-104117.iam.gserviceaccount.com',
    target_scopes = target_scopes,
    delegates=[],
    lifetime=300)

# =====================   Sign

# signer anything you want as the impersonated credentials
b = target_credentials.sign_bytes('badff')
print base64.b64encode(b)


storage_client = storage.Client('fabled-ray-104117', target_credentials)
data_bucket = storage_client.lookup_bucket('fabled-ray-104117')
signed_blob_path = data_bucket.blob("FILENAME")
expires_at_ms = 30 * 60 *60
print expires_at_ms
signed_url = signed_blob_path.generate_signed_url(expires_at_ms, credentials=target_credentials, version="v4")

print signed_url

# =====================   IDToken

target_audience = 'https://your.cloud.run.app'

id_creds = impersonated_credentials.IDTokenCredentials(
    target_credentials, target_audience=target_audience)

url = 'https://your.cloud.run.app'
authed_session = AuthorizedSession(id_creds)
r = authed_session.get(url)

@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Jun 19, 2019
@salrashid123
Copy link
Contributor Author

@theacodes @busunkim96

Any pointers on how i can mock the embedded AuthorizedSession() (or for that matter, if i should even be using it in the implementation)? Once i get through that, i'll add on the other testcases for coverage

@yoshi-automation yoshi-automation added 🚨 This issue needs some love. and removed 🚨 This issue needs some love. labels Jun 26, 2019
@salrashid123
Copy link
Contributor Author

@theacodes @busunkim96
hi- Could we startoff the review cycle on this one? if we're awaiting coverage/tests to pass, i could stand to get a pointer to fix that.

@salrashid123
Copy link
Contributor Author

@theacodes Could we start on the review on this? As mentioned offline, i'm unsure about how to create the testcases that compount two request

Copy link
Contributor

@busunkim96 busunkim96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your patience @salrashid123!

I left a few comments below and will get back to you tomorrow morning on the test cases. You can disregard the current test failure in Travis; it was because of a change to pytest (#353).

Copy link
Contributor

@busunkim96 busunkim96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more comments on raising test coverage

@salrashid123
Copy link
Contributor Author

@busunkim96
@JustinBeckwith
anything additional you'd like to add to the PR

@busunkim96 busunkim96 requested review from tswast and removed request for theacodes August 6, 2019 00:14
Copy link
Contributor

@busunkim96 busunkim96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for all your patience @salrashid123.

@tswast, could you also take a look?

@salrashid123
Copy link
Contributor Author

ok, i'm gonna give one more round of end-to-end testing for all the modes later today (just to be sure).

Ill reply back here before final merge.

thanks for the reviews!

@salrashid123
Copy link
Contributor Author

verified the follwoing works with the final fileset in the last commit

from google.oauth2 import id_token
from google.oauth2 import service_account
from google.auth import impersonated_credentials
import json
import google.auth
from google.auth import jwt
import google.auth.transport.requests
import base64
import os
from datetime import datetime, timedelta

from google.auth.transport.requests import AuthorizedSession
from google.cloud import storage

source_credentials = service_account.Credentials.from_service_account_file(
    '/path/to/svc.json')
target_scopes = ['https://www.googleapis.com/auth/cloud-platform']

target_credentials = impersonated_credentials.Credentials(
    source_credentials = source_credentials,
    target_principal='impersonated-account@fabled-ray-104117.iam.gserviceaccount.com',
    target_scopes = target_scopes,
    delegates=[],
    lifetime=300)

# =====================   SignedURL


client = storage.Client("fabled-ray-104117", target_credentials )

bucket = client.get_bucket('fabled-ray-104117')
blob = bucket.get_blob('signed_url_file.txt')
s = blob.generate_signed_url(expiration=60, method="GET", version="v4")
print s


# =====================   IDToken

target_audience = 'https://myapp-6w42z6vi3q-uc.a.run.app'
id_creds = impersonated_credentials.IDTokenCredentials(
    target_credentials, target_audience=target_audience, include_email=False)

url = 'https://myapp-6w42z6vi3q-uc.a.run.app'
authed_session = AuthorizedSession(id_creds)
r = authed_session.get(url)

print r.status_code
print r.text

# verify
certs_url='https://www.googleapis.com/oauth2/v1/certs'
request = google.auth.transport.requests.Request()
idt = id_creds.token
print idt
print id_token.verify_token(idt,request,certs_url=certs_url)

@busunkim96 busunkim96 merged commit 7a8641a into googleapis:master Aug 7, 2019
@salrashid123 salrashid123 deleted the add-idtoken-signer-impersonated branch August 12, 2019 02:32
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

cla: yes This human has signed the Contributor License Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants