Add Signing.singer_email (#89)

diff --git a/google/auth/app_engine.py b/google/auth/app_engine.py
index 566475e..608651d 100644
--- a/google/auth/app_engine.py
+++ b/google/auth/app_engine.py
@@ -110,3 +110,8 @@
     @_helpers.copy_docstring(credentials.Signing)
     def sign_bytes(self, message):
         return app_identity.sign_blob(message)
+
+    @property
+    @_helpers.copy_docstring(credentials.Signing)
+    def signer_email(self):
+        return self.service_account_email
diff --git a/google/auth/credentials.py b/google/auth/credentials.py
index 470f1a4..360dc0e 100644
--- a/google/auth/credentials.py
+++ b/google/auth/credentials.py
@@ -229,3 +229,10 @@
         # pylint: disable=missing-raises-doc,redundant-returns-doc
         # (pylint doesn't recognize that this is abstract)
         raise NotImplementedError('Sign bytes must be implemented.')
+
+    @abc.abstractproperty
+    def signer_email(self):
+        """Optional[str]: An email address that identifies the signer."""
+        # pylint: disable=missing-raises-doc
+        # (pylint doesn't recognize that this is abstract)
+        raise NotImplementedError('Signer email must be implemented.')
diff --git a/google/auth/jwt.py b/google/auth/jwt.py
index 0884b3d..dfaf2e6 100644
--- a/google/auth/jwt.py
+++ b/google/auth/jwt.py
@@ -463,6 +463,11 @@
         """
         return self._signer.sign(message)
 
+    @property
+    @_helpers.copy_docstring(credentials.Signing)
+    def signer_email(self):
+        return self._issuer
+
     def before_request(self, request, method, url, headers):
         """Performs credential-specific before request logic.
 
diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py
index 24c852b..48b537d 100644
--- a/google/oauth2/service_account.py
+++ b/google/oauth2/service_account.py
@@ -317,3 +317,8 @@
     @_helpers.copy_docstring(credentials.Signing)
     def sign_bytes(self, message):
         return self._signer.sign(message)
+
+    @property
+    @_helpers.copy_docstring(credentials.Signing)
+    def signer_email(self):
+        return self._service_account_email
diff --git a/tests/oauth2/test_service_account.py b/tests/oauth2/test_service_account.py
index 678e6a3..e6ce631 100644
--- a/tests/oauth2/test_service_account.py
+++ b/tests/oauth2/test_service_account.py
@@ -134,6 +134,9 @@
         signature = self.credentials.sign_bytes(to_sign)
         assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
 
+    def test_signer_email(self):
+        assert self.credentials.signer_email == self.SERVICE_ACCOUNT_EMAIL
+
     def test_create_scoped(self):
         scopes = ['email', 'profile']
         credentials = self.credentials.with_scopes(scopes)
diff --git a/tests/test_app_engine.py b/tests/test_app_engine.py
index 94f528d..117533e 100644
--- a/tests/test_app_engine.py
+++ b/tests/test_app_engine.py
@@ -115,3 +115,7 @@
 
         assert signature == mock.sentinel.signature
         app_identity_mock.sign_blob.assert_called_with(to_sign)
+
+    def test_signer_email(self, app_identity_mock):
+        credentials = app_engine.Credentials()
+        assert credentials.signer_email == credentials.service_account_email
diff --git a/tests/test_jwt.py b/tests/test_jwt.py
index 2a4795a..3959260 100644
--- a/tests/test_jwt.py
+++ b/tests/test_jwt.py
@@ -264,6 +264,10 @@
         signature = self.credentials.sign_bytes(to_sign)
         assert crypt.verify_signature(to_sign, signature, PUBLIC_CERT_BYTES)
 
+    def test_signer_email(self):
+        assert (self.credentials.signer_email ==
+                SERVICE_ACCOUNT_INFO['client_email'])
+
     def _verify_token(self, token):
         payload = jwt.decode(token, PUBLIC_CERT_BYTES)
         assert payload['iss'] == self.SERVICE_ACCOUNT_EMAIL