App Identity API for legacy bundled services

Region ID

The REGION_ID is an abbreviated code that Google assigns based on the region you select when you create your app. The code does not correspond to a country or province, even though some region IDs may appear similar to commonly used country and province codes. For apps created after February 2020, REGION_ID .r is included in App Engine URLs. For existing apps created before this date, the region ID is optional in the URL.

Learn more about region IDs .

The App Identity API lets an application discover its application ID (also called the project ID ). Using the ID, an App Engine application can assert its identity to other App Engine Apps, Google APIs, and third-party applications and services. The application ID can also be used to generate a URL or email address, or to make a run-time decision.

Getting the project ID

The project ID can be found using the app_identity.get_application_id() method. The WSGI or CGI environment exposes some implementation details, which are handled by the API.

Getting the application hostname

By default, App Engine apps are served from URLs in the form https:// PROJECT_ID . REGION_ID .r.appspot.com , where the project ID is part of the hostname. If an app is served from a custom domain, it may be necessary to retrieve the entire hostname component. You can do this using the app_identity.get_default_version_hostname() method.

Asserting identity to other App Engine apps

If you want to determine the identity of the App Engine app that is making a request to your App Engine app, you can use the request header X-Appengine-Inbound-Appid . This header is added to the request by the URLFetch service and is not user modifiable, so it safely indicates the requesting application's project ID, if present.

Requirements:

  • Only calls made to your app's appspot.com domain will contain the X-Appengine-Inbound-Appid header. Calls to custom domains do not contain the header.
  • Your requests must be set to not follow redirects. Set the urlfetch.fetch() follow_redirects parameter to False .

In your application handler, you can check the incoming ID by reading the X-Appengine-Inbound-Appid header and comparing it to a list of IDs allowed to make requests. For example:

  import 
  
 webapp2 
 class 
  
 MainPage 
 ( 
 webapp2 
 . 
 RequestHandler 
 ): 
 allowed_app_ids 
 = 
 [ 
 "other-app-id" 
 , 
 "other-app-id-2" 
 ] 
 def 
  
 get 
 ( 
 self 
 ): 
 incoming_app_id 
 = 
 self 
 . 
 request 
 . 
 headers 
 . 
 get 
 ( 
 "X-Appengine-Inbound-Appid" 
 , 
 None 
 ) 
 if 
 incoming_app_id 
 not 
 in 
 self 
 . 
 allowed_app_ids 
 : 
 self 
 . 
 abort 
 ( 
 403 
 ) 
 self 
 . 
 response 
 . 
 write 
 ( 
 "This is a protected page." 
 ) 
 app 
 = 
 webapp2 
 . 
 WSGIApplication 
 ([( 
 "/" 
 , 
 MainPage 
 )], 
 debug 
 = 
 True 
 ) 
 

Asserting identity to Google APIs

Google APIs use the OAuth 2.0 protocol for authentication and authorization . The App Identity API can create OAuth tokens that can be used to assert that the source of a request is the application itself. The get_access_token() method returns an access token for a scope, or list of scopes. This token can then be set in the HTTP headers of a call to identify the calling application.

The following example shows how to use the App Identity API to authenticate to the Cloud Storage API and retrieve and list of all buckets in the project.
  import 
  
 json 
 import 
  
 logging 
 from 
  
 google.appengine.api 
  
 import 
 app_identity 
 from 
  
 google.appengine.api 
  
 import 
 urlfetch 
 import 
  
 webapp2 
 class 
  
 MainPage 
 ( 
 webapp2 
 . 
 RequestHandler 
 ): 
 def 
  
 get 
 ( 
 self 
 ): 
 auth_token 
 , 
 _ 
 = 
 app_identity 
 . 
 get_access_token 
 ( 
 "https://www.googleapis.com/auth/cloud-platform" 
 ) 
 logging 
 . 
 info 
 ( 
 "Using token 
 {} 
 to represent identity 
 {} 
 " 
 . 
 format 
 ( 
 auth_token 
 , 
 app_identity 
 . 
 get_service_account_name 
 () 
 ) 
 ) 
 response 
 = 
 urlfetch 
 . 
 fetch 
 ( 
 "https://www.googleapis.com/storage/v1/b?project= 
 {} 
 " 
 . 
 format 
 ( 
 app_identity 
 . 
 get_application_id 
 () 
 ), 
 method 
 = 
 urlfetch 
 . 
 GET 
 , 
 headers 
 = 
 { 
 "Authorization" 
 : 
 "Bearer 
 {} 
 " 
 . 
 format 
 ( 
 auth_token 
 )}, 
 ) 
 if 
 response 
 . 
 status_code 
 != 
 200 
 : 
 raise 
 Exception 
 ( 
 "Call failed. Status code 
 {} 
 . Body 
 {} 
 " 
 . 
 format 
 ( 
 response 
 . 
 status_code 
 , 
 response 
 . 
 content 
 ) 
 ) 
 result 
 = 
 json 
 . 
 loads 
 ( 
 response 
 . 
 content 
 ) 
 self 
 . 
 response 
 . 
 headers 
 [ 
 "Content-Type" 
 ] 
 = 
 "application/json" 
 self 
 . 
 response 
 . 
 write 
 ( 
 json 
 . 
 dumps 
 ( 
 result 
 , 
 indent 
 = 
 2 
 )) 
 app 
 = 
 webapp2 
 . 
 WSGIApplication 
 ([( 
 "/" 
 , 
 MainPage 
 )], 
 debug 
 = 
 True 
 ) 
 

