feat(iam): Support the mTLS IAM domain for Certificate based Access (… · googleapis/google-auth-library-python@8dcf91a

@@ -22,12 +22,14 @@

2222

import base64

2323

import http.client as http_client

2424

import json

25+

import os

25262627

from google.auth import _exponential_backoff

2728

from google.auth import _helpers

2829

from google.auth import credentials

2930

from google.auth import crypt

3031

from google.auth import exceptions

32+

from google.auth.transport import mtls

31333234

IAM_RETRY_CODES = {

3335

http_client.INTERNAL_SERVER_ERROR,

@@ -38,25 +40,33 @@

38403941

_IAM_SCOPE = ["https://www.googleapis.com/auth/iam"]

404241-

_IAM_ENDPOINT = (

42-

"https://iamcredentials.googleapis.com/v1/projects/-"

43-

+ "/serviceAccounts/{}:generateAccessToken"

44-

)

45-46-

_IAM_SIGN_ENDPOINT = (

47-

"https://iamcredentials.googleapis.com/v1/projects/-"

48-

+ "/serviceAccounts/{}:signBlob"

49-

)

50-51-

_IAM_SIGNJWT_ENDPOINT = (

52-

"https://iamcredentials.googleapis.com/v1/projects/-"

53-

+ "/serviceAccounts/{}:signJwt"

54-

)

55-56-

_IAM_IDTOKEN_ENDPOINT = (

57-

"https://iamcredentials.googleapis.com/v1/"

58-

+ "projects/-/serviceAccounts/{}:generateIdToken"

59-

)

43+

# 1. Determine if we should use mTLS.

44+

# Note: We only support automatic mTLS on the default googleapis.com universe.

45+

if hasattr(mtls, "should_use_client_cert"):

46+

use_client_cert = mtls.should_use_client_cert()

47+

else: # pragma: NO COVER

48+

# if unsupported, fallback to reading from env var

49+

use_client_cert = (

50+

os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false").lower() == "true"

51+

)

52+53+

# 2. Construct the template domain using the library's DEFAULT_UNIVERSE_DOMAIN constant.

54+

# This ensures that the .replace() calls in the classes will work correctly.

55+

if use_client_cert:

56+

# We use the .mtls. prefix only for the default universe template

57+

_IAM_DOMAIN = f"iamcredentials.mtls.{credentials.DEFAULT_UNIVERSE_DOMAIN}"

58+

else:

59+

_IAM_DOMAIN = f"iamcredentials.{credentials.DEFAULT_UNIVERSE_DOMAIN}"

60+61+

# 3. Create the common base URL template

62+

# We use double brackets {{}} so .format() can be called later for the email.

63+

_IAM_BASE_URL = f"https://{_IAM_DOMAIN}/v1/projects/-/serviceAccounts/{{}}"

64+65+

# 4. Define the endpoints as templates

66+

_IAM_ENDPOINT = _IAM_BASE_URL + ":generateAccessToken"

67+

_IAM_SIGN_ENDPOINT = _IAM_BASE_URL + ":signBlob"

68+

_IAM_SIGNJWT_ENDPOINT = _IAM_BASE_URL + ":signJwt"

69+

_IAM_IDTOKEN_ENDPOINT = _IAM_BASE_URL + ":generateIdToken"

607061716272

class Signer(crypt.Signer):