Note that the application's identity is represented by the service account name, which is typically applicationid@appspot.gserviceaccount.com . You can get the exact value by using the get_service_account_name() method. For services which offer ACLs, you can grant the application access by granting this account access.

Asserting identity to third-party services

The token generated by get_access_token() only works against Google services. However you can use the underlying signing technology to assert the identity of your application to other services. The sign_blob() method will sign bytes using a private key unique to your application, and the get_public_certificates() method will return certificates which can be used to validate the signature.

Here is an example showing how to sign a blob and validate its signature:
  import 
  
 base64 
 from 
  
 Crypto.Hash 
  
 import 
 SHA256 
 from 
  
 Crypto.PublicKey 
  
 import 
 RSA 
 from 
  
 Crypto.Signature 
  
 import 
 PKCS1_v1_5 
 from 
  
 Crypto.Util.asn1 
  
 import 
 DerSequence 
 from 
  
 google.appengine.api 
  
 import 
 app_identity 
 import 
  
 webapp2 
 def 
  
 verify_signature 
 ( 
 data 
 , 
 signature 
 , 
 x509_certificate 
 ): 
  
 """Verifies a signature using the given x.509 public key certificate.""" 
 # PyCrypto 2.6 doesn't support x.509 certificates directly, so we'll need 
 # to extract the public key from it manually. 
 # This code is based on https://github.com/google/oauth2client/blob/master 
 # /oauth2client/_pycrypto_crypt.py 
 pem_lines 
 = 
 x509_certificate 
 . 
 replace 
 ( 
 b 
 " " 
 , 
 b 
 "" 
 ) 
 . 
 split 
 () 
 cert_der 
 = 
 base64 
 . 
 urlsafe_b64decode 
 ( 
 b 
 "" 
 . 
 join 
 ( 
 pem_lines 
 [ 
 1 
 : 
 - 
 1 
 ])) 
 cert_seq 
 = 
 DerSequence 
 () 
 cert_seq 
 . 
 decode 
 ( 
 cert_der 
 ) 
 tbs_seq 
 = 
 DerSequence 
 () 
 tbs_seq 
 . 
 decode 
 ( 
 cert_seq 
 [ 
 0 
 ]) 
 public_key 
 = 
 RSA 
 . 
 importKey 
 ( 
 tbs_seq 
 [ 
 6 
 ]) 
 signer 
 = 
 PKCS1_v1_5 
 . 
 new 
 ( 
 public_key 
 ) 
 digest 
 = 
 SHA256 
 . 
 new 
 ( 
 data 
 ) 
 return 
 signer 
 . 
 verify 
 ( 
 digest 
 , 
 signature 
 ) 
 def 
  
 verify_signed_by_app 
 ( 
 data 
 , 
 signature 
 ): 
  
 """Checks the signature and data against all currently valid certificates 
 for the application.""" 
 public_certificates 
 = 
 app_identity 
 . 
 get_public_certificates 
 () 
 for 
 cert 
 in 
 public_certificates 
 : 
 if 
 verify_signature 
 ( 
 data 
 , 
 signature 
 , 
 cert 
 . 
 x509_certificate_pem 
 ): 
 return 
 True 
 return 
 False 
 class 
  
 MainPage 
 ( 
 webapp2 
 . 
 RequestHandler 
 ): 
 def 
  
 get 
 ( 
 self 
 ): 
 message 
 = 
 "Hello, world!" 
 signing_key_name 
 , 
 signature 
 = 
 app_identity 
 . 
 sign_blob 
 ( 
 message 
 ) 
 verified 
 = 
 verify_signed_by_app 
 ( 
 message 
 , 
 signature 
 ) 
 self 
 . 
 response 
 . 
 content_type 
 = 
 "text/plain" 
 self 
 . 
 response 
 . 
 write 
 ( 
 "Message: 
 {} 
 \n 
 " 
 . 
 format 
 ( 
 message 
 )) 
 self 
 . 
 response 
 . 
 write 
 ( 
 "Signature: 
 {} 
 \n 
 " 
 . 
 format 
 ( 
 base64 
 . 
 b64encode 
 ( 
 signature 
 ))) 
 self 
 . 
 response 
 . 
 write 
 ( 
 "Verified: 
 {} 
 \n 
 " 
 . 
 format 
 ( 
 verified 
 )) 
 app 
 = 
 webapp2 
 . 
 WSGIApplication 
 ([( 
 "/" 
 , 
 MainPage 
 )], 
 debug 
 = 
 True 
 ) 
 

Getting the default Cloud Storage Bucket name

Each application can have one default Cloud Storage bucket, which includes 5GB of free storage and a free quota for I/O operations .

To get the name of the default bucket, you can use the App Identity API. Call google.appengine.api.app_identity.app_identity.get_default_gcs_bucket_name .

Design a Mobile Site
View Site in Mobile | Classic
Share by: